Skip to main content

Overview

The TornadoPool contract is the main contract that enables private transactions on Layer 2. It allows deposits of arbitrary amounts, shielded transfers between registered users, and withdrawals. The contract uses a UTXO (Unspent Transaction Output) model to manage user funds privately. Contract Location: contracts/TornadoPool.sol

Constants

MAX_EXT_AMOUNT
int256
Maximum external amount value: 2^248
MAX_FEE
uint256
Maximum fee value: 2^248
MIN_EXT_AMOUNT_LIMIT
uint256
Minimum external amount limit: 0.5 ether

State Variables

verifier2
IVerifier
Immutable address of the SNARK verifier for 2 inputs
verifier16
IVerifier
Immutable address of the SNARK verifier for 16 inputs
token
IERC6777
Immutable address of the ERC20 token used by this pool
omniBridge
address
Immutable address of the OmniBridge contract for cross-chain functionality
l1Unwrapper
address
Immutable address of the L1Unwrapper contract
multisig
address
Immutable address of the multisig governance contract
lastBalance
uint256
Last recorded token balance of the contract
maximumDepositAmount
uint256
Maximum amount that can be deposited in a single transaction
nullifierHashes
mapping(bytes32 => bool)
Mapping to track spent nullifiers to prevent double-spending

Constructor

constructor(
  IVerifier _verifier2,
  IVerifier _verifier16,
  uint32 _levels,
  address _hasher,
  IERC6777 _token,
  address _omniBridge,
  address _l1Unwrapper,
  address _governance,
  uint256 _l1ChainId,
  address _multisig
)
_verifier2
IVerifier
required
The address of SNARK verifier for 2 inputs
_verifier16
IVerifier
required
The address of SNARK verifier for 16 inputs
_levels
uint32
required
Height of the commitments merkle tree
_hasher
address
required
Hasher address for the merkle tree (Poseidon hash)
_token
IERC6777
required
Token address for the pool
_omniBridge
address
required
OmniBridge address for the specified token
_l1Unwrapper
address
required
Address of the L1Helper contract
_governance
address
required
Owner address for governance
_l1ChainId
uint256
required
Chain ID of L1
_multisig
address
required
Multisig address on L2

Public Functions

initialize

function initialize(uint256 _maximumDepositAmount) external
Initializes the contract with maximum deposit amount. Can only be called once.
_maximumDepositAmount
uint256
required
Maximum amount that can be deposited per transaction
Source: contracts/TornadoPool.sol:112

transact

function transact(Proof memory _args, ExtData memory _extData) public
Main function that allows deposits, transfers, and withdrawals. Handles L2 deposits and validates proofs.
_args
Proof
required
Proof structure containing ZK proof and transaction data
_extData
ExtData
required
External data structure containing recipient, amounts, fees, and encrypted outputs
Requirements:
  • For deposits (extAmount > 0): Amount must be transferred from sender and not exceed maximumDepositAmount
  • Valid merkle root
  • Nullifiers not already spent
  • Valid external data hash
  • Valid public amount calculation
  • Valid ZK proof
Source: contracts/TornadoPool.sol:119

register

function register(Account memory _account) public
Registers a user’s public key in the pool to enable receiving shielded transfers.
_account
Account
required
Account structure containing owner address and public key
Requirements:
  • Account owner must be msg.sender
Source: contracts/TornadoPool.sol:129

registerAndTransact

function registerAndTransact(
  Account memory _account,
  Proof memory _proofArgs,
  ExtData memory _extData
) public
Combines registration and transaction in a single call. Useful for new users making their first deposit.
_account
Account
required
Account structure containing owner address and public key
_proofArgs
Proof
required
Proof structure containing ZK proof and transaction data
_extData
ExtData
required
External data structure containing recipient, amounts, fees, and encrypted outputs
Source: contracts/TornadoPool.sol:134

onTokenBridged

function onTokenBridged(
  IERC6777 _token,
  uint256 _amount,
  bytes calldata _data
) external override
Callback function invoked by OmniBridge when tokens are bridged from L1. Automatically processes the deposit transaction.
_token
IERC6777
required
Token contract address (must match pool token)
_amount
uint256
required
Amount of tokens bridged
_data
bytes
required
Encoded Proof and ExtData for the transaction
Requirements:
  • Only callable by omniBridge
  • Token must match pool token
  • Amount must match extData.extAmount
  • Bridge must send sufficient tokens
  • Amount must not exceed maximumDepositAmount
Source: contracts/TornadoPool.sol:143

onTransact

function onTransact(Proof memory _args, ExtData memory _extData) external
Internal wrapper for _transact to enable try-catch from onTokenBridged. Only callable by the contract itself.
_args
Proof
required
Proof structure containing ZK proof and transaction data
_extData
ExtData
required
External data structure
Source: contracts/TornadoPool.sol:163

rescueTokens

function rescueTokens(
  IERC6777 _token,
  address payable _to,
  uint256 _balance
) external
Allows multisig to rescue accidentally sent tokens (not pool tokens). Only callable by multisig.
_token
IERC6777
required
Token contract to rescue (address(0) for ETH)
_to
address payable
required
Recipient address
_balance
uint256
required
Amount to rescue (0 for full balance)
Requirements:
  • Only callable by multisig
  • Cannot rescue pool token
  • Cannot send to zero address
Source: contracts/TornadoPool.sol:169

configureLimits

function configureLimits(uint256 _maximumDepositAmount) public
Updates the maximum deposit amount. Only callable by multisig.
_maximumDepositAmount
uint256
required
New maximum deposit amount
Source: contracts/TornadoPool.sol:191

calculatePublicAmount

function calculatePublicAmount(int256 _extAmount, uint256 _fee) public pure returns (uint256)
Calculates the public amount field for the ZK circuit from external amount and fee.
_extAmount
int256
required
External amount (positive for deposits, negative for withdrawals)
_fee
uint256
required
Relayer fee
Returns: Public amount in field element format Requirements:
  • Fee must be less than MAX_FEE
  • extAmount must be within valid range
Source: contracts/TornadoPool.sol:195

isSpent

function isSpent(bytes32 _nullifierHash) public view returns (bool)
Checks whether a nullifier hash has already been spent.
_nullifierHash
bytes32
required
Nullifier hash to check
Returns: true if the nullifier has been spent, false otherwise Source: contracts/TornadoPool.sol:203

verifyProof

function verifyProof(Proof memory _args) public view returns (bool)
Verifies a ZK-SNARK proof using the appropriate verifier (2 or 16 inputs).
_args
Proof
required
Proof structure to verify
Returns: true if the proof is valid, false otherwise Requirements:
  • Input nullifiers length must be 2 or 16
Source: contracts/TornadoPool.sol:207

Inherited Functions

TornadoPool inherits from:
  • MerkleTreeWithHistory - Provides merkle tree functionality
  • IERC20Receiver - Token bridge receiver interface
  • ReentrancyGuard - Protection against reentrancy attacks
  • CrossChainGuard - Cross-chain message verification
See the respective base contracts for additional functions like isKnownRoot() from MerkleTreeWithHistory.

Build docs developers (and LLMs) love