ERC-20 token standard contains a major logical flaw — lack of communication model (lack of transaction handling model).
This problem is well-known. I wrote tens of articles on Ethereum reddit, gitter and github during the past 6 years. Starting from this post. Also, here is Vitalik Buterin’s comment on this.
The solution exists. In 2017 I proposed the ERC-223 token standard. ERC-223 implements transaction handling model for tokens. (Note that ERC23 and ERC-223 is the same thing, ERC23 is just the old deprecated name)
Lost ERC-20 tokens
Let’s take a look at the DAI contract address. This address has $647,211 worth of ERC-20 tokens on it’s balance.
But it’s a token contract — the token contract is not intended to receive and hold any tokens, the token contract is intended to only be the token.
There are not only DAI tokens in the contract, there are some USDC and USDT as well.
How does this happen?
Here is the description of ERC-20 problems that was posted on Ethereum reddit.
Users accidentally sent tokens to a DAI contract address by mistake, and the contract successfully received tokens when it mustn’t receive them.
It is known for sure that the DAI contract (and any other token contract) is not intended to receive any assets.
- This contract WILL NOT receive Ether if it will be sent to the contract address — in this case an error will occur and the transaction will fail. ETH will be returned to the address of the sender.
- The contract WILL NOT receive ERC-223 tokens — an error will occur similar to that of Ether transaction.
- The contract WILL NOT receive ERC-721 NFTs if it is not intended to and the transaction will fail, no NFTs will be lost.
- The contract WILL receive ERC-20 tokens without any errors (despite it is known that the transaction can only be a mistake) and the tokens will become stuck in the contract address without any possibility to recover them. The user will just lose his funds.
This constantly happens because it is not possible to handle ERC-20 transactions at all. Ether transfer notifies the recipient of an incoming transaction, ERC-223 notifies the recipient, ERC-721 notifies the recipient, ERC-20 does not.
Technical description of the ERC-20 problem
In programming event handling is a standard practice. When one program (such as token contract) is performing some action that involves other program it must notify that program. Transaction is an event and the recipient of the transaction must be able to get a notification on incoming transaction and handle it.
The “final” ERC-20 documentation can be found here: https://eips.ethereum.org/EIPS/eip-20
According to ERC-20 EIP it defines two methods of transferring tokens:
- transfer() function, assumed to be used to transfer tokens between addresses owned by humans.
- transferFrom() function that requires that an approval between sender and spender was issued first. Assumed to be used when a user needs to deposit tokens to contract.
None of this functions notifies the recipient about the incoming ERC-20 transfer. ERC-20 standard does not declare the logic of sending tokens directly to contracts at all.
In order to avoid the situation where a user sent tokens and these got lost in a contract that can’t operate with them the following conditions mus be met:
- if the token is sent to a contract directly and ERC-20 does not support this type of depositing tokens — then an error must occur.
- If the ERC-20 token is sent to a contract that is not intended to receive tokens — then an error must occur.
In order to reject an incoming ERC-20 or throw an error the recipient must recognize the incoming transaction. And this is exactly the problem of ERC-20 standard — it does not let the receiver recognize an incoming transaction.
How much tokens are lost due to this flaw?
Tens of millions of dollars worth of ERC-20 tokens.
On 27 Dec, 2017 there were about $3,000,000 worth of ERC-20 tokens stuck in the contracts (you can find number on this thread).
There is a public record — a twitter thread where one person described how $1,000,000 worth of USDT were lost in the contract exactly because of this ERC-20 flaw.
On March 7, 2023 $AAVE launched a “rescue mission” to extract tokens from contracts. This is exactly the issue of ERC-20 standard that AAVE experienced. Not all tokens will be extracted, and after the extraction new ones will be sent to contracts again.
As of today (3/9/2023) only in the next contracts there are more than $11 million tokens that were lost by users due to ERC-20 lack of transaction handling:
- $6,800,000 are lost in BNB contract https://etherscan.io/address/0xB8c77482e45F1F44dE1745F52C74426C631bDD52
- $2,600,000 are lost in SHIB contract https://etherscan.io/address/0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce
- $1,700,000 are lost in HEX contract https://etherscan.io/address/0x2b591e99afe9f32eaa6214f7b7629768c40eeb39
- $80,000 are lost in USDT contract https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7
- $549,000 are lost in MATIC contract https://etherscan.io/address/0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0
- $526,000 are lost in UNI token contract https://etherscan.io/address/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984
- $238,000 are lost in BUSD contract https://etherscan.io/address/0x4Fabb145d64652a948d72533023f6E7A623C7C53
You can open any contract on Etherscan and watch the amount of tokens that it holds. If the contract is not intended to receive tokens (it is not DEX contract and not a multisig) — then the tokens are lost due to ERC-20 transaction that must be rejected but it wasn’t.
How this issue can be solved?
This is the issue of the adoption of ERC-20 standard as it is. Unfortunately, recovering already lost tokens is not possible but we can prevent this issues in the future.
It is important to spread the word about the issue to convince the token developers of new tokens to pay attention.
Here is a good example of what can be the root of the problem:
- I warned STORJ developers that using ERC-20 standard can be dangerous and it will surely lead to the losses of funds for their users.
- STORJ developers replied “we know, but everyone is using ERC-20 so we will use it too despite knowing of its problems and losses of funds”.
- Users funds got lost on STORJ contract as it was expected.
So far ERC-223 is still the most suitable solution in my opinion but any other token that supports communication model could work. NFTs are safe, ERC-721 implements communication model derived from ERC-223.
Right now, I am building the ecosystem for ERC-223 tokens:
- Token Wrapper ERC20=>ERC223 — a contract that will allow to create “wrapped tokens” for each ERC-20 contract. Wrapped ERC-223 tokens will be backed 1:1 by the original ERC-20 tokens and can be switched back to ERC-20 at any moment. This would open up the opportunity to utilize the advantages of ERC-223 without having to delete and reconstruct the whole token ecosystem. https://github.com/Dexaran/ERC223_to_ERC20_wrapper
- DEX that supports ERC-223 standard (already deployed on Ethereum mainnet): https://github.com/SoyFinance/smart-contracts
- ERC-223 extensions, examples and documentation updates on Ethereum
Frequent arguments
This is not a problem of the token standard, stupid users just send their tokens to wrong address. User mistake, not a flaw of ERC-20.
- When a user sends tokens to the wrong address — it is the user’s fault. When a contract accepts tokens that it shouldn’t accept— that’s the contract’s fault.
- This is a serious problem anyways, tens of millions of dollars are lost already and the amount is growing with each year and each day. It is solvable. There is no reason to leave a flaw that burns the funds of DAPP customers if the solution exists.
- ETH can’t be transferred to a contract that is not intended to receive it. ERC-223 can’t be transferred to a contract that is not intended to receive it. NFT can’t be transferred to a contract that is not intended to receive it. Only ERC-20 can be transferred to a contract and get stuck there.
It can be solved on the side of a UI.
The issue exists for 6 years already, the amount of lost tokens only growth with time so it doesn’t work this way.
This problem can be solved with ERC-20, just need to prevent deposits of tokens to the same contract address.
No. Every contract that is not intended to work with ERC-20 tokens can receive them and there is no way to recognize and subsequently reject the improper transaction for the recipient. That’s a bigger problem. Not just stuck tokens in token contracts.
ERC-677 TransferAndCall solves this issue.
No, it doesn’t. If a token standard does not declare the logic of transferring tokens and only declares the API then it does not solve the issue.
Contacts
Have you lost your tokens, need any other assistance or have a question? Feel free to contact me:
- Emails: dexaran820@gmail.com (preferred) / dexaran@callisto.network / dexaran@ethereumclassic.org (only highest priority)
- Github: https://github.com/Dexaran
- Twitter: https://twitter.com/Dexaran
- Telegram t.me/Dexaran