Tornado Cash Governance Overtaken
Notice: This page is a freshly imported case study from the original repository. The original content was in a different format, and may not have relevant information for all sections. Please help restructure the content by moving information from the 'About' section to other sections, and add any missing information or sources you can find. If you are new here, please read General Tutorial on Wikis or Anatomy of a Case Study for help getting started.
TornadoCash fell victim to a malicious governance proposal, putting control of various aspects of the smart contract in the hands of a single address. This was accomplished through a clever "bait and switch" with a smart contract that delegated calls to another. The original smart contract was self destructed and a new smart contract was deployed to the same address. The financial damage seems minimal, and there is reports that the attacker may be reverting the damage and relinquishing control.
About Tornado Cash
TornadoCash is "[a] fully decentralized protocol for private transactions on Ethereum." and "in the crypto-space."
As a decentralized protocol, Tornado.Cash smart contracts have been implemented within the Ethereum blockchain, making them immutable. They can neither be changed nor tampered with. Therefore, nobody - including the original developers - can modify or shut them down. All governance and mining smart contracts are deployed by the community in a decentralized manner.
As a non-custodial protocol, users keep custody of their cryptocurrencies while operating Tornado.Cash. This means that at each deposit, they are provided with the private key enabling the access to the deposited funds, which gives users complete control over their assets."
"Tornado Cash improves transaction privacy by breaking the on-chain link between source and destination addresses. It uses a smart contract that accepts ETH & other tokens deposits from one address and enables their withdrawal from a different address."
"Since its inception in 2019, Tornado Cash has been operating on the Ethereum blockchain. The protocol has been offering diversified fixed amount pools for six tokens (ETH, DAI, cDAI, USDC, USDT & WBTC) handled by the Ethereum blockchain.
Since June 2021, in addition to the Ethereum blockchain, Tornado Cash smart contracts have also been deployed on other side-chains & blockchains. These deployments enabled the tool to either support new tokens or benefit from Layer-2 advantages, such as faster and cheaper transactions."
This is a global/international case not involving a specific country.
The background of the exchange platform, service, or individuals involved, as it would have been seen or understood at the time of the events.
Include:
- Known history of when and how the service was started.
- What problems does the company or service claim to solve?
- What marketing materials were used by the firm or business?
- Audits performed, and excerpts that may have been included.
- Business registration documents shown (fake or legitimate).
- How were people recruited to participate?
- Public warnings and announcements prior to the event.
Don't Include:
- Any wording which directly states or implies that the business is/was illegitimate, or that a vulnerability existed.
- Anything that wasn't reasonably knowable at the time of the event.
There could be more than one section here. If the same platform is involved with multiple incidents, then it can be linked to a main article page.
The Reality
This sections is included if a case involved deception or information that was unknown at the time. Examples include:
- When the service was actually started (if different than the "official story").
- Who actually ran a service and their own personal history.
- How the service was structured behind the scenes. (For example, there was no "trading bot".)
- Details of what audits reported and how vulnerabilities were missed during auditing.
Controversy of Developer Payments
I hope someone can outshine the work and efforts, I undertook for this organisation. I emplore other contributors to come forward, although I do not recommend it.
What Happened
The TornadoCash governance mechanism was overtaken by a trojan horse proposal. After the community voted to pass the proposal, the contract was self destructed and replaced with a version which granted the attacker complete control over the TornadoCash governance (although no ability to withdraw funds). The attacker eventually published a proposal to revert their control back to the community.
| Date | Event | Description |
|---|---|---|
| May 20th, 2023 1:25:11 AM MDT | Governance Exploit | Blockchain transaction. |
| May 20th, 2023 2:01:00 PM MDT | Samczsun Technical Analysis | Samczsun publishes a technical analysis of the exploit[7]. |
| May 20th, 2023 4:00:00 PM MDT | Correction With Nova At Risk | [8]. |
| May 21st, 2023 3:23:00 AM MDT | BlockSec Team Analysis | The BlockSec team publishes an analysis of the attack exploit, including a slide with a diagram detailing how the attack worked[9]. |
| May 21st, 2023 5:54:00 AM MDT | SlowMist Technical Analysis | SlowMist publishes a technical analysis of the exploit[10]. |
| May 21st, 2023 6:43:00 AM MDT | Ameen Soleimani Warning Tweet | Twitter user Ameen Soleimani warns about the risk to funds in the Tornado Nova contract, and recommends all users to immediately withdraw. Though as he points out, it would take 7 days to execute a rug pull proposal[11]. |
| May 21st, 2023 12:43:00 PM MDT | Apporv Lathey Technical Deep Dive | NTFX protocol developer Apoorv Lathey published a deep technical dive into what happened on Twitter[12]. |
| May 23rd, 2023 8:39:00 AM MDT | Rekt Article Published | Rekt publishes an article on the situation[13][14]. |
Technical Details
This section includes specific detailed technical analysis of any security breaches which happened. What specific software vulnerabilities contributed to the problem and how were they exploited?
Exploiter Addresses: [15] [16]
Malicious Proposal: [17]
Related transactions: [18] [19] [20] [21]
"In a whirlwind of events, Tornado Cash's governance has been taken hostage via a trojan horse proposal, effectively granting control of the DAO to a single address."
"On 2023/05/20 at 07:25:11 UTC, Tornado Cash governance effectively ceased to exist. Through a malicious proposal, an attacker granted themselves 1,200,000 votes. As this is more than the ~700,000 legitimate votes, they now have full control."
"when the attacker created their malicious proposal, they claimed to have used the same logic as an earlier proposal which had passed. However, that wasn't exactly the truth, because they added an extra function"
"Once the proposal was passed by voters, the attacker simply used the emergencyStop function to update the proposal logic to grant themselves the fake votes"
"a proposal contract can be updated through a well-designed trick -- create and create2."
"2/ The attack is a sophisticatedly designed one. 1) The attacker used the name emergencyStop to hide the intent; 2) the attacker used a trick of combining CREATE/CREATE2 to create a contract with the same address with different bytecode."
"Proposal Contract was deployed via CREATE. The address for such contracts is derived by hashing deployer address and deployer nonce.
Note: Smart contracts start with nonce = 1
So, Proposal addr: 0xc50 = hash(0x7dc, 1)"
"After governance approved this Proposal Contract, the attacker called its emergencyStop function (which they added maliciously).
This resulted in the contract calling selfdestruct
Then the Deployer contract was self-destructed as well! (re-setting its nonce to 0)"
"The attacker used CREATE2 to deploy the exact same deployer bytecode.
Because of the same bytecode, the contract was deployed at the same address as before: 0x7dc
The nonce then became 1 (as address now had smart contract code)"
"The attacker then called "create(bytes)" function on the Deployer contract, but this time passing a completely new bytecode for their Malicious contract
As the nonce & deployer address were same as before, this resulted in the Malicious contract at the same address as Proposal"
"While the contracts do not allow for draining of the ~$275M in the privacy pools themselves, the exploiter gained control of the TORN governance token, the power to modify the router to reroute deposits/withdrawals, and admin status over Nova, the Gnosis chain deployment."
"Through governance control, the attacker can: - withdraw all of the locked votes - drain all of the tokens in the governance contract - brick the router
However, the attacker still can't: - drain individual pools"
"In this case, they simply withdrew 10,000 votes as TORN and sold it all"
Samczsun Technical Analysis
An analysis of the exploit was put together by samczsun[7][22].
On 2023/05/20 at 07:25:11 UTC, Tornado Cash governance effectively ceased to exist. Through a malicious proposal, an attacker granted themselves 1,200,000 votes. As this is more than the ~700,000 legitimate votes, they now have full control.
First, what does this mean for Tornado Cash? Through governance control, the attacker can: - withdraw all of the locked votes - drain all of the tokens in the governance contract - brick the router
However, the attacker still can't: - drain individual pools
Next, how did this happen?
Well, when the attacker created their malicious proposal, they claimed to have used the same logic as an earlier proposal which had passed. However, that wasn't exactly the truth, because they added an extra function
Once the proposal was passed by voters, the attacker simply used the emergencyStop function to update the proposal logic to grant themselves the fake votes
Now that they have all the votes, they can do whatever they want. In this case, they simply withdrew 10,000 votes as TORN and sold it all
Finally, what can we learn from this?
Be careful what you vote for! While we all know that proposal descriptions can lie, proposal logic can lie too! If you're depending on the verified source code to stay the same, make sure the contract doesn't have the ability to selfdestruct
BlockSec Technical Analysis
The BlockSec team put together a technical analysis of the exploit attack[23]. The overall attack was detailed on a Google Sheets[9].
1/ The key to the success of the Tornado Cash DAO attack is that 1) blindly vote -- vote without knowing the consequence; 2) a proposal contract can be updated through a well-designed trick -- create and create2.
2/ The attack is a sophisticatedly designed one. 1) The attacker used the name emergencyStop to hide the intent; 2) the attacker used a trick of combining CREATE/CREATE2 to create a contract with the same address with different bytecode.
3/ In summary, how to defend the DAO attack is still an open question. We will provide some open tools in the future to solve this issue. Stay tuned.
SlowMist Technical Analysis
The SlowMist Team published a technical analysis of the exploit[10].
Brief Analysis of TornadoCash Governance Exploit
On May 20, 2023, @TornadoCash suffered a governance attack, in which exploiters took control of the governance of TornadoCash by executing a malicious proposal.
Exploiters first created the proposal contract 0xC503893b3e3c0C6b909222b45f2a3a259a52752D through the 0xAF54612427d97489707332efe0b6290F129DbAcb contract on 2023-05-13 7:07 (UTC).
On 2023-05-13 at 7:22 (UTC), exploiters initiated the #20 proposal and explained in the proposal that the #20 proposal is a supplement to the #16 proposal and has the same execution logic.
But in fact, the proposal contract has an extra self-destruct logic, and its creator, 0x7dC86183274b28E9f1a100a0152DAc975361353d, was created through create2 and has a self-destruct function, so after it self-destructed with the proposal contract, the exploiters could still deploy different bytecodes to the same address in the same way as before.
Unfortunately, the community did not see the foul play in the proposed contract and many users voted for this proposal.
On 2023-05-18, 8:49 - 9:01 (UTC), exploiters repeatedly locked 0 tokens in governance by creating new addresses with multiple transactions.
Now you may be wondering how exploiters ended up taking out so many tokens for these addresses when they locked 0 tokens. The answer lies in the execution of the proposal.
By exploiting the feature that the proposal contract can be destroyed and redeployed with new logic, exploiters destroyed the proposal execution contract at 2023-05-20 7:18 (UTC) and deployed a malicious contract at the same address, whose logic was to modify the amount of tokens locked by the users in governance.
After the exploiters finished modifying the proposal contract, they executed the malicious proposal contract at 2023-05-20 7:25 (UTC). The execution of the proposal was performed via Delegatecall, and as a result, the execution of this proposal resulted in the token lock amount being modified to 10,000 for the addresses controlled by the exploiters in the governance contract.
After the execution of the proposal was complete, the exploiters unlocked the TORN tokens from the Governance Vault.
The TORN tokens reserve in the Vault was depleted and the exploiters took control of the governance at the same time. @samczsun enumerated the possible consequences of this.
Meanwhile, our @MistTrack_io team analyzed the addresses of the proposal voters and made some interesting discoveries
https://twitter.com/samczsun/status/1660042906500214784
Apoorv Lathey Technical Deep Dive
NTFX protocol developer Apoorv Lathey published a deep technical dive into what happened[12]:
Technical Deep Dive: How Tornado Cash governance exploiter was able to deploy a new malicious contract at the same address
TLDR of the attack: Governance approved innocent-looking Proposal contract. Attacker replaced the contract logic with a malicious one at the SAME address after selfdestruct.
The deployment flow of the Proposal contract involved a separate deployer contract to achieve this:
Proposal Contract was deployed via CREATE.
The address for such contracts is derived by hashing deployer address and deployer nonce.
Note: Smart contracts start with nonce = 1
So, Proposal addr: 0xc50 = hash(0x7dc, 1)
After governance approved this Proposal Contract, the attacker called its emergencyStop function (which they added maliciously).
This resulted in the contract calling selfdestruct
Then the Deployer contract was self-destructed as well! (re-setting its nonce to 0)
The attacker used CREATE2 to deploy the exact same deployer bytecode.
Because of the same bytecode, the contract was deployed at the same address as before: 0x7dc
The nonce then became 1 (as address now had smart contract code)
The attacker then called "create(bytes)" function on the Deployer contract, but this time passing a completely new bytecode for their Malicious contract
As the nonce & deployer address were same as before, this resulted in the Malicious contract at the same address as Proposal
Total Amount Lost
The total amount at risk has been estimated at $275,000,000 USD. The total amount lost has been estimated at $59,000 USD.
How much was lost and how was it calculated? If there are conflicting reports, which are accurate and where does the discrepancy lie?
Immediate Reactions
How did the various parties involved (firm, platform, management, and/or affected individual(s)) deal with the events? Were services shut down? Were announcements made? Were groups formed?
Ameen Soleimani Warning Tweet
RIP @TornadoCash governance
IF YOU HAVE FUNDS IN TORNADO NOVA
GTFO ASAP
there is about $1m in the nova contract, that the governance attacker can rugpull via proposal
fortunately the proposal would take 7 days to execute
best not wait!
Check out this great thread by @mesquka about the details of the hack!
tl;dr
the attacker took over the DAO, meaning they control everything the DAO owned:
- $TORN treasury
- relayer registry
- fee registry
- router contract
- tornadocash.eth ENS
The http://tornadocash.eth.link is controlled by the ENS, which means the attacker can point it to whatever they want...
Unfortunately, this also breaks the QR code on our tornado cash t-shirts from @TheMetaFactory, because those point to the .eth.link URL
RIP
The deployed UI also still points to the DAO controlled relayer registry, fee registry, and router contracts, which can now all be rugged.
Do not use the deployed UI.
Inevitably, anons will redeploy the UI and point it to new, immutable versions of the above contracts...
Tell your (non-US) friends to withdraw from Tornado Nova!
Also pull out your TORN LP tokens so the attacker stops dumping on you, silly goose.
Funds in Tornado Cash proper (not Nova) are safu
More from @MicahZoltu on how best (non-US) persons can interact with Tornado Cash
Ultimate Outcome
What was the end result? Was any investigation done? Were any individuals prosecuted? Was there a lawsuit? Was any tracing done?
"However, it seems not all is lost.
Yesterday, just before midday UTC, the exploiter published another proposal to revert the changes.
As long as there are no nasty surprises this time, this could be a bullet dodged for the Tornado Cash community."
Total Amount Recovered
The total amount recovered is unknown.
What funds were recovered? What funds were reimbursed for those affected users?
Ongoing Developments
What parts of this case are still remaining to be concluded?
Individual Prevention Policies
No specific policies for individual prevention have yet been identified in this case.
For the full list of how to protect your funds as an individual, check our Prevention Policies for Individuals guide.
Platform Prevention Policies
Policies for platforms to take to prevent this situation have not yet been selected in this case.
For the full list of how to protect your funds as a financial service, check our Prevention Policies for Platforms guide.
Regulatory Prevention Policies
No specific regulatory policies have yet been identified in this case.
For the full list of regulatory policies that can prevent loss, check our Prevention Policies for Regulators guide.
References
- ↑ https://defillama.com/protocol/tornado-cash (May 24, 2023)
- ↑ Tornado.cash (May 24, 2023)
- ↑ 3.0 3.1 Torn Token Historic Prices - CoinMarketCap (May 24, 2023)
- ↑ Introduction to Tornado Cash - tornado.cash (May 24, 2023)
- ↑ deomaius - "I hope someone can outshine the work and efforts, I undertook for this organisation. I emplore other contributors to come forward, although I do not recommend it." - Twitter (May 24, 2023)
- ↑ #18: Audit reimbursement and remuneration Q2 - Proposal - tornadocash.community (May 24, 2023)
- ↑ 7.0 7.1 samczsun - "On 2023/05/20 at 07:25:11 UTC, Tornado Cash governance effectively ceased to exist. Through a malicious proposal, an attacker granted themselves 1,200,000 votes." - Twitter (May 24, 2023)
- ↑ samczsun - "Correction: @CellierLael correctly pointed out that Tornado Cash Nova, deployed to Gnosis Chain, is a proxy that is administered by governance. Therefore, the attacker is also able to drain all of the ETH in that pool by upgrading the contract" - Twitter (May 29, 2023)
- ↑ 9.0 9.1 TornadoCash DAO Attack - BlockSec Google Slides (May 24, 2023)
- ↑ 10.0 10.1 SlowMist_Team - "Brief Analysis of TornadoCash Governance Exploit" - Twitter (May 24, 2023)
- ↑ 11.0 11.1 Ameen Soleimani - "there is about $1m in the nova contract, that the governance attacker can rugpull via proposal. fortunately the proposal would take 7 days to execute. best not wait!" - Twitter (May 24, 2023)
- ↑ 12.0 12.1 Apoorv Lathey - "Technical Deep Dive: How Tornado Cash governance exploiter was able to deploy a new malicious contract at the same address" - Twitter (May 24, 2023)
- ↑ Rekt - Tornado Cash Governance - REKT (May 24, 2023)
- ↑ RektHQ - "@TornadoCash governance has been taken hostage via a trojan horse proposal." - Twitter (May 29, 2023)
- ↑ Tornado.Cash Governance Exploiter | Address 0x092123663804f8801b9b086b03b98d706f77bd59 | Etherscan (May 24, 2023)
- ↑ Tornado.Cash Governance Exploiter 2 | Address 0x592340957ebc9e4afb0e9af221d06fdddf789de9 | Etherscan (May 24, 2023)
- ↑ Proposal | Address 0xC503893b3e3c0C6b909222b45f2a3a259a52752D | Etherscan (May 24, 2023)
- ↑ Transaction Tracer (May 24, 2023)
- ↑ Transaction Tracer (May 24, 2023)
- ↑ Transaction Tracer (May 24, 2023)
- ↑ Transaction Tracer (May 24, 2023)
- ↑ samczsun - "what does this mean for Tornado Cash? Through governance control, the attacker can: - withdraw all of the locked votes - drain all of the tokens in the governance contract - brick the router However, the attacker still can't: - drain individual pools" - Twitter (May 29, 2023)
- ↑ BlockSecTeam - "The key to the success of the Tornado Cash DAO attack is that 1) blindly vote -- vote without knowing the consequence; 2) a proposal contract can be updated through a well-designed trick -- create and create2." - Twitter (May 24, 2023)