Gas price claimed anonymity mining a victim but now everyone can claim AP

Tornado Cash
5 min readJun 7, 2021


In the last days of 2020, our community launched the Anonymity Mining program as part of the Tornado.Cash Governance Proposal. One of the main goals of the program is to increase the anonymity of the system by incentivizing a larger number and a longer stay of deposits in our anonymity sets. Today, we are delighted by the participation of our community, who have contributed to increase our liquidity by over 300% since the inception of the program.

Liquidity in the 1 ETH anonymity set over time (source)

In spite of all the excitement, soon after the launch, mining experienced a painful roadblock. The unexpectedly steep rise of gas prices in the network broke some of the assumptions considered in the design of our smart contracts. And while users have always been able to enter the mining program and accrue AP, for a period of time claiming rewards became awfully inconvenient. Let’s dive some more into the technical details and the clever solution that came to save the day.

The Merkle Root Update

The anonymity mining process is composed of four stages that involve user interaction with the network. As a refresher, the diagram below illustrates the process:

All four transactions are carried out by individual users as they manage their own notes. Yet, a fifth operation (big red dot) has to take place in the life cycle of AP-mining note: the Merkle root update.

The mining Merkle trees are data structures that register the block number in which deposits and withdrawals took place to allow calculating the longevity of a deposit (while preserving anonymity). Without that information the application can’t know the amount of AP rewards a given note accrued. In order to update their data, someone has to execute a contract call. This action can be carried out by anyone in the network, if they can afford it.

Under the mad gas fee hike in the beginning of the year, it soon became too expensive for the average crypto-Joe to altruistically update the data structures for everyone’s benefit. By the end of March, it cost roughly $16 in gas to register the deposit-withdrawal of a single note. With the backlog growing slowly to over 40 days, and more than 25,000 deposits and withdrawals pending, it would cost ~300 ETH to update the Merkle trees. Anonymity mining was stuck for a good reason.

Expensive operation = no execution = no AP claims

The workaround

The root update operation runs in a smart contract to guarantee it is calculated with trustless integrity, but running the update involves many computations, and therefore lots of gas. The operation could be offloaded to a user, but only if she was able to prove it’s correctness. How could we verify the correctness of a function output without actually doing the computation?

That’s right!

The proposal submitted by Poma implemented a solution with zk-SNARKs. With this new idea, the update function now takes fixed batches of 256 deposits-withdrawals. The update of the Merkle tree is offloaded to the function caller (still anyone), who then submits the new Merkle tree root together with a zero-knowledge proof to back it up. The efficiency gain? A modest reduction in gas usage by 13x!

After passing audits from ZeroPool and ABDK the proposal was submitted for governance approval. Votes in favor swiftly crossed the 25K TORN threshold in the following days. Finally, after the new contracts went live on March 30, the Team spent around 30 ETH to upload those thousands of pending notes and bring the system up to date. Ever since, the community has taken care, executing the root update every other day.

Click to Update Root

In fact, independently of gas use improvements, it is expected to see root updates regularly simply because it’s now easier to do so. The sweet UI update that went live on June 6 makes it exceptionally easy to run a root update with the click of a button, whereas previously, the possibility was reserved to people who eat code for breakfast.

To get the withdrawals tree status, go to the mining page and provide a note that has already been withdrawn. If it hasn’t been included in the latest root update, you’ll see a warning with a link that reads “Show mining note information”. Clicking that link will display the data you’re looking for.

Status of my recently withdrawn note.

From the UI, one may realize that (1) I’m not ready to claim my APs yet because my note forms part of the partially filled batch #112, (2) the previous batch is complete but its data hasn’t yet been included in the trees, and (3) I could update the trees and include batch #111 by clicking “Update tornado trees” myself!

One last bonus

Taking profit from all the smart contract overhauling, a worthwhile enhancement was introduced to one of the updated components: ERC20 anonymity pools are now capable of accumulating AP.

The parameters that define the AP accrual rate for each ERC20 pool were set upon the successful execution of Proposal #5. Details about the new mining rates are available in the proposal description.

The introduction of this feature is particularly good news for, in the case of new pools, providing a reward is a powerful tool to bootstrap their liquidity and ramp up anonymity. More on that soon, stay tuned.