Replies: 3 comments 1 reply
-
I'd like to strongly second @miohtama's points here. ERC-20 is a poor standard, standardized in the aftermath of the DAO-hack. ERC-20 is far too established in the Solidity/EVM world to be replaced, but StarkNet/Cairo gives us an opportunity to start fresh and revisit mistakes of the past. Proposed solutionMy proposal is for Cairo token transfers behave like ETH transfers on mainnet:
Of course, this does open up the possibility of re-entrancy, but this is a feature that is easily addressed by adding re-entrancy locks to smart contracts (would be great to have this integrated at the language level). |
Beta Was this translation helpful? Give feedback.
-
Here is another high profile example of a person almost losing a significant amount of money because of ERC-20 approve() and confusing UX: |
Beta Was this translation helpful? Give feedback.
-
what about have one SIMP for the "compatibility" with ERC-20 and one new fresh improved standard ? It seems very likely we will need compatibility with ERC-20 for adoption. But I agree an improved token standard for StarkNet makes sense. |
Beta Was this translation helpful? Give feedback.
-
Summary
TL; DR Please do not copy ERC-20 "as is" to a new blockchain, as ERC-20 have many known historical flaws that should be avoided, as they are 1) annoying 2) can cause losses for the users.
Motivation
Currently, Cairo ERC-20 is 1:1 copying the most widespread smart contract token standard, ERC-20. ERC-20 was initiated back in 2015, then formalized starting 2016. With the passing time we have found out many mistakes made with ERC-20 and it would be foolish to copy those mistakes to a new token standard when one can start from the clean slate.
Below I go through ERC-20 shortcomings one-by-one and also have some links as reference material. Some post-Ethereum networks, like EOS, have already addressed technicalities and have more user-friendly approach to tokens. Also Ethereum has addressed issues in the form of later standards, like ERC-1363, ERC-777, but due to ossification they have not been adopted (more to below).
The list of ERC-20 shortcomings start here. Some of these can be addressed at a smart contract level. Some like native payable token functions, require VM support, but would make future development easier and safer (this has shown to be possible by EOS, Elrond, NEAR and some other novel blockchains.)
I believe ERC-20 backwards compatibility can be retained, while still addressing some of ERC-20 shortcomings.
Smart contracts cannot reject token transfers
Because of the lack of standardized token receive hook, smart contracts cannot reject token transfers on them. If someone accidentally sends ERC-20 to a smart contract address they are likely lost. This error is common and happens especially when copy-pasting addresses around: tokens are sent to the token contract itself.
There is a Twitter account tweeting these mistakes:
https://twitter.com/TokenOops
Root cause: ERC-20 has different transfer() and transferFrom() semantics when dealing with normal accounts and smart contract accounts.
Account cannot express if it can receive tokens
Similar to one above, a common mistake is to send tokens to a centralised exchange address that cannot handle them. For example, Bittrex charged $5000 for "token recovery" in one point to give back the tokens that the user deposited to the exchange if the exchange did not have an active order book for them.
For example, there is worth of $772M tokens in 0x0 address. Some of them are token burns, but most of them are accidental sends and wallet input field failures: https://etherscan.io/address/0x0000000000000000000000000000000000000000
Root cause: Accounts cannot express what tokens they support
Hot wallets cannot interact with smart contracts
Centralised exchanges and other custodial use hot wallets where each receiving address belongs to an user, but withdraw address comes from a pooled wallet. Because most smart contract operations use msg.sender as the author, any reverse payments for msg.sender would go to the hot wallet pooled address directly. Because the transfer is not tripped through the receiving address of the user, the hot wallet accounting cannot mark this reverse payment deposit belonging to the user.
As a hack workaround, centralised exchanges like Kraken and Coinbase set the gas limit for the token transfers very low, hoping that the gas limit prevents any smart contract interaction from hot wallet direct withdrawals.
Root cause: transfer() does not provide alternative address as the return address
Different transfer semantics for account and smart contract interaction
Users expect
transfer()
to work with a smart contract, as it works with normal accounts. However, this is not the case. Any directtransfer()
and notapprove()
+transferFrom()
pair to a smart contract address usually leads to loss of the tokens, because smart contract cannot account tokens to msg.sender correctly.https://mobile.twitter.com/moo9000/status/1300167829929459713
Approve() inheritently unsafe
The ERC-20 approve() mechanism has been found to be unsafe for normal users. This is because of the confusing UX, because of semantics that do not match the underlying transaction, because of laziness of users and developers.
Any token developers and users should be discouraged the use of approve().
Safe defaults
Related to above, ERC-20 has unsafe defaults, due to
approve()
+transferFrom()
pattern being inherently complex. This has led to the creation of wrappers likeSafeERC20.safeTransferFrom()
. However turns out these wrappers themselves are buggy. Doing duct tape solutions on the top of duct tape solutions have proven to be a bad evolutionary path for security.Any token should have only one way to transfer it and it should be safe under all conditions.
Native asset is treated differently from tokens
In Ethereum Defi world, the native asset ETH must be wrapped to WETH ERC-20 token to interact with many of the smart contracts. This causes extra work for developers, as they need to write double code with ifs to all deposits and withdrawals. This will also confuse users, as they see both the native asset and the wrapped asset in their wallet and wallets do not account them as one item.
As a side note, Solana copied this design mistake. However, for example in the case of EOS, all assets are treated similarly and any token asset can added to any payable transaction.
https://mobile.twitter.com/ProjectSerum/status/1300633211932868610
Lack of native relayers and gas fee markets
To transact with ERC-20 tokens, the user needs to have both the token and Ethers on the same account. This is very confusing for the users who are there only for the token, for example in gaming scenarios, and could not less care about cryptocurrency.
ERC-20 lacks native mechanisms for fee markets and relayers who would be willing to pay the gas fee on the behalf of the user and take a fee cut in the token amount. The history has proven that adding this functionality afterwards is especially complicate. Multiple smart contract wallets (Argent, Pillar, etc.) have come up with incompatible, proprietary, solutions.
Root cause: Lack of gas fee market design when ERC-20 was launched
Lack of metadata
ERC-20 only provides information for name, symbol and token supply. Even the amount of decimals is an add-on. This has created a cottage industry of different "token lists" that supplement this information. A common element to add would be at least homepage, icon and relayer information (for gas market transactions). Metadata often also contains various discussion forums, support email, officially author information (foundation, corporation) and such. Wallets could consume this information directly.
For example, the following applications maintain their incompatible lists just to get a token icon visible in the wallet: MyEtherWallet, TrustWallet, MetaMask, Parity. Then the services maintain their own lists: Uniswap, Loopring, IDEX.
Root cause: Blockchain persistent storage was deemed too expensive for this, community inability to come together for a common standard
Suggestion: Have also "icon", "homepage" and such as the part of the token standard and do not leave this for "third party curated registry."
Lack of notifications
Because how ERC-20 transfer events are implemented, wallets usually need to run extra infrastructure and servers to detect incoming token transfers. Developers lack generic "notify me for all incoming transfers for this address" event. (Furthermore it is even worse for ETH itself as it does not have any notifications and the only way to see balance changes is polling or heavily instrumented custom node.)
This makes it expensive to build wallets as you need to invest to the server-side infrastructure a lot, which is against the point of decentralisation.
Standard UX rules how the user finds out incoming transfer
ERC-20 wallets like MetaMask does not display incoming transfers by default if the ERC-20 token is not whitelisted in the MetaMask source code. This is to avoid airdrop spam attacks where desperate marketers send a small amount of tokens to everyone in the hope the user does a web search for this token and proceeds to buy or sell.
However, it also makes it impossible to send any tokens to new users. Because MetaMask wallet silently ignores all incoming transfers that are not whitelisted either by the MetaMask team or the user itself ("Add custom token") the first question of novice users if their tokens were lost.
Root cause: Community inability to come together for a common standard
Re-entrancy implementation guidelines
Because of re-entrancy issues on badly written smart contracts, people are afraid of moving away from ERC-20 even though these issues would have been already addressed. This has caused ossification of Ethereum token development, as ERC-20 is barely good enough, but users and developers will be suffering for the years to come.
Whereas this issue was addressed in late code examples and is now even highlighted in Solidity developer manual, the community has still not yet moved over this.
Root cause: Community ossification, psychological change resistance
Legacy useless functions
Functions like
increaseAllowance()
anddecreaseAllowance()
are legacy overreaching security research work and do not have any real life usage. They should be dropped.Beta Was this translation helpful? Give feedback.
All reactions