Toutes les vulnérabilités
CRITICALWeb3exploited in the wildcurated

WEB3-THEDAO-2016

Web3 · Ethereum · The DAO

Résumé

The DAO was an audacious 2016 experiment: a leaderless venture fund living entirely as a smart contract on Ethereum, which raised about $150 million in ether, then roughly 14% of all the ETH in existence. On 17 June 2016 an attacker exploited a reentrancy bug in its withdrawal logic to siphon out about 3.6 million ETH, a third of the fund. The theft forced an existential choice on Ethereum itself: let it stand on the principle that "code is law," or rewrite history to undo it. The community chose to undo it with a hard fork, and the minority who refused kept the original chain alive as Ethereum Classic. It is the foundational smart-contract hack, and the moment a blockchain had to decide whether its own rules were absolute.

How it happened

The DAO let any holder who disagreed with the group split off and withdraw their share of the ether, through a function called splitDAO. The flaw in it is now the most famous bug in crypto: a reentrancy error. The function sent the ether out to the caller before it updated that caller's balance to zero.

The attacker exploited the gap. Their receiving contract had a fallback function that, the instant it received ether from splitDAO, immediately called splitDAO again, re-entering the function before the first call had finished and before the balance had been decremented. So the contract paid out the same balance over and over inside one nested loop, draining far more ether than the attacker was ever owed. About 3.6 million ETH flowed out. What let the bug slip past auditors is that it lived in the interaction of two functions that were each safe on their own: the withdrawal helper was fine in isolation, and splitDAO was fine without it, but together they were lethal, which is exactly why reentrancy is so insidious to review. It is the textbook demonstration of why a contract must follow "checks-effects-interactions", update its own state before making any external call.

The hard fork and the Ethereum Classic split

The drained ether landed in a "child DAO" subject to a 28-day withdrawal delay, which bought the community time to react, and two things happened in that window. A volunteer "Robin Hood Group" used the very same reentrancy bug defensively, draining most of the remaining funds into a protected contract before the attacker could reach them. And the developers first tried a gentler fix, a soft fork to freeze the stolen ether, then abandoned it when Cornell researchers showed it would open a denial-of-service hole. That left a stark choice on a blockchain barely a year old. A smart contract is supposed to be immutable, and Ethereum's founding ideal was that "code is law", whatever the code does is final. But letting the theft stand would gut a large fraction of the young ecosystem. After fierce debate, the community executed a contentious hard fork at block 1,920,000 on 20 July 2016 that effectively rewound the theft and returned the funds. Roughly 85% of the network's mining power followed the new chain, which is the Ethereum we know today. A principled minority refused, arguing that reversing a valid execution betrayed the entire point of an immutable ledger, and kept mining the original chain, which lives on as Ethereum Classic. The split is permanent.

Why The DAO still matters

The DAO matters twice over. As security, it is the original reentrancy catastrophe, and despite being the most studied bug class in the space, reentrancy still drains protocols years later (it returned, through a compiler quirk, in the 2023 Curve hack). Checks-effects-interactions, reentrancy guards, and pull-over-push withdrawals are all standard practice because of it. As philosophy, it forced the question of whether a blockchain's immutability is truly absolute, and the answer, a community will override it under enough pressure, is written permanently into the existence of two Ethereums. (A year later, the US SEC ruled that DAO tokens had been unregistered securities, its first such finding for a crypto token.) The lesson for builders is concrete: update state before external calls, guard fund-moving functions, and test for reentrancy on every one, because "immutable" is a promise your governance may someday be asked to break.

Comment le corriger

  • For an active reentrancy drain there is little to do on-chain except pause the contract if it can be paused; The DAO bought time only because of a 28-day withdrawal delay.
  • Replace the contract with a fixed version that follows checks-effects-interactions and adds a reentrancy guard; deployed contracts cannot be edited, so the old one must be retired.
  • In the extreme, a chain-level hard fork can reverse the theft, as Ethereum did, but it is socially divisive and splits the community; treat it as a last resort, never a plan.

Comment l’éviter

  • Follow checks-effects-interactions: update balances and totalSupply before any external call.
  • Use a reentrancy guard (mutex) on functions that make external calls.
  • Prefer pull-over-push withdrawals and minimize ether transfers inside state transitions.
  • Limit gas forwarded on external calls or use transfer-style patterns where appropriate.
  • Add reentrancy-focused invariant and property tests for every fund-moving function.

Références

Vulnérabilités liées

Tout Web3 →