Rationale for depth limit:
Having a 1024 call depth limit - many programming languages break at
high stack depths much more quickly than they break at high levels of
memory usage or computational load, so the implied limit from the
block gas limit may not be sufficient.
The EVM needs to be deterministic. If an Ethereum client is implemented in a language that breaks at high stack depths, then such a client would not be able to implement the Ethereum protocol: it would not be able to produce the results according to consensus.
A recent proposal by Vitalik Buterin is to simply have gas as the limiting factor (though the depth could reach 2091).
function foo() {
send()
send()
}
Both send()
can be attacked. Invoking the first send()
increases the depth by 1, but reduces it again by 1 when it returns. send()
doesn't throw
, so no exceptions are generated.
To attack foo()
, an attacker recursively invokes itself 1023 times, then invokes foo()
. (In Solidity, the recursive function should be external
so that the call depth is increased [unlike internal functions which are jumps within the code and don't increase the depth].)
(Invokes itself 1023 times because the first invocation before the recursion increases the depth by 1. By the time foo
is called, the depth will be at the 1024 limit.)
EDIT: EIP 150 makes it impractical to reach a stack depth of 1024, effectively eliminating call depth attacks. See How does EIP 150 change the call depth attack?