
One day, a user contacted rabbit.io support claiming that after an exchange he received 1 XLM instead of 1,000 USDC.
It looked like a serious loss. One lumen is worth far less than a dollar: at the moment, XLM is trading at around $0.22. Losing almost the entire amount in such a way would be alarming for anyone.
Naturally, we started investigating the case immediately. If it had turned out that the wrong amount or the wrong asset was sent due to our fault, we would have taken action right away and made sure the user received the correct funds.
But the story turned out to be far more interesting.
Our systems worked exactly as intended. 1,000 USDC were sent to the address provided by the user, with no errors or failures on our side. And yet, in the Stellar network there is a subtle architectural detail that can, quite literally, turn 1,000 USDC into 1 XLM if you overlook it.
Let me explain how this happens.
The rabbit.io client was not a beginner. On the contrary, he was an experienced crypto user who deliberately stored his funds in non-custodial wallets rather than on exchanges. Most of his experience, however, came from EVM-based networks.
In the Ethereum world, users get used to a simple model: any token sent to your address will arrive successfully. In the worst case, you just need to manually add the token to your wallet interface. And even when the wallet app does not support a specific token at all, you can import your seed phrase into another wallet that does.
Stellar works very differently.
Its architecture is fundamentally unlike Ethereum, Binance Smart Chain, or Polygon. Even the concept of an address is different. In EVM networks, addresses are effectively free of charge. In Stellar, creating an address on the ledger costs 1 XLM.
And that exact amount — 1 XLM — is what our client saw in his wallet after the exchange.
The most important difference between Stellar and EVM-based networks lies in how assets are received.
In Stellar, a wallet must explicitly approve any new token before it can be credited. For example, in order to receive USDC for the first time, a Stellar account has to create a trustline to the USDC issuer. Creating a trustline requires locking 0.5 XLM as a reserve, which secures the corresponding ledger entry.
Originally, if a token was sent to an address without an existing trustline, the transaction would simply fail. The full amount would remain with the sender.
Starting with Stellar Protocol 15, this behavior was changed with the introduction of claimable balances. The goal was to improve usability and allow tokens to be sent even to “unprepared” accounts.
When we sent USDC to our client’s Stellar address that did not have a trustline to USDC, the protocol handled the transaction as follows:
In other words, the funds were recorded on the ledger and remained there, waiting for someone to explicitly claim them. Who is allowed to do so is defined by the conditions of the transaction. By default, both the sender and the recipient are eligible claimants.
But where did the 1 XLM on the recipient’s account come from? The answer is: from us — although we never intentionally sent it.
Here is how such transactions are actually processed.
Step 1. The sender initiates a USDC transfer and signs a transaction with the following parameters:
At this stage, the sender implicitly agrees to pay whatever amount of XLM is required to process the transaction. In practice, users rarely pay attention to this detail, because transaction fees on Stellar are usually negligible.
Step 2. Stellar performs a series of basic validations to check whether the operation can be executed
Taken together, these conditions mean that a direct payment is not possible.
Step 3. Instead of rejecting the transaction outright, Stellar activates the claimable balance mechanism.
To do so, the network:
However, in order for the recipient to be listed as a potential claimant, the recipient’s account must exist on the network. At the time of the transaction, the account existed only inside the recipient’s wallet app. It had not yet been created on the Stellar ledger.
Under these conditions, the account is created as part of the same transaction.
As mentioned earlier, creating an account on Stellar is not free. The 1 XLM required to create the account is taken from the source of the operation, meaning from the sender’s balance:
This 1 XLM is part of the cost of executing the transaction — a cost we implicitly accepted when signing the transaction. Technically, it ends up on the recipient’s balance, but the recipient cannot actually use it. In particular, the recipient cannot take half of that amount to create a trustline for USDC and claim the funds.
If the recipient’s account had already existed on the network, but simply lacked a trustline to USDC, no additional 1 XLM would have been required. In that case, the recipient would not have seen any visible change in his wallet at all.
The first step was for the recipient to sign a changeTrust operation for the USDC asset. For this operation to succeed, the wallet must have at least 0.5 XLM of free balance, which becomes locked as a reserve when the trustline is created.
Our client did not have any free XLM. More precisely, the only XLM on the account was the 1 XLM that appeared there as a result of the exchange — but that amount was fully locked as the base reserve and could not be used.
We therefore suggested a simple workaround: exchange a small amount of any available cryptocurrency into lumens. After doing so, the client finally had enough free XLM to create a trustline in his wallet.
Once the trustline to USDC was established, the user was able to claim the 1,000 USDC. In this case, everything ended well for all parties involved.
The situation our client encountered is not unique. And he was genuinely fortunate that he was using non-custodial wallets fully under his own control. That is precisely what made the issue relatively easy to resolve.
I was reminded of this story because just a few days ago I read about a very similar case involving another user. The amount was exactly the same — 1,000 USDC — but the circumstances made the problem far more difficult to fix.
Three days ago, a comment appeared on LinkedIn under the latest post by Uphold CEO Simon McLoughlin, where an Uphold user described the following situation:
Given how closely the symptoms match, I believe the underlying issue is exactly the same.
Most likely, Uphold generates deposit addresses on demand, and the XLM address to which the user sent the funds had not yet been created on the Stellar ledger. That would explain why 1 XLM appeared on the account as a result of the transaction. However, the 1,000 USDC did not, and resolving the situation would require Uphold to manually create a trustline to USDC for that address.
Why did support refuse to help?
My guess is security architecture. Any business dealing with cryptocurrency invests heavily in wallet security. It seems that Uphold did not implement a process for creating trustlines outside of the expected, standard deposit flow. Adding such functionality retroactively, while meeting all internal security requirements, may cost the exchange far more than the 1,000 USDC lost by the user.
As of today, the comment under the CEO’s post has been removed. I do not know whether it was deleted by the user himself or by the exchange. I hope the issue was resolved and the user chose to remove the comment on his own. But if the comment was removed by Uphold, that would be a troubling signal.
These problems should not be quietly buried. On the contrary, they deserve attention — so that other users do not repeat the same mistake. That is why I decided to share both our story and the Uphold user’s story here.
If at least one of the wallets involved — either the sender’s or the recipient’s — is fully controlled by the owner of the funds, the situation is relatively straightforward:
However, when custodial wallets are involved — for example, CEX wallets — things become much more complicated.
Custodial services are not obligated to manually interfere with their wallet infrastructure to fix a user’s mistake, especially if doing so introduces additional operational or security risks. As a result, you may be refused assistance, even though the funds technically still exist on the ledger.
That said, it is still worth trying. As long as the exchange controls the private keys, there is a chance the funds can be recovered.
If you find yourself in this situation:
Ultimately, the best solution is still prevention. Being your own custodian has many advantages, but it also comes with a high level of responsibility. When sending cryptocurrency, attention to detail matters, because some mistakes are far easier to make than they are to fix.