Proposal #4: Tornado Trees upgrade

ZKP Tree updates proposal


TORN Mining is currently stuck because nobody is paying for the gas cost of updating the Merkle tree. This proposal would introduce a new Merkle tree leveraging Zero Knowledge proof that would be an order of magnitude cheaper to update and would therefore unstuck mining. The proposal is live at vote now if you support it.


Back in December 2020 the Tornado Cash team annouced a governance layer for the ecosystem. This system came with a very novel way of incentivising Tornado cash usage to create a strong anonymity set. Up to 10% of the total supply of TORN can be “mined” by user depositing funds in the anonymity pools. The system works by first earning AP (Anonymity Points) proportionally to the amount of time spent in the pool. Once the AP is earned they need to be claimed for each individual pool withdrawal. After the claim, the last step is to swap the AP for TORN in an AMM.

Because the anonymity of the miners have to be preserved this system works by having a third party, updating the Merkle tree that allows people to claim. You can only update the the deposit+withdrawal in the tree in the order they were made. Meaning that if 100 withdrawals are ahead of me in the tree queue, I would have to update and pay gas for these 100 withdrawals before mine can be added to the tree.
Problem: There is currently no incentive to update the tree and therefore, nobody is doing it. Gas costs are a lot higher than anticipated by the TCash team when they designed the system. The result is that people can’t claim AP reward. This is the message that you likely see if you try to claim AP:

Currently, there is more than 12000 withdrawals with and 15000 deposits in the Tree queue waiting to be included. To update 60 deposits or withdrawals, it cost around 5 millions gas, at 120 Gwei that’s 0.6 ETH or around $1000 at current price. That means that to update all pending withdrawals and deposits it would cost around $450k for 2-3 months of withdrawals. I would estimate that almost $100k of gas per month is needed to keep the tree updated assuming a gas price between 100 and 200 Gwei.


This proposal introduce a new system that will drastically reduce the cost of updating the Merkle tree by leveraging Zero Knowledge Proof. Zero Knowledge Proofs allow to verify the correctness of a function output without actually doing the computation (therefore reducing gas cost!). ZKP is already a core technology making Tornado Cash anonymity pool possible. They would be reused here but to achieve a different purpose. This update require a new Tornado Cash proxy contract.

ZKP tree contract

The new tree contract code can be found here (In contracts/TornadoTrees.sol):

The proposal contract setting up and configuring the new tree contract can be found here (In contracts/Proposal.sol):

The update functions updateDepositTree and updateWithdrawalTree will load exactly 256 deposits leafs or 256 withdrawals leafs at once. Along with those you have to pass the new Merkle root and the ZKP of the root calculation.
Like before, a repo is provided with a script creating the ZKP and calling the update function. This script can be found on this repo, (be sure to be on the snark branch): GitHub - tornadocash/tornado-root-updater at snark

One call to one of the update function cost around 1,065,929 gas thefore reducing the gas cost by a factor of 13.

Some additional considerations on the tree contract:

  • It is proxy upgradable by governance

New Tornado Cash proxy

A new Tornado Proxy was required because it is the proxy that adds withdrawals and deposits to the Tree queue. It therfore needs to point to a new tree contract.

The proxy also introduce one new feature, the support for ERC20 anonymity pools. Up to now, ERC20 pools were not going through the proxy. Users were interacting directly with the pool contract. Now users will have a choice to go through the proxy. The benefit of going to the proxy is that ERC20 pool can be used for anonymity mining.
Important: That does not mean that ERC20 pool will have mining activated but that they can be activated in the future by governance.

The function updateInstance has an onlyGovernance modifier and will allow governance to add and remove instances (= pools) from the proxy but also to activate/deactivate mining for an instance.

Additional consideration for the proxy contract:

  • The UI will now have to point to the new proxy
  • Relayers will have to upgrade to point to the new proxy

Proposal contract

The proposal will deploy configure the new Proxy and Tree contracts described above. This how the system reconfigured for these contracts to work:

  1. The tree contract is initialized with the latest Merkle root of the old tree contract. The new tree takes over from here. That means that if you are currently farming AP, you are not affected, you will be able to claim AP as expected once the tree is updated

  2. The proposal will register the following pools with mining enabled:

    • 0.1 ETH 0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc
    • 1 ETH 0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936
    • 10 ETH 0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF
    • 100 ETH 0xA160cdAB225685dA1d56aa342Ad8841c3b53f291
  3. The proposal will register the following pools with mining disabled:

    • 100 DAI 0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3
    • 1k DAI 0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144
    • 10k DAI 0x07687e702b410Fa43f4cB4Af7FA097918ffD2730
    • 100k DAI 0x23773E65ed146A459791799d01336DB287f25334
    • 5k cDAI 0x22aaA7720ddd5388A3c0A3333430953C68f1849b
    • 50k cDAI 0x03893a7c7463AE47D46bc7f091665f1893656003
    • 500k cDAI 0x2717c5e28cf931547B621a5dddb772Ab6A35B701
    • 5m cDAI 0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af
    • 100 USDC 0xd96f2B1c14Db8458374d9Aca76E26c3D18364307
    • 1000 USDC 0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D
    • 100 USDT 0x169AD27A470D064DEDE56a2D3ff727986b15D52B
    • 1000 USDT 0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f
    • 0.1 WBTC 0x178169B423a011fff22B9e3F3abeA13414dDD0F1
    • 1 WBTC 0x610B717796ad172B316836AC95a2ffad065CeaB4
    • 10 WBTC 0xbB93e510BbCD0B7beb5A853875f9eC60275CF498

    Note that the ETH pools are the already existing pools. The ERC20 pools are the pools that already existed before (long before TORN was introduced) plus the recently deployed pools. See: New pools are here! DAI, cDAI and WBTC - #2 by gewitet

  4. The miner contract will be configured to point to the new tree contract.


  • ABDK
  • ZeroPool 1 2


Here’s a smart contract address for this proposal Proposal | 0x4b6c07b8940a7602fe4332afa915b366e56eace5

Now someone with 1000 TORN needs to submit this proposal contract to Tornado Cash Governance for voting

Update: The proposal is live at vote now if you support it.


This is great! It is finally here. I would like to thank @poma and all Tornado team members for their hard work :pray: .


Yes please ! There are about 20-25 accounts only, taking away the vesting ones, am I correct ?

I would be happy to submit this proposal if someone is looking to sell me 1,000 TORN OTC at the current market price with no slippage.

I have around 500 and can delegate to one of the devs. PM me if needed.

I think we can suggest in community to all people who want to delegate to 1 address to have 1000 Torn for proposal.
But we need one address who have a bigger amount!
If someone have an address and want to share ,i can delegate is well,dont have much,but im sure there are more people who will want to delegate.

We need a single address with at least 1000 TORN, you can’t cumulate several delegations.

1 Like

…unless we propose through a smart contract. But let’s try an easy way first.

1 Like

Didnt know about that.Then we need to wait a person who will start this proposal.:grimacing:

reducing the gas cost by a factor of 13

It will still cost $30k-40k to update the whole tree. Not exactly sure if it will solve the problem… Also, what if there’s not enough votes for the proposal? It seems there’s an incentive for holders to vote AGAINST the proposal because there would be too much selling pressure.

Also was it tested on Goerli? I had a note on Goerli that could be used to claim AP, but now it says not ready for anonymity mining.

Add Torn as a new pool and I push this proposal.
For obvious legal reason before that I can’t paticipate just like many large holders…

1 Like

It was tested extensively both on Goerli and Mainnet fork. We tested full cycle of propose, vote, execute, migration; then tested new root updates, deposits, withdrawals, old and new note claims and swaps. It also had 2 audits. Testing was the reason it took that long. But of course there is always a small chance that we missed something.


The proposal is now live and available to vote on

currently at 11k/25k, need 14k more votes to pass.


So how much Gas do we will need to process all withdrawals after update ,do i calculate correct ,about 8.7 mil Gas?Or my calculation is wrong?Thx

If my calculations are correct we need 112,422,199.21875 gas to process everything.

12000 + 15000 / 256 * 1065929

At 120 GWEI per transaction that’s only 13.49 ETH which is a MASSIVE improvement from the previous 270 ETH required.


This is a reminder for everyone who hasn’t voted yet to do so as soon as possible.

We are currently 6,707 TORN short for this proposal to be executed with 1 day and 11 hours left to vote.

1 Like

What options do we have if defeated?
Do we vote on it again after days?

I locked some torn and voted. Now I got more torn but it doesn’t let me to lock more?

It should allow you to lock more, maybe it’s a bug. To update your vote count you’ll have to vote yes again after locking