diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 767315450..55106fa98 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -490,6 +490,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_
       LOG_PRINT_L0("Spent money: " << print_money(amount) << ", with tx: " << get_transaction_hash(tx));
       tx_money_spent_in_ins += amount;
       td.m_spent = true;
+      td.m_spent_height = height;
       if (0 != m_callback)
         m_callback->on_money_spent(height, td.m_tx, amount, tx);
     }
@@ -1167,6 +1168,17 @@ void wallet2::detach_blockchain(uint64_t height)
   LOG_PRINT_L0("Detaching blockchain on height " << height);
   size_t transfers_detached = 0;
 
+  for (size_t i = 0; i < m_transfers.size(); ++i)
+  {
+    wallet2::transfer_details &td = m_transfers[i];
+    if (td.m_spent && td.m_spent_height >= height)
+    {
+      LOG_PRINT_L1("Resetting spent status for output " << i << ": " << td.m_key_image);
+      td.m_spent = false;
+      td.m_spent_height = 0;
+    }
+  }
+
   auto it = std::find_if(m_transfers.begin(), m_transfers.end(), [&](const transfer_details& td){return td.m_block_height >= height;});
   size_t i_start = it - m_transfers.begin();
 
@@ -1980,10 +1992,12 @@ void wallet2::rescan_spent()
       if (td.m_spent)
       {
         LOG_PRINT_L0("Marking output " << i << "(" << td.m_key_image << ") as unspent, it was marked as spent");
+        td.m_spent_height = 0;
       }
       else
       {
         LOG_PRINT_L0("Marking output " << i << "(" << td.m_key_image << ") as spent, it was marked as unspent");
+        // unknown height, if this gets reorged, it might still be missed
       }
       td.m_spent = daemon_resp.spent_status[i] != COMMAND_RPC_IS_KEY_IMAGE_SPENT::UNSPENT;
     }
@@ -2293,7 +2307,10 @@ void wallet2::commit_tx(pending_tx& ptx)
   LOG_PRINT_L2("transaction " << txid << " generated ok and sent to daemon, key_images: [" << ptx.key_images << "]");
 
   BOOST_FOREACH(transfer_container::iterator it, ptx.selected_transfers)
+  {
     it->m_spent = true;
+    it->m_spent_height = 0;
+  }
 
   //fee includes dust if dust policy specified it.
   LOG_PRINT_L0("Transaction successfully sent. <" << txid << ">" << ENDL
@@ -2371,7 +2388,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
 
         // mark transfers to be used as "spent"
         BOOST_FOREACH(transfer_container::iterator it, ptx.selected_transfers)
+        {
           it->m_spent = true;
+          it->m_spent_height = 0;
+        }
       }
 
       // if we made it this far, we've selected our transactions.  committing them will mark them spent,
@@ -2381,7 +2401,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
       {
         // mark transfers to be used as not spent
         BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+        {
           it2->m_spent = false;
+          it2->m_spent_height = 0;
+        }
 
       }
 
@@ -2398,8 +2421,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
       {
         // mark transfers to be used as not spent
         BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+        {
           it2->m_spent = false;
-
+          it2->m_spent_height = 0;
+        }
       }
 
       if (attempt_count >= MAX_SPLIT_ATTEMPTS)
@@ -2416,8 +2441,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto
       {
         // mark transfers to be used as not spent
         BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+        {
           it2->m_spent = false;
-
+          it2->m_spent_height = 0;
+        }
       }
 
       throw;
@@ -3860,7 +3887,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
 
         // mark transfers to be used as "spent"
         BOOST_FOREACH(transfer_container::iterator it, ptx.selected_transfers)
+        {
           it->m_spent = true;
+          it->m_spent_height = 0;
+        }
       }
 
       // if we made it this far, we've selected our transactions.  committing them will mark them spent,
@@ -3870,8 +3900,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
       {
         // mark transfers to be used as not spent
         BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+        {
           it2->m_spent = false;
-
+          it2->m_spent_height = 0;
+        }
       }
 
       // if we made it this far, we're OK to actually send the transactions
@@ -3887,8 +3919,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
       {
         // mark transfers to be used as not spent
         BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+        {
           it2->m_spent = false;
-
+          it2->m_spent_height = 0;
+        }
       }
 
       if (attempt_count >= MAX_SPLIT_ATTEMPTS)
@@ -3905,8 +3939,10 @@ std::vector<wallet2::pending_tx> wallet2::create_unmixable_sweep_transactions(bo
       {
         // mark transfers to be used as not spent
         BOOST_FOREACH(transfer_container::iterator it2, ptx.selected_transfers)
+        {
           it2->m_spent = false;
-
+          it2->m_spent_height = 0;
+        }
       }
 
       throw;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 125f8edb5..1c835429f 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -103,6 +103,7 @@ namespace tools
       size_t m_internal_output_index;
       uint64_t m_global_output_index;
       bool m_spent;
+      uint64_t m_spent_height;
       crypto::key_image m_key_image; //TODO: key_image stored twice :(
       rct::key m_mask;
       uint64_t m_amount;
@@ -490,7 +491,7 @@ namespace tools
   };
 }
 BOOST_CLASS_VERSION(tools::wallet2, 13)
-BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 1)
+BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 2)
 BOOST_CLASS_VERSION(tools::wallet2::payment_details, 1)
 BOOST_CLASS_VERSION(tools::wallet2::unconfirmed_transfer_details, 4)
 BOOST_CLASS_VERSION(tools::wallet2::confirmed_transfer_details, 2)
@@ -500,14 +501,21 @@ namespace boost
   namespace serialization
   {
     template <class Archive>
-    inline void initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x)
+    inline void initialize_transfer_details(Archive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
     {
     }
     template<>
-    inline void initialize_transfer_details(boost::archive::binary_iarchive &a, tools::wallet2::transfer_details &x)
+    inline void initialize_transfer_details(boost::archive::binary_iarchive &a, tools::wallet2::transfer_details &x, const boost::serialization::version_type ver)
     {
-        x.m_mask = rct::identity();
-        x.m_amount = x.m_tx.vout[x.m_internal_output_index].amount;
+        if (ver < 1)
+        {
+          x.m_mask = rct::identity();
+          x.m_amount = x.m_tx.vout[x.m_internal_output_index].amount;
+        }
+        if (ver < 2)
+        {
+          x.m_spent_height = 0;
+        }
     }
 
     template <class Archive>
@@ -522,11 +530,17 @@ namespace boost
       if (ver < 1)
       {
         // ensure mask and amount are set
-        initialize_transfer_details(a, x);
+        initialize_transfer_details(a, x, ver);
         return;
       }
       a & x.m_mask;
       a & x.m_amount;
+      if (ver < 2)
+      {
+        initialize_transfer_details(a, x, ver);
+        return;
+      }
+      a & x.m_spent_height;
     }
 
     template <class Archive>