Smart contracts are fundamentally bad software engineering, part 666 of a never-ending series — PeckShield have been running an automatic scanner on the public Ethereum blockchain:
Built on our earlier efforts in analyzing EOS tokens, we have developed an automated system to scan and analyze Ethereum-based (ERC-20) token transfers. Specifically, our system will automatically send out alerts if any suspicious transactions (e.g., involving unreasonably large tokens) occur.
They’ve found a couple of beauties, which they’ve branded “BatchOverflow” and “ProxyOverflow.” These affect multiple ERC-20 tokens — which are the basis for almost all ICOs.
The root cause is that smart contract coders just copy each other’s code a lot, because who needs formal methods when you can cut’n’paste’n’bodge.
On Sunday 22 April, PeckShield detected two transfers of 2255 — or, in hexadecimal, 0x8000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 — BeautyChain (BEC) tokens.
If you add these two numbers, you get 2256, a 257-bit number — or, since we’re working in Solidity, which has 256-bit integers, you get an overflow, and the counter cycles back around to 0.
This occurs in a function called batchTransfer() — a version of which is used in quite a lot of ERC-20 token contracts, because smart contract programmers copy code from each other lots and lots:
In line 257, amount is cnt times _value — and if _value is a huge number, this can easily overflow. This then passes the sanity checks in lines 258 and 259.
Finally, in lines 262 to 265, the balances of the two receivers will have the very large _value added to them.
batchTransfer() is not part of the ERC-20 standard, but it’s widely used — so, despite the CVE (CVE-2018-10299) specifying only BeautyChain, PeckShield found over a dozen tokens vulnerable to this exploit.