A Survey of Attacks on Ethereum Smart Contracts
1. Summary
Some of the primitives used in Solidity to invoke func- tions and to transfer ether may have the side effect of invoking the fallback function of the callee/recipient. We illustrate them below.
callinvokes a function (of another contract, or of itself), and transfers ether to the callee. E.g., one can invoke the functionpingof contractcas follows:c.call.value(amount)(bytes4(sha3("ping(uint256)")),n);where the called function is identified by the first 4 bytes of its hashed signature,
amountdetermines how many wei have to be transferred toc, andnis the actual parameter of ping. Remarkably, if a function with the given signature does not exist at addressc, then the fallback function ofcis executed, instead.sendis used to transfer ether from the running contract to some recipientr, as inr.send(amount). After the ether has been transferred,sendexecutes the recipient’s fallback.delegatecallis quite similar tocall, with the difference that the invocation of the called function is run in the caller environment. For instance, executingc.delegatecall(bytes4(sha3("ping(uint256)")),n)if
pingcontains the variable this, it refers to the caller’s address and not toc, and in case of ether transfer to some recipientd— viad.send(amount)— the ether is taken from the caller balance.besides the primitives above, one can also use a direct call as follows:
contract Alice { function ping(uint) returns (uint) } contract Bob { function pong(Alice c){ c.ping(42); } }The first line declares the interface of
Alice’s contract, and the last two lines containBob’s contract: therein,ponginvokesAlice’spingvia a direct call. Now, if the programmer mistypes the interface of contractAlice(e.g., by declaring the type of the parameter asint, instead ofuint), andAlicehas no function with that signature, then the call topingactually results in a call toAlice’s fallback function.
Here is a list of vulnerabilities
- Exception disorder. In Solidity there are several situations where an excep- tion may be raised, e.g. if (i) the execution runs out of gas; (ii) the call stack reaches its limit; (iii) the command throw is executed. However, Solidity is not uniform in the way it handles exceptions: there are two different behaviours, which depend on how contracts call each others.
- if every element of the chain is a direct call, then the execution stops, and every side effect (including transfers of ether) is reverted. Further, all the gas allocated by the originating transaction is consumed;
 - if at least one element of the chain is a 
call(the casesdelegatecallandsendare similar), then the exception is propagated along the chain, reverting all the side effects in the called contracts, until it reaches acall. From that point the execution is resumed, with thecallreturning false10. Further, all the gas allocated by the call iscall. 
 - Gasless send. When using the function 
sendto transfer ether to a contract, it is possible to incur in an out-of-gas exception. This may be quite unex- pected by programmers, because transferring ether is not generally associated to executing code. - Type casts. The Solidity compiler can detects some type errors.
 - Reentrancy. The fallback mechanism may allow an attacker to re-enter the caller function. This may result in unexpected behaviours, and possibly also in loops of invoca- tions which eventually consume all the gas.
 - Keeping secrets. Declaring a field as private does not guarantee its secrecy. This is because, to set the value of a field, users must send a suitable transaction to miners, who will then publish it on the blockchain. Since the blockchain is public, everyone can inspect the contents of the transaction, and infer the new value of the field.
 - Immutable bugs. Once a contract is published on the blockchain, it can no longer be altered.
 - Stack size limit. Each time a contract invokes another contract (or even itself via 
`this.f()) the call stack associated with the transaction grows by one frame. The call stack is bounded to 1024 frames: when this limit is reached, a further invocation throws an exception.