Back to Home

()

exploit
0xc0ee9db1a9e0...86bf68d47b89
HomesteadContract #19KExact Bytecode MatchEdit this contract
Deployed June 15, 2016 (10 years ago)Block 1,706,608

Reentrancy contract from the June 17, 2016 DAO attack. Its owner triggered recursive splitDAO calls to drain The DAO. Exact structural source reconstruction.

Homestead EraVerified Source

Historical Significance

On June 17, 2016, this reentrancy pattern drained about 3.6 million ether from The DAO, worth roughly 60 million US dollars at the time and close to 15 percent of all ether then in circulation. The stolen funds were routed into a child DAO, sometimes called the Dark DAO (0x304a554a), which was subject to a 28 day withdrawal delay. That delay set off a public race to secure the remaining funds before the attacker could cash out.

The theft forced the most contentious decision in Ethereum's history. On July 20, 2016 the network executed a hard fork at block 1,920,000 that moved the drained funds to a recovery contract and effectively reversed the theft. A portion of the community rejected the fork on the principle that a blockchain's recorded history must remain immutable, and continued the original unforked chain as Ethereum Classic (ETC). The forked chain retained the name Ethereum (ETH). The split gave the ecosystem two persistent chains and a lasting philosophical divide between immutability and intervention.

References:

Context

The DAO was a decentralized venture fund launched in April and May 2016 by slock.it, a German startup founded by Christoph Jentzsch, Simon Jentzsch, and Stephan Tual. Participants sent ether to the contract in exchange for DAO tokens that carried voting rights over how the pooled capital would be invested. The crowdsale gathered more than 12.7 million ether, over 150 million US dollars at the time, which made it the largest crowdfunding event created up to that point.

Token holders could exit through a splitDAO function that created a child DAO and returned a proportional share of ether along with accrued rewards. The flaw was in the ordering of that reward path: ether was sent to the caller before the caller's token balance was cleared, which let a contract re-enter and withdraw repeatedly within a single transaction.

After the attack began, the White Hat Group, including Griff Green, Lefteris Karapetsas, and others, deployed contracts using the same exploit to move the remaining vulnerable ether beyond the attacker's reach. Following the July 20, 2016 hard fork, recovered funds were made claimable through a WithdrawDAO contract, letting original DAO token holders redeem their share.

Token Information
Token Name

Symbol

Decimals
1
Key Facts
Deployment Block
1,706,608
Deployment Date
Jun 15, 2016, 08:23 AM
Code Size
2.1 KB
Gas at Deploy
665,050
Transactions by Year
2016257

Description

This is one of the malicious contracts used to drain The DAO. It exploited a reentrancy flaw in the way The DAO paid out rewards when a token holder split away from the fund.

The attack ran through the contract's own functions and its fallback. The owner first called the trigger function (selector 0x625e847d), which set counter to 1 and called splitDAO(proposalID, curator) on The DAO. Splitting caused The DAO to send this contract its share of the reward account, and that incoming ether invoked the contract's fallback function.

The recursion lived in the fallback. When the caller was The DAO's reward account, the fallback compared counter against limit (set to 29 on the primary instance). While counter was still below the limit it incremented counter and called splitDAO again, before The DAO had finished updating its internal token balances. Because the balance had not yet been zeroed, each nested call paid out against the same tokens a second time. Once counter reached the limit the fallback stopped recursing, moved the accumulated DAO tokens to a paired address held in next, and reset counter to 1 so the cycle could be repeated. If any address other than the reward account triggered the fallback, it emitted an event carrying the string constuctor fail. The misspelling of the word constructor is present in the original on-chain bytecode and is one of the contract's distinguishing fingerprints.

Ether left the contract through owner2.send(this.balance) in the trigger and setup functions, forwarding the balance to an address the attacker controlled. All five byte-identical instances hardcode The DAO at 0xbb9bc244d798123fde783fcc1c72d3bb8c189413, supplied as the constructor argument.

This source is an exact structural reconstruction. It compiles with solc 0.3.5 (June 2016 nightly, optimizer on) to a byte-for-byte match of the on-chain 2142-byte runtime, except for five identifier names that cannot be recovered from bytecode (two public getters, the trigger function, a setter, and one event). Placeholder names are used for those five.

Source Verified

SolidityExact bytecode match(2,142 bytes)
Compiler: v0.3.5-

Compiles with solc 0.3.5 (2016-06-14 nightly, commit 371690f0, optimizer on) to a byte-for-byte match of the on-chain 2142-byte runtime, with the sole exception of five identifier names whose original spellings cannot be recovered from bytecode (two public getters at slots 5 and 7, the onlyOwner trigger 0x625e847d, the setter 0x7f9f519f, and the event topic 0xbab6859b). Placeholder names limit, owner2, attack, setLimit, and NewLimit are used for those five. Everything else is confirmed exact. Verified by placeholder-substitution (0 differing bytes), Panoramix decompilation, and on-chain usage of every function.

Heuristic Analysis

The following characteristics were detected through bytecode analysis and may not be accurate.

Detected Type: exploit
Has ERC-20-like patterns

Bytecode Overview

Opcodes2,142
Unique Opcodes206
Jump Instructions99
Storage Operations61

External Links

Related contracts