2/ There are two kinds of problematic transfers in the financial world: authorised and unauthorised. In this Twitter thread, we focus on authorised transfers - i.e. the account owner signs the transfer himself.
3/ Unauthorised are usually caused by malware on your PC.
The root cause of unauthorisation transfer problems is 99% time the usage of Microsoft Windows, Excel macros and such. Only Microsoft could fix this, and they have not been doing great for the last 20 years.
The root cause of unauthorisation transfer problems is 99% time the usage of Microsoft Windows, Excel macros and such. Only Microsoft could fix this, and they have not been doing great for the last 20 years.
4/ Then for the authorised transfers, there are two cases
- I know what I am signing, but someone is later exploiting you (rugpulls, romance scams)
- I don't know what I am signing, but I do it in any case
- I know what I am signing, but someone is later exploiting you (rugpulls, romance scams)
- I don't know what I am signing, but I do it in any case
5/ In this thread, we focus only on the last case:
"I am signing something that I do not understand."
Why would you do that? Sounds pretty stupid.. easy to go to victim blaming here.
"I am signing something that I do not understand."
Why would you do that? Sounds pretty stupid.. easy to go to victim blaming here.
6/ A notable recent example is when Kevin Rose signed off $2M worth of NFTs by accident.
7/ But crypto it is different...! Let's explore how the signing scams came to be, why were the signing schemes created in the first place and how they are now used to dupe millions out of users.
9/ When you transfer fiat money between bank accounts, it clearly says "I am going to transfer XXX boomer money to my landlord."
Ethereum crypto wallets do not do this.
Ethereum crypto wallets do not do this.
10/ This is simply because the wallet does not know what most Ethereum transactions are doing.
12/ Well... no. Back in the day, Ethereum developers decided otherwise when the ERC-20 token transfer standard was created.
13/ The original proposals had few mechanisms for transferring tokens.
14/ Specifically, the mistake was made that plain value transfers and smart contract interactions use different transfer() methods... you suddenly have two different transfers and need to know to use the correct one!
15/ Then, for the smart contract interactive transfers there were options...
- approve() and transferFrom() takes two physical transactions, and that's why you have two MetaMask popups on Uniswap swaps
- approve() and transferFrom() takes two physical transactions, and that's why you have two MetaMask popups on Uniswap swaps
16/ - transferAndCall(), approveAndCall(), their variants, doing everything in a single transfer() with cleaner semantics that user could understand
All variants share the same fundamental logic but some minor implementation differences. Various ERCs have been written on this.
All variants share the same fundamental logic but some minor implementation differences. Various ERCs have been written on this.
17/ The ERC-20 author chose approve() and transferFrom(). This is because Ethereum smart contract security community feared, and still fears, re-entrancy attacks.
"Any tradeoff is sufficient as long the Solidity development attack surface here is minimised."
"Any tradeoff is sufficient as long the Solidity development attack surface here is minimised."
18/ This was in the aftermath of TheDAO incident. Ethereum was not widely used yet, there were only a handful of smart contracts in existence. For the full chain of events, read my comments here:
19/ Later, Ethereum NFT standards inherited ERC-721 inherited ERC-20 transfer semantics:
eips.ethereum.org
eips.ethereum.org
20/ Because the logic of two transactions of approve() and transferFrom() is unergonomic (you get two MetaMask popups instead of one, spend more gas), various solutions have been proposed to make everything happen in a single transaction.
21/ Instead of working towards making a better ERC token standard with clean transfer(from, to, amount) semantics, a lot of stopgap fixes have been attempted on the top of ERC tokens to wiggle out more out of it.
22/ Stop gap fixes have made it worse by
- Not focusing on the end-user security
- Still not offering clean transfer() semantics
- Making complex signature schemes that users do not understand
- Making it harder to interact because different incompatible schemes
- Not focusing on the end-user security
- Still not offering clean transfer() semantics
- Making complex signature schemes that users do not understand
- Making it harder to interact because different incompatible schemes
24/ All of these schemes use a custom signature or approval scheme, which is not user readable and does not clearly state what assets it is transferring.
Furthermore, the schemes are incompatible with each other.
Furthermore, the schemes are incompatible with each other.
25/ These schemes also do not focus on the holistic security.
They sure make
- Solidity developer work easier
- Smart contract auditor work easier
- Save gas
... but there is no focus on the UX, etc.
They sure make
- Solidity developer work easier
- Smart contract auditor work easier
- Save gas
... but there is no focus on the UX, etc.
26/ To add to the insult of the offence, services like Uniswap and OpenSea miseducate users to give infinite approvals and sign anything.
27/ Because users are conditionalised to sign any opaque signatures, like Microsoft Windows yes / no popups, the security nightmare and the scam scene were born.
29/ In a retrospective, it would have been much better to have ERC-20 without the need for approve() from the beginning.
30/ Any re-entrancy attack fears could be mitigated on a lower level, as this is a separate concern from a token standard anyway. Solidity compiler built-in support comes to mind.
Also, note that ERC-20 tokens themselves can still be re-entrant if they are malicious.
Also, note that ERC-20 tokens themselves can still be re-entrant if they are malicious.
31/ The best evidence that the problem is self-inflicted is that other newer blockchains do not have these issues.
Thus, in theory, Ethereum-based chains could solve this properly as well.
Thus, in theory, Ethereum-based chains could solve this properly as well.
32/ @cosmos has MsgSend semantics in its bank module that offers a simple way to reason about any token transfer:
cosmwasm.github.io
cosmwasm.github.io
33/ @fuellabs_ and Sway programming language make re-entrancy attacks impossible at the compiler level:
forum.fuel.network
(Also I heard there might be EVM port of Sway)
forum.fuel.network
(Also I heard there might be EVM port of Sway)
34/ @MultiversX offers an extensible token standard where the core is unchangeable, and transfer semantics are well defined
docs.multiversx.com
docs.multiversx.com
35/ Other chains with better token transfer semantics include NEAR, Chia, et.
But some new chains also copy ERC-20 1:1 which is not very smart at this point.
But some new chains also copy ERC-20 1:1 which is not very smart at this point.
37/ I believe this problem is very difficult to fix because of coordination problems with the Ethereum community. It is not really "anyone's problem", and developers themselves are not hurt because of the bad token standards.
38/ I believe this because numerous ERC standards were proposed over the years, even before ERC-20. However, the narrow scope of in the way of Ethereum security researchers think about re-entrancy and ignore clean semantics and UX makes progress difficult.
39/ A large number of scams are directly enabled by approve() and signatures. They have
caused massive losses for users. Enabling approve and signature behaviour is partially responsible for taking the industry's reputation to the gutters.
caused massive losses for users. Enabling approve and signature behaviour is partially responsible for taking the industry's reputation to the gutters.
40/ One of the most common arguments against public blockchains is that users cannot be trusted with their own wallets. Unfortunately, this is true, and this is partially caused by authorised illegitimate transfer issues caused by bad ERC standards.
41/ Any large project that could be in a position to move the needle has its own pet peeves, like permit(), Permit2, and so on. They are not holistically attempting to solve the problem.
42/ And more duct tape is slapped on: Because of broken ERC transfer semantics, wallets now start to pile "simulations" in their transfers, making it complicated to build a secure Ethereum wallet
(These simulations can be gamed)
(These simulations can be gamed)
43/ The long-term future is likely on another chain which solves any basic functionality like good and secure wallet UX from the start. This wallet UX is largely driven by having good token standards.
Loading suggestions...