ERC-20 is the most used token standard on Ethereum. It’s pure implementation contains a flaw that would be classified as a critical security issue according to OpenZeppelin bug bounty criteria. That flaw could lead to a permanent loss of funds for token holders. At the moment of writing $83,000,000 worth of ERC-20 tokens are lost because of this issue. This article serves the purpose of keeping historical tracks related to this issue in one place.
Lack of transaction handling on ERC-20 transfer()
function
This problem was described in this article that I published in 2023. This is a copy of a reddit post that was removed from Ethereum subreddit in 2017.
Software development is not a new area so there are well-known security practices in place. Most basic ones are described here.
We are interested in this two paragraphs:
2. Secure Defaults
Adopting Secure Defaults is a fundamental principle that mandates systems configurations to be inherently safe. This approach stems from the understanding that many end-users stick to default settings. By setting these defaults to be highly secure, you can safeguard most users.
7. Failing Securely
The principle of failing securely dictates that a system should respond to errors or failures in a way that preserves the overall security of the application.
ERC-20 is a software standard. It is written in a way that violates two of the basic secure software development principles — failsafe defaults and error handling (described under “failing securely” paragraph in the above article).
There are two methods of transferring tokens in ERC-20: transfer
function and approve & transferFrom
pattern. The transfer function is designed to transfer tokens between externally owned addresses. It does not invoke a callback in the recipient in case it’s a contract which makes error handling impossible (and this violates a principle of failing securely) and at the same time it does not restrict transfers to smart-contracts via the transfer function which is the default one used by wallets (this violates a principle of fail-safe defaults as the default method of transferring tokens is unsafe and may result in a loss of funds).
As the result, users are losing their funds with tokens that implement ERC-20 standard if they send them to a smart-contract which is not designed to receive tokens for example. We wrote a scrip that calculates the amount of funds lost on Ethereum mainnet and you can access it at dexaran.github.io/erc20-losses
It should be noted that Ethereum developers are aware of how things need to be done securely. The native currency of Ethereum chain (ether) does not implement two different methods of transferring and it’s default transferring method does invoke a callback (the receive() function or fallback function) upon transferring ether to contracts. ERC-721 NFTs also invoke a callback and therefore are safe to use.
Why ERC-20 is built the way it is
- ERC-20 was created in 2015. There was a 1024-call-stack depth bug in the EVM at that time which made it impossible to securely invoke a callback function upon token transfer.
- The impossibility of implementing callback function invocation led to the development of approve & transferFrom pattern as an alternative method of depositing tokens to smart-contracts. The security problem here is that if
transfer
function must not be used to deposit tokens to contracts it should have been restricted so that it would only be possible to deposit tokens via approve & transferFrom. This wasn’t done. - In 2016 1024-call-stack-depth bug was fixed.
- In 2017 the issue with ERC-20 tokens was discovered.
The history of the problem
- There is another article describing it’s classification from security point of view.
- There is a Callisto Security statement regarding this issue.
- In 2017 alternative ERC-223 token standard that fixes this issue was proposed. There is a clear description in ERC-223 proposal text which states that it fixes an issue of ERC-20 standard that caused users to lose few millions of dollars worth of tokens in 2017.
- During the discussion of ERC-20 standard it was discovered that approve & transferFrom pattern has no practical use for any token standard implementing transaction handling.
- In 2017 the ERC-20 standard was moved to “final” status. During it’s finalisation process it was reported that it contains this security flaw that causes financial losses to token users. It was highlighted that $16,000 of tokens were lost at that point. Then ERC-20 token standard was finalized without changes. https://github.com/ethereum/EIPs/pull/610#issuecomment-296711733
- A comment was made on the ERC-20 discussion thread highlighting that the amount of lost tokens has grown from $10,000 to $400,000 in 2 months.
https://github.com/ethereum/EIPs/issues/20#issuecomment-307752081 - STORJ developers were warned about the problems of ERC-20 standard that they are using. They replied that they are not going to apply any fixes. Their users started losing tokens.
- A user lost $130,000 worth of tokens due to the described flaw.
- The creator of ERC-20 standard announced that they are not using this standard in their new project.
- ERC-20 issue was reported to OpenZeppelin in 2018 then in 2023. Both issues were dismissed. No changes were applied to OpenZeppelin ERC-20 tokens. This issue is not documented in their repor and thier code contains the described security flaw. The issue was reported as part of their bugbounty classifying as a critical security vulnerability. It was dismissed with a “public disclosure of unpatched vulnerability” reason confirming that this is an issue and this is unpatched.
- Security warning was added to the description of the ERC-20 standard at ethereum.org: https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
- ERC-20 standard usage safety discussion on OpenZeppelin github: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3575#issuecomment-1693316451
- A user lost $240,000 worth of tokens due to the described issue in 2023.
- The issue was escalated to EthCatHerders (EIP editors). It was concluded that EIP process does not allow for security disclosures in “final” EIPs and the Security Considerations section of an EIP is only written by the EIP author at the moment of EIP creation. As the result, if an issue is discovered after the finalization of an EIP — it is not included in the security considerations section even if it is a critical security vulnerability.
- In 2024 a modification of EIP process that would allow for security disclosures in final EIPs was proposed.
- This proposal was rejected by EIP editors (2 votes against; 1 in favour).
- Here is one of the call records where the issue was discussed with EIP editors.
Results
- Once 1024-call-stack depth bug was fixed a new token standard that would implement a proper transferring methods should have been created. This was done. ERC-223 and ERC-777 standards do implement transactions that invoke callbacks on the recipients side allowing for error handling. ERC-777 doesn’t suffice failsafe defaults criteria however as it supports
transfer
function that works identical to ERC-20. - Once new standards emerged it was necessary to coordinate the upgrading process to convince the implementers to start using a new one and to convince exchanges / wallets / explorers and other ecosystem participants to start supporting new token standards. This wasn’t handled properly neither by Ethereum Foundation (which kept promoting ERC-20) nor by token standards creators (including myself).
- The issue was reported (for example here and here). It was known that the problem was causing financial damage to Ethereum users. At this point, it was necessary to make a security finding disclosure to notify the implementers and ecosystem participants. It was possible to develop a solution or suggest using existing solutions (like ERC-223) instead of promoting ERC-20. This wasn’t done. Ethereum Foundation kept promoting ERC-20 standard on their resources, it was described as one of the main features on ethereum.org web page and they ignored a request for the code examples removal even after the security issues were discovered and reported to them.
- If the EIP process is known to lead to a situation where a known security issue that was reported 8 years ago kept causing financial damage to the ecosystem — the process needed to be changed. This wasn’t done and the proposal to change the EIP process was rejected in 2024.