Practical ERC20 burning
Do not use contract burns, use well-known burn addresses.
Token burning is the act of permanently removing a certain number of tokens from circulation. This article delves into its intricacies and offers guidance based on my real-world experiences at Aurora.
Why is there a problem?
The ERC20 standard does not inherently specify a token burning mechanism.
The most common implementation of ERC20, provides ERC20Burnable
to solve that, but not all deployed OpenZepellin contracts include ERC20Burnable
. Many ERC20 contracts are locked and not upgradeable.
Due to these constraints, projects seek alternative ways to approach token burns.
Do not use contract burns
One often recommended way to burn tokens involves creating a contract which immediately self destructs and sends tokens to its own address. However, this method comes with its set of challenges:
- Overhead of creating, deploying and testing such contract, especially if the burn needs to happen periodically
- Even if the contract uses
SELFDESTRUCT
it does not preclude the possibility of redeploying another contract at the same address. This has been successfully exploited in the infamous Tornado Cash attack by using a metamorphic contract factory. - There is a negative sentiment against
SELFDESTRUCT
opcode and (although stagnant) EIP-4758 that highlights some security concerns. - Token burns via this method aren't recognised on most analytics platforms.
Given the listed concerns, I advise against this approach and encourage the use of burn addresses.
Use well-known burn addresses
A burn address is a recognized externally owned account (EOA) where tokens can be sent to symbolize their destruction. While the token count remains unchanged, these tokens are effectively removed from circulation since no private key can control the burn address.
One of the common questions is "what if somebody knows or brute forces the private keys for such EOA addresses?"
Ethereum security model rests on the practical impossibility of brute forcing EOA accounts, so it does not make sense to take the risk of such attack into account when planning the burns. And to mitigate the risk of malicious burn addresses, use only the well-known ones.
You can find the list of burn addresses on Etherscan but I recommend limiting it to the top two that stand out by the TVL and number of transactions: 0x0000000000000000000000000000000000000000
(null) and 0x000000000000000000000000000000000000dEaD
(dead).
Interestingly, OpenZeppelin's ERC20 implementation restricts transfers to null which could leave you with the second best choice: dead.
The benefit of using well-known burn addresses over "contract burns" is that burn addresses are accounted for and integrated into numerous analytics tools, ensuring accurate token burn data representation.
Bonus tips
- Ensure that your ERC20 contract is locked and immutable before initiating burns.
- For ERC20 tokens on multiple networks, execute burns on your primary network only, for unified tracking and analytics.
- For the first burn, refrain from using decentralised or ZK-bridges. If your contract unexpectedly rejects the transaction (like disallowing transfers to null) – it might muddle your analytics even though the tokens are technically burned.
Big thanks to Lance Henderson for technical insights and for reviewing this post!