Reddit post Worry-some bug / exploit with ERC20 token transactions from exchanges and the Golem post How to Find $10M Just by Reading the Blockchain.
This problem seems to be about how the exchanges implement their withdrawal functions and seems to be as follows:
- A user has a certain ERC20 token balance in the exchange, say 1,000 units
- The user wants to withdraw this balance into an external Ethereum address
- The user specifies an external Ethereum address that is too short, and the balance of 1,000 units
- The exchange check the amount to be transferred and this falls within the user’s balance amount
- The exchange issues the
ERC20.transfer(address, value)
with the address that is too short, and the correct value - The Ethereum JSON-RPC or Web3 JavaScript API that the exchange calls will shift the amount field into the gap in the address field. The amount field is then increased by many orders, e.g., 1,000 becomes 1,000,000
- The transaction will transfer 1,000,000 units of the token to the user’s address
- The user can craft the address to end with zeroes so the padding of the gap with the value field will result in the user’s correct address
The transaction that raised the issue is 0x0213fb70… and has the following transfer data:
1 2 3 |
Function: transfer(address _to, uint256 _value) 0xa9059cbb0000000000000000000000000797350000000000000000000000000000000000000000000005150ac4c39a6f3f0000 |
Breaking up the data into the proper chunks:
1 2 3 4 5 6 7 |
0x // Hex prefix a9059cbb // web3.sha3("transfer(address,uint256)").substring(0,10) => "0xa9059cbb" 0000000000000000000000000797350000000000 // address - 40 characters 000000000000000000000000000000000005150ac4c39a6f3f0000 // value - 54 characters - should be 64 characters // Ruler below 1234567890123456789012345678901234567890123456789012345678901234 |
The value field will be padded with zeros to make up 64 characters:
1 2 3 4 5 6 7 8 9 10 11 12 |
// Intended transfer amount // new BigNumber("5150ac4c39a6f3f0000",16).div(1e18) // 23999.99 000000000000000000000000000000000005150ac4c39a6f3f0000 // Actual transfer instruction // new BigNumber("5150ac4c39a6f3f00000000000000",16).div(1e18) 26388268071507722.24 000000000000000000000000000000000005150ac4c39a6f3f00000000000000 // Ruler below 1234567890123456789012345678901234567890123456789012345678901234 |
Conclusion – CryptoDerivatives.Market Is Not Affected By The Exchange ERC20 Withdrawal Bug.