37

A Simpler Explanation The attacker creates a wallet contract (0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89 in the 17/06/2016 attack) with a default (or fallback) function () to call The DAO's splitDAO(...) function a number of times. Following is a simple default function (): function () { // Note that the following statement can only be called ...


14

If your code looks like this in pseudo code: function do: if (pool has mymoney = true) split(mymoney) pool has mymoney = false By repeatedly calling that function, you have sort of a race condition where you are allowed to spend your money twice, trice, ... ad infitum. Fix is simple, reverse two operations: function do: if (pool has ...


10

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 ...


10

Call depth attack A. No. If the call depth is at 1024, employeeAddress.send will fail. The depth remains at 1024 and bossAddress.send will also fail. The depth will only decrease to 1023 when payout (or its caller, depending on how payout is invoked) is finished. B. Yes, that all sounds correct and no need for any call depth manipulation. C. There is ...


5

A "recursive calling vulnerability" is an ambiguous term that should be avoided because it is imprecise and can mean 2 things. Reentrant attack You probably mean "reentrancy vulnerability" or "reentrant attack", which is what @Roland's answer describes. Note: not all reentrant attacks have to be recursive (in the sense that malicious code does not have to ...


3

Whew, I've figured it out. I couldn't make stack depth attack work with call though. I used delegatecall instead. Here's an example that shows how it works. contract Attacker { Victim public victimContract; uint x; function Attacker(){ victimContract = (new Victim).value(10 wei)(); } function attack(uint y) { if (y > ...


3

Instead of Attacker(this).reachStackDepth(x++);, shouldn't you do Attacker(this).reachStackDepth(++x);? Or do x++; before you call reachStackDepth().


3

This attack was eliminated for all practical purposes by EIP 150, which was implemented in October, 2016. For details see How does EIP 150 change the call depth attack?


3

The normal stack is what you describe. This is where the basic opcodes take their operands. The call stack is in relation to calls between contracts. You see, when you send a transaction to a smart contract, the execution there starts with an empty memory and an empty normal stack. That is true when you sign a transaction and send it to a contract. That ...


2

There is link describing how 63/64 rule allowed to execute transaction but to waste a lot of gas instead of just failing: https://github.com/Synthetixio/synthetix/issues/243


2

It is not possible to reach callstack depth 1024, because the max forwarded gas is always 63/64 of the total available gas. The block gas limits need to be of the order of 1e8 ((63/64)^1024) in order to reach this depth.


1

Call depth attacks are impractical now (see EIP114 and EIP150). So they could be only reproduced in old versions of EVM.


1

This is answered in What was the second vulnerability used in The DAO attack on 17 June 2016? . What the attacker did was to transfer their tokens from account to account so they could repeatedly call the SplitDAO recursively 29 x something like: for (i = 1 to 482) { call wallet default function () // which performed the following: // transfer ...


Only top voted, non community-wiki answers of a minimum length are eligible