For further reading, see , “ICO Smart Contract Vulnerability: Short Address Attack”, or this .
The Vulnerability
When passing parameters to a smart contract, the parameters are encoded according to the . It is possible to send encoded parameters that are shorter than the expected parameter length (for example, sending an address that is only 38 hex chars (19 bytes) instead of the standard 40 hex chars (20 bytes)). In such a scenario, the EVM will add zeros to the end of the encoded parameters to make up the expected length.
Consider the standard ERC20 transfer function interface, noting the order of the parameters:
Now consider an exchange holding a large amount of a token (let’s say ) and a user who wishes to withdraw their share of 100 tokens. The user would submit their address, 0xdeaddeaddeaddeaddeaddeaddeaddeaddeaddead
, and the number of tokens, 100
. The exchange would encode these parameters in the order specified by the transfer
function; that is, address
then tokens
. The encoded result would be:
Let us now look at what would happen if one were to send an address that was missing 1 byte (2 hex digits). Specifically, let’s say an attacker sends 0xdeaddeaddeaddeaddeaddeaddeaddeaddeadde
as an address (missing the last two digits) and the same 100
tokens to withdraw. If the exchange does not validate this input, it will get encoded as:
The difference is subtle. Note that 00
has been added to the end of the encoding, to make up for the short address that was sent. When this gets sent to the smart contract, the parameters will be read as 0xdeaddeaddeaddeaddeaddeaddeaddeaddeadde00
and the value will be read as 56bc75e2d6310000000
(notice the two extra 0s). This value is now 25600
tokens (the value has been multiplied by 256
). In this example, if the exchange held this many tokens, the user would withdraw 25600
tokens (while the exchange thinks the user is only withdrawing 100
) to the modified address. Obviously the attacker won’t possess the modified address in this example, but if the attacker were to generate any address that ended in 0s (which can be easily brute-forced) and used this generated address, they could steal tokens from the unsuspecting exchange.