An attacker took effective control of Tornado Cash governance on May 20, 2023, after replacing the code behind an approved proposal and executing it through the protocol’s governance contract. Ethereum transaction records show Proposal 20 was executed successfully at 07:25:11 UTC. A later technical reconstruction by Coinbase found that the execution assigned 1.2 million TORN in artificial locked balances across 101 accounts, giving the attacker dominant voting power.
The incident mattered beyond the immediate loss of governance tokens. Tornado Cash relied on token voting and executable smart-contract proposals to administer parts of the protocol. The takeover demonstrated that a proposal could pass the published voting and timelock process while its executable behavior changed before execution.
An approved address acquired different code
The attacker submitted Proposal 20 on May 13, 2023. Its on-chain description said it would penalize four relayers and use the same logic as Proposal 16. Tornado Cash’s governance documentation described a five-day voting period, a two-day timelock and execution of proposal contracts through `delegatecall`, which runs proposal logic in the governance contract’s storage context.
The initial Proposal 20 contract resembled the earlier relayer proposal but included an `emergencyStop()` function capable of destroying the contract. After voting ended, the attacker invoked that function at 07:18:35 UTC on May 20. Twelve seconds later, a deployment chain using Ethereum’s `CREATE2` and `CREATE` operations placed different bytecode at the same proposal address.
That address continuity was the trap. Reviewing an address or its earlier code was insufficient because the contract could be destroyed and recreated. The replacement retained the expected relayer operations while adding storage writes that credited 100 prepared accounts with 10,000 TORN each and one account with 200,000 TORN. The resulting total was 1.2 million TORN in fabricated governance balances.
Execution converted code risk into control
At 07:25:11 UTC, the attacker called the governance contract and executed Proposal 20. The transaction emitted a `ProposalExecuted` event identifying proposal number 20. Because execution used `delegatecall`, the replacement proposal modified governance storage rather than merely changing its own isolated state.
The immediate, verified consequence was control over the governance system and access to TORN held as locked governance balances. Coinbase’s transaction reconstruction records withdrawals of 4,000 TORN at 07:34:35 UTC and another 6,000 TORN at 10:22:35 UTC on May 20. Accordingly, the event-day window from 00:00 through 23:59 UTC supports a confirmed withdrawal total of 10,000 TORN. No dollar value is assigned here because venue prices and liquidity varied during the incident, and a token quotation would not measure the broader cost of compromised governance.
The takeover did not establish that the attacker could directly empty every Tornado Cash deposit pool. Contemporaneous reporting distinguished control of governance, locked votes and potentially the router from custody of assets inside immutable pool contracts. That limitation was important: governance compromise was severe, but it was not equivalent to a verified drain of all funds processed by the mixer.
Why the governance model failed
The transaction sequence exposed a review failure at the boundary between social approval and executable code. Voting participation and a timelock worked as configured. They did not protect the system when voters approved a proposal address whose code could later be replaced.
The event therefore challenged a common institutional assumption about decentralized governance: transparent transactions do not guarantee that participants have reviewed the code path that will exist at execution. Proposal immutability, bytecode verification at execution and restrictions on destructive or redeployable contracts were separate controls that the voting process did not supply.
Later context
A Coinbase analysis published after the incident traced a further withdrawal of 473,000 TORN on May 21, bringing the reconstructed total to 483,000 TORN. That later transaction is included only as retrospective context and is not presented as information available within the May 20 event-day window.
The complete source packet and revision history are retained with the newsroom record.
Automated systems may have assisted with source organization and drafting. Coinburn is accountable for the published text and maintains a revision record.
This article provides news and analysis, not investment, legal or tax advice. Digital assets are volatile and may result in total loss.

