1. Introduction
In August 2022, the US Treasury’s Office of Foreign Assets Control (OFAC) sanctioned Tornado Cash, adding 45 Ethereum addresses to the Specially Designated Nationals (SDN) List of sanctioned persons.
This document aims to help the reader understand what Tornado Cash is, how it works, and what, exactly, was sanctioned. But before we jump into Tornado Cash, let’s review a few key concepts around Ethereum, smart contracts, and decentralization.
2. Background: What is Ethereum, who are its users, what is a smart contract?
Ethereum is a cooperatively-run, global, transparent database. Through mutual effort, participants from all over the world maintain Ethereum’s public record of addresses, which reference both user accounts and smart contract applications. These records work together much like the user accounts and software of a modern desktop computer, except that Ethereum is:
- Cooperatively-run: Ethereum’s fundamental operation comes from the collective effort of its participants worldwide. No single party can make changes to how Ethereum works.
- Publicly-accessible: Anyone anywhere in the world can interact with Ethereum, its users, and its applications.
- Transparent: Anyone anywhere in the world can download and view all the information in Ethereum’s database.
Anyone can be a user of Ethereum. Creating an account is simple, and does not require a phone number, email, or physical address. Instead, users install an application called a “wallet,” which generates a unique identifier for that user called an “address” and a password-like number for authentication called a “private key.” Much like a person with multiple email addresses, Ethereum’s users can create and use as many addresses as they want. Unlike with email, however, Ethereum’s users are not “customers” in the traditional sense. They are participants in a global computing system running on open-source software, which functions without third-party oversight. It is also important to note that Ethereum addresses controlled by the same user are not necessarily publicly linked to one another; they are simply unique identifiers that belong to the user who has the corresponding private key.
By sharing an address, users are able to receive tokens (e.g. crypto-assets like Ether) from anyone, anywhere in the world. Unlike a traditional payment service, sending and receiving tokens on Ethereum does not require an intermediary. Instead, the sender broadcasts their intent to transfer tokens, signs their message mathematically using the corresponding private key, and Ethereum’s network collectively updates the global records of the sender and receiver addresses with the new balances. At no point in this process does a third party take custody of the tokens being transferred.
In addition to sending and receiving tokens, user accounts can interact with smart contracts, which are applications that extend the functionality of Ethereum. When developers program smart contracts, they decide what operations the smart contract will support and what rules those operations must follow. These rules and operations are written using code that is broadcast to Ethereum’s network, just like the token transactions described above. Once a smart contract’s code is added to Ethereum’s records, it receives a unique address and can be interacted with by any user to automatically carry out the rules and operations it supports.
In essence, smart contracts are open-source applications that anyone can deploy to Ethereum. Just like the rest of Ethereum, smart contracts can be viewed and used by anyone, anywhere, and without relying on an intermediary.
Both people and smart contracts can have Ethereum addresses; the key difference is that when a person has an address they have the private key that controls any tokens sent to that address. That person will ultimately decide if and when any transactions are made with those tokens. When a smart contract has an address, the rules and operations written in the smart contract code control the tokens. They could be simple rules (e.g. automatically send the tokens back), or more complicated rules. There could be rules that include human operations and human decisions (e.g. send the tokens back if 3 out of 5 of these human-controlled addresses send a signed message saying they agree). The rules could also, however, be fully and permanently outside of any human being’s control. In that case, so too are any tokens sent to that address until and unless the contract sends them back to some human according to the rules.
By default, smart contracts are immutable, which means they cannot be removed or updated by anyone once deployed. It is possible for the smart contract’s developers to include (in the contract code) the ability to update functionality as a supported operation (e.g. this human-controlled address can rewrite the contract in the future). However, such an operation must be included in the smart contract’s code prior to the smart contract’s deployment (i.e. publication to the Ethereum network). Without the inclusion of updatability prior to deployment, a smart contract cannot be modified by anyone. It is also possible to revoke the ability to update functionality by transferring the permissions for this ability to a placeholder Ethereum address for which there is no corresponding private key. This placeholder is known as “the zero address.” Once the ability to update a contract has been revoked, it cannot be reclaimed and the contract can no longer be changed.
Unlike traditional finance, Ethereum’s records are completely transparent: anyone can download and view the balances and transaction history of its user accounts. Although user addresses are pseudonymous, if a real-world identity is linked to a user address, it becomes possible to trace that user’s complete financial history. Ethereum’s transparency is important for auditability (e.g. verifying that updates to records are valid). However, this transparency also makes it difficult for users to protect their personal information. By default, a record of a casual transaction today (e.g. paying for Wi-Fi at the airport) leads directly to records of earlier transactions, which may include any intimate, revealing, or sensitive transactions made by the same user long ago.
Among the many different applications smart contracts may support, they may also provide an avenue for users to regain the privacy they expect when interacting with financial systems. Central to that privacy is the use of smart contracts to break the public chain of records that would otherwise link your transaction today to every transaction you’ve ever made in the past. Enter Tornado Cash.
3. Tornado Cash: A smart contract application
Tornado Cash is an open source software project that provides privacy protection for Ethereum’s users. Like many such projects, the name does not refer to a legal entity, but to several open source software libraries that have been developed over many years by a diverse group of contributors. These contributors have published and made Tornado Cash available for general use as a collection of smart contracts on the Ethereum blockchain.
As we will explain, some of these smart contracts have been sanctioned by OFAC. The core of Tornado Cash’s privacy tools, however, make up a subset of the addresses sanctioned by OFAC: the Tornado Cash “pools.” Each Tornado Cash pool is a smart contract deployed to Ethereum. Like other smart contracts, the pool contracts extend the functionality of Ethereum with specific operations that can be executed by any user of Ethereum according to the rules defined in the Tornado Cash contracts’ code.
This section will describe how these pools work. In particular, it will describe the key innovation that enables these pools to function autonomously: an application of privacy-preserving mathematics known as “zero-knowledge cryptography.”
Subsequent sections will describe the specific addresses sanctioned by OFAC, and what they do. An appendix at the end will list all of the sanctioned contracts and their salient features.
Tornado Cash Core Contracts: Pools
Tornado Cash pools are smart contracts that enable users to transact privately on Ethereum. When prompted by a user, pools will automatically carry out one of two supported operations: “deposit” or “withdraw.” Together, these operations allow a user to deposit tokens from one address and later withdraw those same tokens to a different address. Crucially, even though these deposit and withdrawal events occur publicly on Ethereum’s transparent ledger, any public link between the deposit and withdrawal addresses is severed. The user is able to withdraw and use their funds without fear of exposing their entire financial history to third parties.
In support of the deposit and withdrawal operations, these smart contracts encode strict rules that further define its functionality. These rules are automatically applied to the deposit and withdrawal operations to maintain a very important property shared by all Tornado Cash pools: users can only withdraw the specific tokens they originally deposited.
This property is enforced automatically for all the pool’s operations, and ensures that Tornado Cash pools are entirely non-custodial. That is, a user who deposits and later withdraws tokens maintains total ownership and control over their tokens, even as they pass through the pool. At no point is the user required to relinquish control of their tokens to anyone.
A key principle of Tornado Cash pools is that a user’s privacy is derived in large part from the simultaneous usage of the pool by many other users. If the pool had only a single user, it wouldn’t matter that the link between the user’s deposit and withdrawal addresses was severed: simple inference would make it obvious where the withdrawn tokens came from. Instead, pools are used by many users simultaneously. Think of it like a bank’s safe deposit box room. Anyone can go and store valuables in a locked box in that room, and, assuming the locks are good, only the person with the key can ever get those valuables back. Security aside, however, this may or may not be privacy enhancing. If only one person is ever seen going into and out of the room, then we know any valuables in that room are theirs. If, on the other hand, many people frequently go into and out of the room, then we have no way of knowing who controls which valuables in which boxes. By guaranteeing the property that users can only withdraw tokens they originally deposited, many users can simultaneously use these pools with the assurance that no-one else will receive their tokens.
Traditionally, these assurances would be provided by a custodial service: a bank in the safe deposit box example, or a group of people running a “mixing service” in other common cryptocurrency arrangements. Mixing services like Blender.io directly accept tokens from their clients, aggregate and mix them, and then return the funds to their clients (often taking some fee in the process). During the intermediate aggregation and mixing stage, the funds in question are completely in the control of the operators of the mixing service and are commingled. At the final stage of the mixing process, a user would receive funds sourced directly from the myriad other users that also used the service.
In contrast, Tornado Cash pools have no custodial operator, and users only ever withdraw the tokens they originally deposited (rather than a mixture of tokens from the other users of the service). This is made possible because of important properties of the deposit and withdrawal operations, which are automatically carried out through the use of a privacy-preserving branch of mathematics called “zero-knowledge cryptography.” This zero-knowledge cryptography is included in Tornado Cash’s smart contract code, and forms the foundation on which the deposit and withdrawal operations function.
Zero-Knowledge Proofs
To recall an earlier point, Ethereum is transparent: anyone can view the transaction history and balance of any user account. Likewise, anyone can view the interaction history, balance, and code of a smart contract application. If a user prompts a smart contract to perform an operation, this interaction becomes a fact that is forever recorded in Ethereum’s public records and can be recalled and inspected by anyone. So how is it that a user can deposit into a Tornado Cash pool and later withdraw to a different address without creating an obvious link to anyone observing Ethereum’s public records?
The answer lies in zero-knowledge proofs. A zero-knowledge proof is a cryptographic method by which one party (the “prover”) can prove to another party (the “verifier”) that a given statement is true without the prover conveying any additional information apart from the fact that the statement is indeed true.
In the case of Tornado Cash, the “prover” is the user withdrawing tokens from the pool, while the “verifier” is one of the Tornado Cash pool contracts. When a user prompts the pool smart contract to withdraw their tokens, the user must supply the prompt with a zero-knowledge proof. The pool’s code automatically checks the input proof, only processing a withdrawal if the proof is found to be valid. Exactly what statement is being proven by the user and how they create that proof is slightly more complicated, and requires a bit more detail on the deposit process.
Pool Deposit Process
When a user wants to deposit tokens, they first generate a “deposit note” (a long sequence of digits known only to the user). This is done privately on the user’s own computer, and is never shared publicly. Next, the user prompts the Tornado Cash pool contract to process the deposit. Along with this prompt, the user supplies a hash (or encoded form) of their deposit note and the tokens for deposit. The pool smart contract automatically records the encoded note as a new entry in a public list of other users’ encoded notes. At this point, the depositing user has completed the first part of the process, and retains the deposit note, which acts as a receipt to withdraw the tokens later.
Pool Withdrawal Process
When a user is ready to withdraw their tokens, they first split their deposit note in half. One side acts like a “secret,” and the other acts like a “lock.” After that, the user prompts the Tornado Cash smart contract to withdraw. Along with the prompt, the user supplies:
- A hash (or encoded form) of the “lock”
- A zero-knowledge proof, generated using the “secret” and the “lock”
The pool smart contract uses these inputs to automatically verify – that is, prove – the following:
- That the zero-knowledge proof was generated using the “secret.” It is the exact same “secret” that corresponds to one of the existing encoded notes in the pool’s public list of encoded notes (i.e. proving that the tokens being withdrawn were previously deposited by someone).
- That the same proof also corresponds to the encoded form of the “lock” supplied with the proof (i.e. proving that the person who is withdrawing them must be the same person who deposited them).
- That the submitted “lock” has not been submitted previously (i.e. the deposit in question has not already been withdrawn).
Assuming the proof is verified, the pool smart contract automatically:
- Sends the user their tokens.
- Records the encoded “lock” in a public list of other users’ encoded locks, ensuring the same tokens cannot be withdrawn again.
Crucially, the above operations are carried out while the following is never revealed: which specific encoded note the proof corresponds to (i.e. who, among all of Tornado Cash’s depositors, is now withdrawing).
Can Tornado Cash be removed or updated? If so, by whom?
As stated previously, for most readers, Tornado Cash is synonymous with a core subset of the Tornado Cash smart contracts: the Tornado Cash pools. The vast majority of these contracts are immutable. That is, they have no ability to be updated or removed by anyone. A complete list of sanctioned, immutable Tornado Cash pools can be found in Appendix A.
Note that many of these pools had, at one point, an “operator” role. The operator role was originally held by 0xDD4c…3384, aka Gitcoin Grants: Tornado.cash, another sanctioned address. This role afforded its holder two permissions:
- updateVerifier: Used to update the “verifier” used by the smart contract. In essence, this permission could be used to modify how the contract processed zero-knowledge proofs.
- changeOperator: Used to transfer the “operator” permission to another address, or revoke the “operator” permission entirely by transferring it to the zero address.
In May 2020, the updateVerifier permission was used in conjunction with the changeOperator permission as a final update to these Tornado Cash pools. This updated all pools’ zero-knowledge proof processors to their final version, which incorporated the contributions of over 1,100 community participants. Additionally, this update revoked the “operator” permission by using changeOperator to transfer the permission to the zero address. In effect, the update performed in May 2020 cemented the community’s preferences, and ensured no further changes could be made. Details on this process can be found here.
A handful of SDN-listed pools still have an “operator” permission. Of these, two belong to very old, now-unused versions of Tornado Cash. The remaining pools either have newer, immutable versions, or were used so little that they were likely overlooked during the May 2020 final update. Most of these remaining eight pools have never been used, and the ones that were used were only used once or twice within the past three years. A complete list of sanctioned, outdated Tornado Cash pools that retain the operator permission can be found in Appendix C.
Tornado Cash Auxiliary Contracts & Controls
Governance and TORN Token
The pool smart contracts represent the core of the Tornado Cash application, which remains immutable and uncontrolled by any party. However, OFAC’s sanctions also include auxiliary smart contracts that provide coordination mechanisms for the continued maintenance and use of Tornado Cash by its community. Several of these contracts are unused today, belonging to older versions of Tornado Cash. A complete list of OFAC-sanctioned smart contracts that relate to Tornado Cash’s community maintenance can be found in Appendix B.
The SDN List includes two primary contracts still in use today:
- Tornado Cash (Router): References a registry of up-to-date Tornado Cash pools, consistent with the current version of Tornado Cash. Users may optionally choose to interact with Tornado Cash pools via the Router contract, which ensures their deposit and withdrawal operations are processed using up-to-date code.
- Tornado Cash (Relayer Registry): References a registry of operators providing relay-assisted withdrawal services to users of Tornado Cash. Users may optionally elect to process their withdrawals via a relayer, which may afford additional privacy.
Unlike the pool smart contracts, the Router and Relayer Registry support some updatable functionality. However, the permission to update these contracts is held not by a human, but by another smart contract. This smart contract, also known as Tornado Cash: Governance, defines the rules and operations that determine how the Router and Relayer Registry may be updated.
In short, Tornado Cash: Governance provides that updates to these smart contracts are processed at the behest of the community, which holds public votes to determine what updates should occur, and when. Any holder of TORN tokens may participate in these votes. TORN is an ERC20-token built on Ethereum that is expressly used by the community to vote on governance proposals. Any user of Ethereum may purchase TORN tokens and participate in this process.
Note that while this process allows the wider Ethereum community to participate in the development and maintenance of Tornado Cash, no part of this process allows for the update or removal of Tornado Cash pool smart contracts. Additionally, participating in the Tornado Cash: Governance process is entirely optional: users can use Tornado Cash pools without any involvement, oversight, or interaction with the Tornado Cash: Governance process.
Although Tornado Cash: Governance and the TORN token contract are parts of the Tornado Cash software ecosystem, neither was added to OFAC’s SDN List.
Relayers
As previously mentioned, “relayers” are independent operators that provide an optional service for Tornado Cash users.
By default, when users prompt the Tornado Cash pool contracts for withdrawal, the withdrawal account needs to already have Ether in order to pay the Ethereum network to process the smart contract’s operations. However, sending Ether to the withdrawal account prior to withdrawal might create a link between the user’s deposit and withdrawal accounts.
Relayers allow users to process withdrawals without needing to pre-fund their withdrawal accounts, which helps users maintain privacy when withdrawing.
Users select a relayer from a public Relayer Registry, another sanctioned Tornado Cash smart contract. The user then uses their withdrawal account to sign a transaction authorizing the relayer-assisted withdrawal. The user sends this transaction to their selected relayer, who processes the withdrawal on their behalf, earning a fee in the process. Note that even though they process withdrawals on behalf of users, relayers never have custody over users’ tokens; the smart contract ensures that withdrawn tokens are only ever sent to the user’s withdrawal account.
OFAC has not specifically added any relayer addresses to the SDN List, but it has added the smart contract that contains a registry of relayers to the list.
Compliance Tool
Tornado Cash was built to enable Ethereum’s users to reclaim their privacy. Rather than exposing their complete financial history, Tornado Cash gives users control over their personal information: both what is shared and with whom it is shared. However, maintaining privacy and preserving control over one’s personal information does not need to come at the expense of non-compliance with legal obligations.
To this end, the developers of Tornado Cash created the Tornado Cash Compliance Tool. Users supply the tool with the original “deposit note” generated during the pool deposit process to create a PDF report that provides proof of the original source of the tokens. Although the public link between a user’s deposit and withdrawal addresses was severed by the Tornado Cash pool contracts, the Compliance Tool allows users to selectively “undo” this severance to provide traceability to third parties.
The Compliance Tool is not a smart contract. However, just like the other software described in this article, the Compliance Tool is also not a service provided by Tornado Cash developers; it is an open-source tool that can be used by anyone.
Other Tornado Cash Smart Contracts and Addresses
Finally, two of the sanctioned addresses are donation addresses. These addresses were used in the past to raise money in support of the development of the privacy software that powers Tornado Cash. While some person or entity does control tokens sent to these addresses, those tokens are not, to our knowledge, being mixed or re-routed for privacy purposes. They are merely a gift from the sender in support of software development efforts performed by the recipient. A complete list of donation addresses sanctioned by OFAC can be found in Appendix D.
In general, while a minority of the contracts listed by OFAC do retain elements of human control, none of them are critical to the basic operation of Tornado Cash’s privacy tools, and none of them take control of user tokens. The core privacy tools – the pool contracts – are outside of any individual or group’s control; they are simply widely distributed computer code that is executed by the Ethereum network according to strict and unalterable rules.
Summary
In summary:
- The Tornado Cash smart contracts allow users to deposit and later withdraw their tokens to another address.
- Even though anyone can observe users deposit or withdraw tokens, they are not able to determine which withdrawals correspond to which deposits.
- These operations are defined as smart contract code and are carried out automatically without any intermediary or third party.
- Users retain control of their funds the whole time, and are only able to withdraw the tokens they originally deposit.
- No one controls the operation of these Tornado Cash smart contracts and no one has the ability to change their operation in the future.
- Some OFAC-identified addresses retain a level of human control. However, these addresses are not core to the operation of the privacy tools found at the immutable addresses and they can not exercise control over any user tokens.
Update December 16, 2022
On November 8th, 2022, OFAC simultaneously delisted and redesignated Tornado Cash. As a result, several new alphanumeric addresses have appeared on the SDN List, and a single address was removed for reasons unknown.
None of the immutable Tornado cash pool addresses from the original designation were removed from the SDN List. The redesignation added 53 new addresses. Of these, nine addresses are also immutable and related to the functionality of Tornado Cash as a privacy tool. These addresses are characterized in detail in Appendix E, below.
Another seven addresses do not point to any software tools or assets on the Ethereum blockchain. OFAC’s designation clearly specifies that the listed addresses are meant to refer to the Ethereum blockchain because each listing is prefaced by “Digital Currency Address – ETH.” And yet there are no assets or code at those addresses on the Ethereum blockchain. Other blockchain networks, among them Arbitrum, Optimism, BSC, Gnosis Chain, Polygon, and Avalanche, use the same addressing scheme as the Ethereum protocol and do contain immutable Tornado Cash smart contract tools at some of those addresses. It appears that the designation of these seven addresses was made carelessly because, as currently described in the SDN List, they do not accurately point to blockchain addresses that contain any software tools or assets whatsoever. We can postulate, however, that these seven designations were meant to point to addresses on these alternative blockchains despite facially directing SDN List readers to empty addresses on Ethereum. These addresses are characterized in Appendix F, below.
Of the remaining 37 new addresses that we have not yet discussed, 19 are likely intended to refer to Ethereum “testnet” addresses. As with the seven addresses described above, these addresses are empty on the Ethereum blockchain, containing no software tools or assets, however it is likely that OFAC mislabeled them and intended to describe identical addresses on the Goreli Ethereum testnet blockchain. A testnet is a blockchain network environment where cryptocurrency software developers can test their software for bugs without suffering real economic consequences. Unlike cryptocurrencies like ETH, “testnet tokens” (which can be sent and received to and from testnet contracts) are free to obtain and have no resale value. While OFAC’s stated goal is to use its sanctions powers to block US persons from transacting with sanctioned persons or their property, these testnet contracts are incapable of facilitating any economic transactions sanctioned or not. If OFAC intended to sanction these testnet addresses then they are placing a ban on US persons engaging in security research and software testing rather than a ban on US persons making transactions with sanctioned persons or their property. OFAC has not explained specifically why it has added these addresses to the SDN List or whether they intended to identify the empty addresses on Ethereum or these software testing tools on the Goreli Ethereum testnet. These addresses are characterized in Appendix G, below.
The remaining 18 new addresses are further auxiliary contracts on Ethereum that are not essential to the operation of the Tornado Cash pools by persons seeking privacy on Ethereum. These addresses are characterized in Appendix H, below.
Appendix: Categorization of sanctioned addresses
These appendices list all addresses sanctioned by OFAC. They have been categorized according to the function they provide in the context of the Tornado Cash application.
Included with each address listed is the following information:
- Name: A name by which the address can be referenced. Note that these names do not come from the Tornado Cash developers, they come from Etherscan: a third party service whose website can be used to display information on the current state of Ethereum. The names listed are intended to be a handy reference, and do not necessarily reflect the views of the community or the Tornado Cash developers.
- Description: A short description of what each address refers to.
A: List of immutable Tornado Cash pools
- 0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc
- Name: Tornado.Cash: 0.1 ETH
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 0.1 ETH.
- Operator: Revoked (operator set to zero address)
- 0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936
- Name: Tornado.Cash: 1 ETH
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 1 ETH.
- Operator: Revoked (operator set to zero address)
- 0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF
- Name: Tornado.Cash: 10 ETH
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 10 ETH.
- Operator: Revoked (operator set to zero address)
- 0xA160cdAB225685dA1d56aa342Ad8841c3b53f291
- Name: Tornado.Cash: 100 ETH
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 100 ETH.
- Operator: Revoked (operator set to zero address)
- 0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3
- Name: Tornado.Cash: 100 DAI
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 100 DAI.
- Operator: Revoked (operator set to zero address)
- 0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144
- Name: Tornado.Cash: 1000 DAI
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 1000 DAI.
- Operator: Revoked (operator set to zero address)
- 0x07687e702b410Fa43f4cB4Af7FA097918ffD2730
- Name: Tornado.Cash: 10000 DAI 2
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 10000 DAI.
- Operator: None (functionality not included)
- 0x23773E65ed146A459791799d01336DB287f25334
- Name: Tornado.Cash: 100000 DAI
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 100000 DAI.
- Operator: None (functionality not included)
- 0x22aaA7720ddd5388A3c0A3333430953C68f1849b
- Name: Tornado.Cash: 5000 cDAI
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 5000 cDAI.
- Operator: Revoked (operator set to zero address)
- 0xBA214C1c1928a32Bffe790263E38B4Af9bFCD659
- Name: Tornado.Cash: 50000 cDAI
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 50000 cDAI.
- Operator: Revoked (operator set to zero address)
- 0x03893a7c7463AE47D46bc7f091665f1893656003
- Name: Tornado.Cash: 50000 cDAI 2
- Description: A newer version of the 50000 cDAI Tornado Cash pool, which allows deposits and withdrawals in increments of 50000 cDAI.
- Operator: None (functionality not included)
- 0x2717c5e28cf931547B621a5dddb772Ab6A35B701
- Name: Tornado.Cash: 500000 cDAI 2
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 500000 cDAI.
- Operator: None (functionality not included)
- 0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af
- Name: Tornado.Cash: 5000000 cDAI
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 5000000 cDAI.
- Operator: None (functionality not included)
- 0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D
- Name: Tornado.Cash: 100 USDC
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 100 USDC.
- Operator: Revoked (operator set to zero address)
- 0xd96f2B1c14Db8458374d9Aca76E26c3D18364307
- Name: Tornado.Cash: 1000 USDC
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 1000 USDC.
- Operator: Revoked (operator set to zero address)
- 0x169AD27A470D064DEDE56a2D3ff727986b15D52B
- Name: Tornado.Cash: 100 USDT
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 100 USDT.
- Operator: Revoked (operator set to zero address)
- 0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f
- Name: Tornado.Cash: 1000 USDT
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 1000 USDT.
- Operator: Revoked (operator set to zero address)
- 0x178169B423a011fff22B9e3F3abeA13414dDD0F1
- Name: Tornado.Cash: 0.1 WBTC
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 0.1 WBTC.
- Operator: None (functionality not included)
- 0x610B717796ad172B316836AC95a2ffad065CeaB4
- Name: Tornado.Cash: 1 WBTC
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 1 WBTC.
- Operator: None (functionality not included)
- 0xbB93e510BbCD0B7beb5A853875f9eC60275CF498
- Name: Tornado.Cash: 10 WBTC
- Description: A Tornado Cash pool that allows deposits and withdrawals in increments of 10 WBTC.
- Operator: None (functionality not included)
B: List of community-governed contracts
- 0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b
- Name: Tornado.Cash: Router
- Description: A contract that maintains a list of Tornado Cash pools, which can be used by users to route deposits and withdrawals to the correct Tornado Cash pool.
- Still in use: Yes.
- Governance Controls: No significant controls. The community may choose to withdraw any tokens sent to the Router, as the Router is not an intended recipient of tokens.
- 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2
- Name: Tornado.Cash: Relayer Registry
- Description: This contract allows anyone to register as a Tornado Cash relayer. Relayers provide an optional service for users to make gasless withdrawals.
- Still in use: Yes.
- Governance Controls: Updatable pending a community vote.
- 0x527653eA119F3E6a1F5BD18fbF4714081D7B31ce
- Name: Tornado.Cash: Trees
- Description: This contract holds a merkle tree (a kind of list) of all Tornado Cash deposit and withdrawal events.
- Still in use: No, this is associated with an older version of Tornado Cash.
- Governance Controls: Updatable pending a community vote.
- 0xCa0840578f57fE71599D29375e16783424023357
- Name: Tornado.Cash: L1 Helper
- Description: Allows users to designate deposited Ether to be bridged to a Tornado Cash pool located on the Gnosis Chain blockchain. This smart contract is not a major component of the Tornado Cash application.
- Still in use: Yes.
- Governance Controls: No significant controls. The community may choose to withdraw tokens sent to this contract, as it is not an intended recipient.
- 0x722122dF12D4e14e13Ac3b6895a86e84145b6967
- Name: Tornado.Cash: Proxy
- Description: An old version of Tornado.Cash: Router.
- Still in use: No, this is associated with an older version of Tornado Cash.
- Governance Controls: No significant controls following deprecation of this contract in Feb 2022. The community may choose to withdraw tokens sent to this contract, as it is not an intended recipient.
- 0x905b63Fff465B9fFBF41DeA908CEb12478ec7601
- Name: Tornado.Cash: Old Proxy
- Description: An old version of Tornado.Cash: Router.
- Still in use: No, this is associated with an older version of Tornado Cash.
- Governance Controls: No significant controls. The community may choose to withdraw tokens sent to this contract, as it is not an intended recipient.
C: List of outdated contracts that retain an operator permission
- 0x94A1B5CdB22c43faab4AbEb5c74999895464Ddaf
- Name: Tornado.Cash: Mixer 1
- Description: An old version of the Tornado Cash pools, unused today.
- Operator: 0x8589427373D6D84E98730D7795D8f6f8731FDA16, aka Tornado Cash: Donate
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to “enable” and “disable” the use of the contract. As of Oct 2019, the operator has “disabled” use of the contract.
- 0xb541fc07bC7619fD4062A54d96268525cBC6FfEF
- Name: Tornado.Cash: Mixer 2
- Description: An old version of the Tornado Cash pools, unused today.
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls: Updatable by the operator.
- 0xF60dD140cFf0706bAE9Cd734Ac3ae76AD9eBC32A
- Name: Tornado.Cash: 10000 DAI
- Description: Old/unused Tornado Cash pool that allows deposits and withdrawals in increments of 10000 DAI.
- Last used: Feb, 2020
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0xb1C8094B234DcE6e03f10a5b673c1d8C69739A00
- Name: Tornado.Cash: 500000 cDAI
- Description: Unused Tornado Cash pool that allows deposits and withdrawals in increments of 500000 cDAI.
- Last used: Never used
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0xD691F27f38B395864Ea86CfC7253969B409c362d
- Name: Tornado.Cash: 10000 USDC
- Description: Unused Tornado Cash pool that allows deposits and withdrawals in increments of 10000 USDC.
- Last used: Never used
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0xaEaaC358560e11f52454D997AAFF2c5731B6f8a6
- Name: Tornado.Cash: 5000 cUSDC
- Description: Old/unused Tornado Cash pool that allows deposits and withdrawals in increments of 5000 cUSDC.
- Last used: May, 2020
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0x1356c899D8C9467C7f71C195612F8A395aBf2f0a
- Name: Tornado.Cash: 50000 cUSDC
- Description: Unused Tornado Cash pool that allows deposits and withdrawals in increments of 50000 cUSDC.
- Last used: Never used
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0xA60C772958a3eD56c1F15dD055bA37AC8e523a0D
- Name: Tornado.Cash: 500000 cUSDC
- Description: Unused Tornado Cash pool that allows deposits and withdrawals in increments of 500000 cUSDC.
- Last used: Never used
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0xF67721A2D8F736E75a49FdD7FAd2e31D8676542a
- Name: Tornado.Cash: 10000 USDT
- Description: Old/unused Tornado Cash pool that allows deposits and withdrawals in increments of 10000 USDT.
- Last used: May, 2020
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
- 0x9AD122c22B14202B4490eDAf288FDb3C7cb3ff5E
- Name: Tornado.Cash: 100000 USDT
- Description: Unused Tornado Cash pool that allows deposits and withdrawals in increments of 100000 USDT.
- Last used: Never used
- Operator: 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384, aka Gitcoin Grants: Tornado.cash
- Operator Controls:
- This contract cannot be removed by anyone.
- The sole permission afforded to the Operator is the permission to update the “verifier” used by the contract. In essence, the Operator may change how this contract processes zero-knowledge proofs.
D: List of donation addresses
- 0xDD4c48C0B24039969fC16D1cdF626eaB821d3384
- Name: Gitcoin Grants: Tornado.cash
- Description: A smart contract used to receive software development grants from the Gitcoin crowdfunding platform.
- 0x8589427373D6D84E98730D7795D8f6f8731FDA16
- Name: Tornado.Cash: Donate
- Description: A user address used to receive donations for software development. This address is not a smart contract.
E: Nov-8th Redesignation — New Immutable Contract Addresses on Ethereum
- 0xCEe71753C9820f063b38FDbE4cFDAf1d3D928A80
- Name: Deployer Contract
- Description: A simple factory smart contract used to deploy other contract components of the Tornado Cash ecosystem.
- Operator: None (functionality not included)
- 0x756C4628E57F7e7f8a459EC2752968360Cf4D1AA
- Name: Echoer
- Description: A simple smart contract that emits an event containing data passed to it by the contract caller, hence the “echo”.
- Operator: None (functionality not included)
- 0x94C92F096437ab9958fC0A37F09348f30389Ae79
- Description: A set of old smart contracts that contain a utility library for hashing functionality that were deployed on both Ethereum mainnet and Gnosis Chain. Unused today.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: The source code for these smart contracts is not verified so the stated functionality is a best-guess interpretation.
- 0xD82ed8786D7c69DC7e052F7A542AB047971E73d2
- Name: Tornado.Cash: Poseidon 3
- Description: An old smart contract containing a utility library for hashing functionality. Unused today.
- Operator: None (functionality not included)
- Note: The source code for these smart contracts is not verified so the stated functionality is a best-guess interpretation.
- 0x88fd245fEdeC4A936e700f9173454D1931B4C307
- Name: Tornado.Cash: Reward Verifier
- Description: A smart contract used to verify proofs for rewards distribution in the anonymity mining program.
- Operator: None (functionality not included)
- 0x653477c392c16b0765603074f157314Cc4f40c32
- Name: Tornado.Cash: Tree Update Verifier
- Description: A smart contract used to verify proofs of tree updates for the anonymity mining program.
- Operator: None (functionality not included)
- 0x743494b60097A2230018079c02fe21a7B687EAA5
- Name: Verifier 16
- Description: A smart contract used to verify proofs for the Tornado Cash Nova pools on Gnosis Chain.
- Operator: None (functionality not included)
- 0xDF3A408c53E5078af6e8fb2A85088D46Ee09A61b
- Name: Verifier 2
- Description: A smart contract used to verify proofs for the Tornado Cash Nova pools on Gnosis Chain.
- Operator: None (functionality not included)
- 0x09193888b3f38C82dEdfda55259A82C0E7De875E
- Name: Tornado.Cash: Withdraw Verifier
- Description: A smart contract used to verify proofs for withdrawals in the anonymity mining program.
- Operator: None (functionality not included)
F: Nov-8th Redesignation — New Addresses that are Empty on Ethereum but Contain Immutable Contracts on Other Chains
- 0xd47438c816c9e7f2e2888e060936a499af9582b3
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 1 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0x84443CFd09A48AF6eF360C6976C5392aC5023a1F
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 0.1 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0x330bdFADE01eE9bF63C209Ee33102DD334618e0a
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 10 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0xaf4c0B70B2Ea9FB7487C7CbB37aDa259579fe040
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 10,000 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 100 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0xa5C2254e4253490C54cef0a4347fddb8f75A4998
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 100,000 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0xdf231d99Ff8b6c6CBF4E9B9a945CBAcEF9339178
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 1,000 for a specified asset on multiple blockchain networks that each use the same contract address.
- Deployed Instances:
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
- 0xaf8d1839c3c67cf571aa74B5c12398d4901147B3
- Description: A set of Tornado Cash pools that allow deposits and withdrawals in increments of 500 for a specified asset on multiple blockchain networks, although this contract has only been deployed on the Avalanche network.
- Deployed Instances: Avalanche: 500 AVAX
- Operator: None (functionality not included)
- Note: OFAC has specified that the address listed was a “Digital Currency Address – ETH.” However, there is no smart contract on the Ethereum blockchain at this address. They may have intended to sanction these addresses on other networks where Tornado Cash contract code does exist, but this is a best-guess interpretation.
G: Nov-8th Redesignation — New Addresses that are empty on Ethereum mainnet but contain non-immutable contracts on the Goerli Ethereum testnet
As with the addresses described in Appendix F, these addresses are empty on the Ethereum blockchain and contain no smart contract code. However, it is possible that OFAC intended to identify the same addresses as they exist on the Goerli testnet. These smart contracts are deployed on the Goerli testnet and are used for testing Tornado Cash functionality. These smart contracts do not use any real assets and therefore cannot be used for money laundering or other criminal purposes.
- 0x6Bf694a291DF3FeC1f7e69701E3ab6c592435Ae7
- Name: 0.1 ETH Pool
- 0x242654336ca2205714071898f67E254EB49ACdCe
- 0.1 WBTC Pool
- 0x3aac1cC67c2ec5Db4eA850957b967Ba153aD6279
- Name: 1 ETH Pool
- 0x776198CCF446DFa168347089d7338879273172cF
- Name: 1 WBTC Pool
- 0xCC84179FFD19A1627E79F8648d09e095252Bc418
- Name: 1,000 DAI Pool
- 0x723B78e67497E85279CB204544566F4dC5d2acA0
- Name: 10 ETH Pool
- 0xeDC5d01286f99A066559F60a585406f3878a033e
- Name: 10 WBTC Pool
- 0xD5d6f8D9e784d0e26222ad3834500801a68D027D
- Name: 10,000 DAI Pool
- 0x76D85B4C0Fc497EeCc38902397aC608000A06607
- Name: 100 DAI Pool
- 0x0E3A09dDA6B20aFbB34aC7cD4A6881493f3E7bf7
- Name: 100 ETH Pool
- 0x05E0b5B40B7b66098C2161A5EE11C5740A3A7C45
- Name: 100 USDC Deposit
- 0x538Ab61E8A9fc1b2f93b3dd9011d662d89bE6FE6
- Name: 100 USDT Pool
- 0x407CcEeaA7c95d2FE2250Bf9F2c105aA7AAFB512
- Name: 100,000 DAI Pool
- 0x23173fE8b96A4Ad8d2E17fB83EA5dcccdCa1Ae52
- Name: 1000 USDC Pool
- 0x94Be88213a387E992Dd87DE56950a9aef34b9448
- Name: 1000 USDT Pool
- 0x57b2B8c82F065de8Ef5573f9730fC1449B403C9f
- Name: 5,000,000 cDAI Pool
- 0x8281Aa6795aDE17C8973e1aedcA380258Bc124F9
- Name: 500,000 cDAI Pool
- 0x833481186f16Cece3f1Eeea1a694c42034c3a0dB
- Name: 5000 cDAI Pool
- 0xd8D7DE3349ccaA0Fde6298fe6D7b7d0d34586193
- Name: 50,000 cDAI
H: Nov-8th Redesignation — New Addresses that are non-immutable and governance-related or ancillary
The following are smart contracts that service some governance or ancillary functionality to the Tornado Cash ecosystem such as managing Relayer registries, governance or providing libraries for hashing functionality. These contracts are not critical to the operation of Tornado Cash deposit pools and may be partially controlled and upgradeable by privileged accounts.
- 0xffbac21a641dcfe4552920138d90f3638b3c9fba
- Name: Tornado.Cash: Governance Impl
- 0x3efa30704d2b8bbac821307230376556cf8cc39e
- Name: Tornado.Cash: vTORN Token
- 0x179f48c78f57a3a78f0608cc9197b8972921d1d2
- Tornado.Cash: Governance Vesting
- 0xb04E030140b30C27bcdfaafFFA98C57d80eDa7B4
- Name: Tornado.Cash: Community Fund
- 0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7
- Name: Tornado.Cash: Fee Manager (Proxy)
- 0xf4B067dD14e95Bab89Be928c07Cb22E3c94E0DAA
- Name: Tornado.Cash: Fee Manager (Implementation)
- 0xB20c66C4DE72433F3cE747b58B86830c459CA911
- Name: Tornado.Cash: Instance Registry (Proxy)
- 0x2FC93484614a34f26F7970CBB94615bA109BB4bf
- Name: Tornado.Cash: Governance Staking
- 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce
- Name: Tornado.Cash: Governance (Proxy)
- 0xD692Fd2D0b2Fbd2e52CFa5B5b9424bC981C30696
- Name: Tornado Cash Nova: Pool Contract (Proxy)
- Deployed on Gnosis Chain
- 0x2f50508a8a3d323b91336fa3ea6ae50e55f32185
- Name: Tornado.Cash: Governance Vault
- 0x746aebc06d2ae31b71ac51429a19d54e797878e9
- Name: Tornado.Cash: Mining v2
- 0x01e2919679362dFBC9ee1644Ba9C6da6D6245BB1
- Name: Relayer Registry
- 0x5cab7692D4E94096462119ab7bF57319726Eed2A
- Name: Tornado.Cash: Reward Swap
- 0x77777feddddffc19ff86db637967013e6c6a116c
- Name: Tornado.Cash: TORN Token
- 0x26903a5a198D571422b2b4EA08b56a37cbD68c89
- Name: Tornado Staking Rewards
Acknowledgements
- Shayan Eskandari (@sbetamc)
- Mikerah (@badcryptobitch)
- Banteg (@bantg)
- Wavey (@wavey0x)
- Hudson Jameson (@hudsonjameson)
- Kirill Pimenov (@kirushik)
- Mike Wawszczak (@mikedotwaves)
- Mary Mallor (@mmaller)
- M (@PopcornandWhiskey)
- Milo Murphy
Thank you to these independent researchers and advocates who donated their time and expertise to this effort.