Unaudited, unvetted, experimental. Do not use as a reference. AI-researched ratings that may be wrong; not advice or a statement of fact about any provider. Full disclaimer
Pending review. 1150 of 1150 ratings not yet checked by a human. Do not rely on unreviewed ratings.
Ratings apply to this deployment only. Treat them as unverified for other chains. Why this deployment: The classic UI's networkConfig.js (tornado-classic-ui@a83fae07 L11-L60) lists Ethereum mainnet first (netId1, deployedBlock 9116966), and the onchain InstanceRegistry 0xB20c…A911 lists 19 enabled mainnet instances. Unit: the 4 ETH pools (0.1/1/10/100) and the 8 stablecoin pools (DAI 100-100k, USDC 100/1k, USDT 100/1k). Excluded: cDAI and WBTC pools, other chains (BSC, Polygon, Gnosis, Arbitrum, Optimism, Avalanche), Nova, and governance-only contracts (staking, vesting).
Offered everywhere, per the provider's code or documents. Checked 2026-10-09. Not scored.
The pools are immutable contracts with no live operator and no address or country check, so deposit and withdraw are callable from anywhere. The archived official classic UI has no country or IP geolocation gate in its source (grep for country, geolocation, ipapi, jurisdiction finds nothing); it screens the connecting wallet address against the Chainalysis sanctions oracle and redirects listed addresses to a 451 page. That is an address filter, not a country list. We found no first-party terms page listing countries; the GitHub org is archived and the classic UI source contains no terms text naming countries. Judgment call: we did not inspect the UI build currently served at tornadocash.eth, which could differ from the archived source. Legality of use differs by jurisdiction (see `context`); that is not an availability restriction by the provider.
Evidence (2)2 verified
Verified
deposit() and withdraw() in the deployed v2.0 source check only the commitment, nullifier, Merkle root and zkSNARK proof; there is no caller, address or country restriction.
The classic UI's only access check is isSanctioned(address) on the Chainalysis oracle at wallet connect; a grep of the source at this commit for country, geolocation, ipapi, ip-api and jurisdiction finds no country gate.
Can any privileged role stop, freeze, or block payments through the settlement contracts, and how is that role constrained? C1
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The pool contracts that hold and release funds have no pause, freeze, blacklist or allowlist. Their one admin role, operator, could only swap the verifier, and it reads as the zero address onchain on every pool that has it; the two newer DAI pools have no operator at all. The verifier has no admin. TORN governance does control a gate one step out: the optional TornadoRouter checks an upgradeable InstanceRegistry and RelayerRegistry, so governance could disable an instance on the router path. Judgment call: we score the pools as the settlement contracts and give 3, because a payer and payee can call the pools directly (C2) and the router gate does not reach that path.
Evidence (4)4 verified
Verified
The only privileged role in the pool source (tag v2.0, solc 0.5.11, the build deployed in Dec 2019) is operator, which can call updateVerifier and changeOperator (L116-L123); there is no pause, freeze, blacklist or allowlist. The Tornado and MerkleTreeWithHistory contracts in the Sourcify source of 0x47CE…2936 are identical to this file apart from line endings.
operator() of the ETH 1 pool returns the zero address at block 26141552; operator() also returns zero on the 0.1, 10, 100 ETH, DAI 100/1000, USDC and USDT pools at block 26141280, and reverts (no such function) on the DAI 10k/100k pools, whose 0.7.6 source has no operator.
The ETH 0.1 pool's source adds operator-only migrateState, initializeTreeForMigration and finishMigration; operator() returns zero, so none can be called.
The optional TornadoRouter refuses deposits and withdrawals for instances the InstanceRegistry marks DISABLED and calls RelayerRegistry.burn on withdraw; its governance() is the TORN governance proxy 0x5efd…A1Ce. All 19 registry instances read state 1 (enabled) at block 26140925.
Can a payer or payee complete settlement by calling the public contracts directly, without the provider's API, signer, or relayer? C2
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
A payer can deposit and a payee holding the note can withdraw by calling the pool contracts directly, with no relayer, router, API or signature from anyone else. Addresses and ABI are committed in the public UI repo, and the reference client calls the pool directly. We did not run a transaction. The payment is completed by handing the note to the payee off-chain; the protocol has no on-chain payee field at deposit time.
Evidence (4)4 verified
Verified
deposit(commitment) and withdraw(proof, root, nullifierHash, recipient, relayer, fee, refund) are external with no caller check; the relayer is only a fee recipient bound into the proof, and fee may be zero (ETHTornado.sol L29-L40 pays recipient directly).
Does the payment flow require a relayer, paymaster, bundler, or API that only the provider runs? C3
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
Settlement needs only the pools, a proof client and an Ethereum RPC. A relayer is optional: it exists so a withdrawer can pay gas from the withdrawn amount instead of from a funded account, which matters for privacy but not for settlement. The indexer is optional too, as the UI falls back to RPC event reads. Judgment call: we score 3 although withdrawing to a fresh address without a relayer needs gas from elsewhere, which can reduce privacy (see P3); the cell measures whether settlement depends on a hosted intermediary, and it does not.
Evidence (3)3 verified
Verified
Withdrawal pays denomination minus fee to the recipient and pays a relayer only if fee > 0; any account may submit the transaction.
The UI reads deposit events from The Graph and then from the RPC, so the indexer is optional; the proving key is a static GitHub release asset (tornado-core v2.1).
Relayers are optional; the RelayerRegistry lets anyone owning an ENS subdomain register with minStakeAmount 5000 TORN; relayer code is public (tornado-relayer, archived).
Is the settlement layer free of address or geographic filtering, and is any filtering at the edge disclosed and avoidable? C4
2 Partial
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The pools are neutral: no address or country filtering. The archived classic UI screens the connecting wallet against the Chainalysis sanctions oracle and sends listed addresses away. The check is visible in public code, the list source is identified by its oracle address, and the direct pool path bypasses it. tornado-core's cli.js has no screening. Judgment call: this fits anchor 3 in substance, but 3 needs a distributed package or trace for the client, and we also did not inspect the build currently served at tornadocash.eth, so we take 2.
Evidence (3)3 verified
Verified
On wallet connect (L427) the UI calls isSanctioned(address) on the Chainalysis sanctions oracle 0x40C57923924B5c5c5455c48D93317139ADDaC8fb and, if true, redirects the page away; pages/451.vue shows "Unavailable For Legal Reasons".
Are the tokens and chains the rail depends on enumerated, with their issuers' freeze powers and sequencer assumptions stated to payees? C5
! Under review
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 todayDrift
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The weekly re-check found that a recorded fact changed. This rating counts as unknown until a reviewer re-checks it.
Tokens and pools are enumerated onchain and in the UI config. Neither the repos nor the UI tell users that USDC and USDT can blacklist a pool address, which would lock every note in that pool; the pools were not blacklisted at our block. ETH and DAI pools carry no issuer freeze. Ethereum L1 has no sequencer. Scored 2: enumerated in code, assumptions not stated.
Evidence (2)2 verified
VerifiedDrift
InstanceRegistry lists each instance with its token (DAI 0x6B17…1d0F, USDC 0xA0b8…eB48, USDT 0xdAC1…1ec7, cDAI, WBTC, or ETH) and state; networkConfig.js in the UI enumerates the same per network.
USDC isBlacklisted() returns false for both USDC pools, and USDT isBlackListed() returns false for both USDT pools, at block 26141584; both issuers retain the power to blacklist.
Does the deployed bytecode match public source, and can a third party rebuild it? O1
1 Weak
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-07 12 days ago
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The pools and verifier are partial matches on Sourcify, the governance-era contracts are full matches, and the hasher, which every deposit calls, has no Sourcify verification (it is generated bytecode; we could not load Etherscan). No rebuild was attempted. Judgment call: partial matches would support 2, but one settlement-path contract is unverified, so we take anchor 1.
Evidence (2)2 verified
Verified
Sourcify returns match (partial, metadata differs) for all 12 pools and the verifier 0xce17…557A, exact_match for the router, registries and FeeManager, and no record for the MiMC hasher 0x8358…28fe.
Tag v2.0 pins solc 0.5.11 with optimizer runs 200, matching the deployed compiler; Verifier.sol is generated from the trusted-setup key and the hasher bytecode by scripts/compileHasher.js, neither committed as source.
Are the SDK, frontend, backend or API, indexer, and deploy scripts all public? O2
1 Weak
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-07 12 days ago
UnreviewedAssessed by AI research agent (seed), 2026-10-07
Every layer has public source on GitHub, but all of it is archived since 2022. For the immutable pools and the proof client the archive is still the running code. The governance-era router and registries are public only as Sourcify source, and the frontend now served via tornadocash.eth and current relayer builds were not traced to any public repository in this review. Judgment call: between 2 and 1 we take 1, because we could not show the live frontend and relayer builds are public.
Evidence (1)1 verified
Verified
All 47 repos in github.com/tornadocash are archived, last pushed between 2019 and 2022-08-22; they include contracts, circuits, CLI, classic UI, relayer, subgraphs and deploy scripts.
Are ABIs, event schemas, an API schema, and a payee data export in a non-proprietary format all in the repo? O4
2 Partial
Best evidence: VerifiedChecked 2026-10-07 12 days ago
UnreviewedAssessed by AI research agent (seed), 2026-10-07
ABIs and event schemas are in the repo. There is no protocol API to document, as no backend is required. There is no payee export function; the note string is the only record a payee holds. Judgment call: we treat the absence of any required API as satisfying the API part, giving 2; no export, so not 3.
Evidence (1)1 verified
Verified
ABIs for the pool instance, router (TornadoProxy), RelayerRegistry and governance are committed; Deposit and Withdrawal events are defined in Tornado.sol L36-L37.
Does the license actually let a third party fork, modify, and run it?
2 PartialPillar rating: weakest of 3 3 of 3 Partial or better
What would raise this pillar
Open-source licences reaching Strong: OSI-approved license on every repo in repos.
Protection against relicensing reaching Strong: No CLA, or a CLA that does not permit unilateral relicensing, plus a written license-stability commitment in the repo.
No proprietary dependencies reaching Strong: A production deployment needs no proprietary plugin or hosted-only service.
Does every repository needed to run the product carry an OSI-approved license? F1
2 Partial
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
Every required component carries an OSI licence: GPL-3.0 for the pools, circuits and proof client, and MIT for the classic UI. The circomlib fork used in proof generation states GPL-3.0 only in package.json, with no LICENSE file; its upstream is GPL-3.0. The optional tornado-cli, relayer and subgraph repos have no LICENSE file. Judgment call: we count the package.json declaration on circomlib as a licence, and we take 2 rather than 3 because of the unlicensed optional repos.
Evidence (2)2 verified
Verified
tornado-core (pools, circuits, verifier generation, cli.js) is GPL-3.0 at the deployed tag; the websnark and snarkjs forks are GPL-3.0 (GitHub license API).
The circomlib fork pinned by tornado-core has no LICENSE file; its package.json declares GPL-3.0. tornado-cli has no LICENSE file (package.json says ISC); tornado-relayer and tornado-subgraph have none.
Can the provider unilaterally relicense future versions, and has it committed not to? F2
2 Partial
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
There is no CLA and no relicensing event, and the GitHub repos are archived. No written licence-stability commitment exists.
Evidence (1)1 verified
Verified
The UI's contributing guide asks for focused PRs and has no CLA. tornado-core has no CONTRIBUTING file, and its LICENSE has a single commit, 21a9545b (2019-07-17).
Does a production deployment need a proprietary plugin or hosted-only service? F3
2 Partial
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
No proprietary plugin or hosted-only service is needed. The pools, proving key and client are public, and any Ethereum RPC works. The UI's default Infura and Alchemy RPCs, The Graph, and the Chainalysis oracle are all optional. Judgment call: the code supports 3, but with no O3 reproduction we take 2.
Evidence (1)1 verified
Verified
The circuit and proving key come from tornado-core GitHub release assets (v2.1); the client needs only a user-supplied RPC.
What can an observer learn, and did the user knowingly choose it?
2 PartialPillar rating: weakest of 5 5 of 5 Partial or better
What would raise this pillar
Tracking and analytics reaching Strong: None in SDK, widget, or frontend manifests and lockfiles, confirmed by trace.
Third parties in the payment flow reaching Strong: Only the configured RPC; no third-party indexer, risk-scoring, or pricing vendor in the critical path.
Endpoints can be changed reaching Strong: RPC and indexer URLs configurable in the UI or SDK, and indexer code public.
Do the SDK, widget, or frontend ship analytics, telemetry, error reporting, or fingerprinting? P1
2 Partial
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The archived UI and the core client ship no analytics or telemetry. When a remote RPC is used, tornado-cli calls ip.tornado.cash to show the user's IP; that call is counted under P4. We ran no trace and did not inspect the live IPFS build. Judgment call: absence shown only in code is capped at 2.
Evidence (1)1 verified
Verified
None of the UI dependencies is an analytics, telemetry, error-reporting or fingerprinting package; nuxt.config.js L53 sets a CSP with script-src 'self'.
Does the flow collect anything beyond addresses, amounts, token, and chain? P2
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The protocol collects only what settlement needs: a commitment at deposit, and recipient, relayer and fee at withdrawal. No required component holds account, identity or contact data. An optional relayer sees the recipient and the proof it relays.
Evidence (1)1 verified
Verified
The public inputs are root, nullifierHash, recipient, relayer, fee and refund. The private inputs (nullifier, secret, Merkle path) stay in the user's client. Deposit takes only a commitment.
What do calldata and events reveal about who paid whom for what? P3
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
Onchain data shows who deposited and who received, but not which deposit paid which withdrawal. Amounts are fixed denominations, and there is no memo or invoice field. Linkage can still come from timing, distinctive gas or funding patterns, low pool activity, reused addresses, or the optional router EncryptedNote event, which ties the depositor's address to an encrypted note backup. Judgment call: anonymity-set size depends on user behaviour and is not scored; we score what the code and chain reveal, which is anchor 3.
Evidence (2)2 verified
Verified
Deposit emits commitment, leafIndex and timestamp, and the depositor is the tx sender. Withdrawal emits recipient, nullifierHash, relayer and fee. The proof hides which commitment a nullifier spends.
Which third parties see a request during a payment, and can they be swapped out? P4
2 Partial
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
On the minimal required path (core client plus RPC), only the RPC the user chooses sees the request. The optional UI adds The Graph (hardcoded) and default Infura and Alchemy RPCs (swappable in Settings). An optional relayer, when used, sees the recipient and the user's IP unless Tor is used. tornado-cli adds an IP-echo call. All of these are named in code. Judgment call: we score 2 because the hardcoded Graph endpoint cannot be swapped by config, although a user avoids it by not using the UI.
Evidence (2)2 verified
Verified
The UI queries The Graph hosted-service subgraphs at hardcoded URLs. Its RPC defaults are Infura and Alchemy with build-time keys (networkConfig.js L30-L39), replaceable in Settings. The Chainalysis oracle is read through the RPC.
Can RPC and indexer URLs be changed, and is the indexer code public? P5
2 Partial
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The RPC can be set in the UI, and with --rpc in the CLI. The indexer URL can be changed only in code, though the UI falls back to RPC reads. Scored 2: the indexer is configurable via code only.
Evidence (1)1 verified
Verified
The UI settings offer an RPC dropdown and a custom RPC URL field. The indexer URL is fixed in services/graph.js; the indexer code is public (tornado-subgraph).
Who can cause loss, lock users in, or change the rules?
1 WeakPillar rating: weakest of 6 4 of 6 Partial or better
What would raise this pillar
Token approval scope reaching Partial: A bounded allowance by default (capped or refilling, limited to one receiver), or exact-amount with an unbounded opt-in clearly labelled in code.
Audits and bug bounty reaching Partial: Audit pinned to a commit, resolutions not individually linked.
Who holds funds between payer and payee, and can the provider redirect them? S1
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The pools are non-upgradeable escrows that release funds only to whoever holds the note's secret, who chooses the recipient in the proof. No operator, governance or relayer can redirect funds. A relayer cannot change the recipient or fee because both are bound into the proof. Whoever holds the note controls the funds, so a payer who keeps a copy of a note handed to a payee can still withdraw first.
Evidence (2)2 verified
Verified
Funds sit in the pool between deposit and withdrawal and leave only to the recipient (and an optional relayer fee) bound into a valid proof for an unspent nullifier; no function lets any role move pool funds.
The DAI 100k pool (0.7.6 build) has no operator function, and its EIP-1967 implementation slot is zero; the 0.5.11 pools have operator() = 0x0 (see C1).
Who can change the contract code, and with how much notice? S2
3 Strong
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
No one can change the pool, verifier or router code: none is a proxy, and the one pool role that could swap the verifier is set to zero. TORN governance (5-day vote, 2-day execution delay, delegatecall execution) can upgrade the InstanceRegistry, RelayerRegistry and FeeManager, which only the optional router path consults, and it owns the tornadocash.eth name that serves the UI. Proposal 20's target was created after its vote closed and carries a selfdestruct, which shows that code executed by governance need not be the code voters saw. Judgment call: we score the settlement contracts at 3; the governance risk is in the router path and the frontend, both of which a user can avoid.
Evidence (4)4 verified
Verified
The EIP-1967 implementation slot reads zero on all 12 pools and on the verifier and router; pools have no upgrade function, and operator() (which could swap the verifier) is 0x0.
RelayerRegistry, InstanceRegistry and FeeManager are proxies whose admin slot is the governance proxy 0x5efd…A1Ce; governance is its own admin (LoopbackProxy).
EXECUTION_DELAY is 172800 s (2 days) after a 432000 s (5 day) voting period; execute() delegatecalls the proposal contract (tornado-governance Governance.sol L184-L200), so a passed proposal can do anything governance can.
proposals(20) has target 0xC503…752D, endTime 1684394654 (2023-05-18) and executed = true; the verified code at the target includes an owner-only selfdestruct (emergencyStop), and Sourcify records its creation in tx 0x4eeffe76…042b at block 17299150 (2023-05-20), after voting closed.
How large an allowance does the SDK ask users to grant, and for how long? S3
1 Weak
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The UI asks by default for an unlimited allowance to TornadoRouter and shows the choice in its approval dialog. The router is not upgradeable, and deposit pulls only the denomination from msg.sender, but any allowance left over remains exposed to the router's fixed code. The core client approves exactly the deposit amount, which would score higher. Judgment call: we score the UI default because it is the published frontend, and take 1 (unbounded by default, disclosed).
Evidence (2)2 verified
Verified
approvalAmount defaults to 'unlimited' (L13), which approves 2^256-1 to the router; components/ApproveModalBox.vue offers the user a choice between the deposit amount and unlimited.
If the provider disappears tomorrow, do payees keep their funds and the ability to keep settling? S4
2 Partial
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
Derived from S1=3, C2=3, C3=3 and O3=1. Funds sit in immutable pools that no one can redirect (S1). A note holder can withdraw by calling the pool directly with the public client and proving key (C2), and no relayer or indexer is required (C3). Settlement can continue the same way. A public frontend build exists in the archived classic UI, but we did not reproduce it (O3=1). Judgment call: 2, not 3, for that reason.
Evidence (2)2 verified
Verified
The pools are immutable with operator 0x0, and withdraw is callable by anyone holding a valid proof (C2).
Are secrets kept out of client bundles and are webhooks signed and verified? S5
2 Partial
Best evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
The user secret is the note (nullifier and secret), generated and kept client-side. The protocol has no API keys or webhooks. The UI embeds RPC provider keys in its bundle, a minor issue since they grant only RPC quota. Integrity of the served frontend depends on whoever controls tornadocash.eth (TORN governance, see S2). Judgment call: 2 for the bundled RPC keys.
Evidence (1)1 verified
Verified
The UI builds INFURA_KEY and ALCHEMY_*_KEY from env into client-side RPC URLs, so those keys ship in the browser bundle; they authorise RPC usage only. There are no webhooks or merchant API keys.
Has the code been audited at a pinned commit, were findings fixed traceably, and is there a live bounty? S6
1 Weak
Sets the pillar ratingBest evidence: VerifiedChecked 2026-10-19 today
UnreviewedAssessed by AI research agent (seed), 2026-10-07
ABDK audited the contracts and circuits at a pinned commit, and the report links fix commits. The deployed code was built from tag v2.0, 107 commits later, and we could not confirm every change after the audit was reviewed. There is no live bug bounty. The router, registries and governance upgrades were not reviewed here. Judgment call: 1 rather than 2, because the audited commit is not the deployed commit.
Evidence (2)2 verified
Verified
ABDK's Solidity audit pins peppersec/tornado-mixer commit 0484408e (2019-10-17) and links fix commits such as d0e312eb (merge of PR 24, "audit-6"); circuit and cryptographic reviews sit in the same folder.
The README links the ABDK reports at tornado.cash URLs, which no longer resolve. The deployed tag v2.0 (7033f344) is 107 commits after the audited commit, with contract changes; no bug bounty or SECURITY file exists in the repos.
Published audits and similar reviews of this provider's code, newest first. Context for the Audits and bug bounty rating, which scores them; this list does not change any rating, and an audit of older code says little about what is deployed now.
Cryptographic review of the mixer protocol (Pedersen and MiMC hashing, nullifier and commitment design) and its implementation. Reviews the protocol design used by the deployed pools; the implementation it read was the then-current master of peppersec/tornado-mixer (now tornadocash/tornado-core), not a pinned commit.
Withdraw circuit, Merkle tree checker and hash templates (circom) in tornado-mixer. at 0484408e82 The repository was then named peppersec/tornado-mixer. The deployed proving key comes from the tornado-core v2.1 release assets; we did not compare the deployed circuit with the audited commit.
Partly
No major issues; minor issues, many fixed in linked commits, one left open
Pool contracts (Mixer, ETH and ERC20 mixers, Merkle tree) in tornado-mixer. at 0484408e82 The deployed pools were built from tag v2.0 (7033f344), 107 commits after the audited commit, with contract changes (see S6).
Partly
No critical issues; major and moderate flaws marked fixed (last fix commit d0e312eb); some minor issues deferred or declined
Compiled from: The tornado-core README audit section (its tornado.cash/audits links no longer resolve), the classic UI README (links a Decurity dApp audit at tornado.cash, which no longer resolves and is not in Decurity's public audits repo), the ABDK portfolio at github.com/abdk-consulting/audits (tornado folder), all archived github.com/tornadocash repos, and the Trail of Bits publications list. ABDK's 2020 audit of the Tornado Farm anonymity-mining contracts is in the same folder but is not in the payment path, so it is not listed. No published audit of the router, registries or governance contracts was found. Checked 2026-10-13. Only published reports are listed; private audits a provider mentions without a report are not.
Operational and procurement
Facts an institution's procurement, finance and security functions ask for. Separate from the CROPS ratings and never scored.
Group A: operational facts. Group B: 45 due-diligence controls derived from a UN agency's vendor requirements: 10 evidenced, 0 attested, 4 absent, 31 not applicable, 0 unknown. "Not applicable" means there is no operator to hold the control: it falls to whoever deploys the rail. How to read this.
Group A: operational facts
Fees
Evidenced
Component
Paid by
Amount
Basis
provider
none
none in the pool contracts
withdraw sends the denomination minus the proof-bound fee to the recipient and the fee to the relayer; the pools take nothing and have no admin to add a fee.
provider
payee
optional relayer fee, set by the chosen relayer
Deducted from the withdrawn denomination when a relayer submits the withdrawal; fee and relayer are bound into the proof. Zero when the withdrawer submits it.
network
payer
deposit sample 2026-10-09, 0.00287 ETH (919,444 gas at 3.12 gwei)
Router deposit into the ETH 1 pool, tx 0xb25e…d1cc, block 26153431; varies with Ethereum gas price.
network
payee
withdrawal sample 2026-10-09, 0.00109 ETH (349,079 gas at 3.12 gwei)
Self-submitted withdrawal from the ETH 1 pool via the router with fee 0, tx 0x7678…48e3, block 26153424.
limit
none
fixed denominations per pool (ETH 0.1/1/10/100, DAI 100 to 100k, USDC and USDT 100/1k)
Each pool's denomination is set at construction and cannot change; one deposit equals one denomination (pools enumerated per token in the InstanceRegistry, see refs).
On the optional router path, relayers registered in the RelayerRegistry have TORN burned from their stake per withdrawal (FeeManager sets the rate); that cost falls on relayers and reaches users only through their fee. No FX.
Withdrawal receipt read 2026-10-09: gasUsed 349079, effectiveGasPrice 3.125 gwei, cost 0.001091 ETH; Withdrawal log from the ETH 1 pool with relayer 0x0 and fee 0.
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Custody model
Evidenced
Self-custody
Agrees with S1 (score 3). Funds sit in immutable pools between deposit and withdrawal and leave only to whoever holds the note; no operator, governance or relayer can move them. Holding the note is holding the funds, so a payer who keeps a copy can withdraw first.
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Licences and registrations
N/A: falls to the institution
An institution using the pools carries its own licensing and sanctions analysis; see the provider file's `context` for the 2022 OFAC designation and its 2025 removal.
No legal entity operates the pools and no party takes custody or provides a service on the required path; there is nobody to hold a licence. Relayers and frontends are optional and independent.
Verified
The GitHub organisation profile names no company (company null; name "Tornado Cash"; blog tornado.cash).
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Cash-out options
N/A: falls to the institution
The note holder withdraws the token to an address it chooses; converting it to local currency is outside the protocol.
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
First deployment
Evidenced
2019-12-16 (block 9116966): ETH 0.1 pool 0x12D6…B8Fc, the first Ethereum mainnet pool (also the UI config's deployedBlock); the ETH 1 pool followed at block 9117609.
Verified
Sourcify creation data gives tx 0xeed4367a9b4c066b9fbf0a44869f36b93d2f06e5a63a9464ddfd0597a8a45935, block 9116966, deployer 0x8589…DA16; the receipt's contractAddress is this pool and the block time is 2019-12-16 19:08 UTC.
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Operating entity
Absent
Searched: the GitHub org profile, tornado-core and classic-UI READMEs and the classic UI source (no terms or legal entity), and https://tornado.cash (no response to curl). No contracting entity is disclosed. OFAC's 2022 designation treated "Tornado Cash" as an entity without naming a legal form, and the US and Dutch prosecutions named individuals; neither is a company record.
Verified
The organisation profile names no company or legal entity.
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Security incidents
Evidenced
2023-05-20: TORN governance proposal 20 was executed although its target contract was created after the vote closed and carries an owner-only selfdestruct, so the code executed was not the code voters saw. It reached governance, the registries and the router path, not the pools. Wider effects were not reconstructed here. funds lost: unknownsource
Absence of a found incident is not evidence that none occurred.
Primary sources only. A 2024 report of a backdoor in the IPFS-served frontend was not evidenced from a primary source and is not listed. No pool contract incident was found: the pools are immutable and their operator is zero (CROPS C1, S2).
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Product changes affecting users
Evidenced
2022-08-08: US Treasury (OFAC) designated Tornado Cash and its smart contract addresses. source
2022-08-22: Last push to the github.com/tornadocash repositories; all 47 are now archived. source
2025-03-21: US Treasury announced removal of the Tornado Cash sanctions. source
The pool contracts themselves have not changed since deployment. Governance changes to the optional registries and router are not itemised (72 proposals at the seed read).
checked 2026-10-09 · source unchanged at weekly re-read 2026-10-19
UnreviewedAssessed by AI research agent (operational), 2026-10-09Checked 2026-10-09
Volume transacted (verified only)
Unknown
not computed on 2026-10-19: eth_getLogs: Request blocked
Settlement is observable but the event shape does not fit a single amount spec. 347 events (deposits and withdrawals) appeared on the four ETH pools in the 5000 blocks to 26153707, so the pools are in use. Not computed; the maintainer runs scripts/volumes.mjs.
UnreviewedAssessed by AI research agent (operational), 2026-10-09
Group B: institutional due diligence
Control
State
What was found
Assurance and certifications
B1.1 ISO 27001, developer organisation Is the organisation that develops the product ISO 27001 certified, and does the certificate name that entity?
N/A: falls to the institution implied from the component list
B1.2 ISO 27001, hosting and support organisation Is the organisation that hosts and supports the service ISO 27001 certified in its own name, with a scope covering the service?
N/A: falls to the institution implied from the component list
B1.3 SOC 2 Type II or ISAE 3000/3402 reports Does the provider undergo periodic SOC 2 Type II or ISAE 3402 Type II assessments and make reports available?
N/A: falls to the institution implied from the component list
B1.4 Independent source-code security review before go-live Was the application reviewed by an independent party before launch, and is the report linked?
N/A: falls to the institution implied from the component list
B1.5 Penetration testing Is the service penetration-tested before go-live and at least every three years, with results available?
N/A: falls to the institution implied from the component list
B1.6 Vulnerability scanning cadence Are the platform and the application scanned for vulnerabilities at least every six months?
N/A: falls to the institution implied from the component list
Vulnerability and patch management
B2.1 Security contact and disclosure policy Is there a published way to report a vulnerability (SECURITY.md, security.txt, or a disclosure page)?
Absent
none of 9 repo(s): tornadocash/tornado-core (archived) ✗ no security policy file; tornadocash/tornado-classic-ui (archived) ✗ no security policy file; tornadocash/tornado-cli (archived) ✗ no security policy file; tornadocash/tornado-relayer (archived) ✗ no security policy file; tornadocash/tornado-governance (archived) ✗ no security policy file; tornadocash/tornado-subgraph (archived) ✗ no security policy file; tornadocash/websnark (archived) ✗ no security policy file; tornadocash/snarkjs (archived) ✗ no security policy file; tornadocash/circomlib (archived) ✗ no security policy file source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 · source 8 · source 9
B2.2 Patch service levels Does the provider commit to patch timelines for known vulnerabilities (the partner expects 30 days critical, 40 high, 90 medium)?
N/A: falls to the institution implied from the component list
B2.3 Dependency and vulnerability scanning in CI Do the public repositories run dependency or code scanning automatically?
Absent
none of 9 repo(s): tornadocash/tornado-core (archived) ✗ no scanning config or workflow step found; tornadocash/tornado-classic-ui (archived) ✗ no scanning config or workflow step found; tornadocash/tornado-cli (archived) ✗ no scanning config or workflow step found; tornadocash/tornado-relayer (archived) ✗ no scanning config or workflow step found; tornadocash/tornado-governance (archived) ✗ no scanning config or workflow step found; tornadocash/tornado-subgraph (archived) ✗ no scanning config or workflow step found; tornadocash/websnark (archived) ✗ no scanning config or workflow step found; tornadocash/snarkjs (archived) ✗ no scanning config or workflow step found; tornadocash/circomlib (archived) ✗ no scanning config or workflow step found source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 · source 8 · source 9
Incident reporting and continuity
B3.1 Incident reporting commitment Does the provider commit to notify customers of security or data incidents within a stated time (the partner expects 24 hours)?
N/A: falls to the institution implied from the component list
B3.2 Backups and restore testing Are customer records backed up daily and restores tested on a schedule?
N/A: no such service implied from the component list
B3.3 Recovery plan Is there an approved and tested recovery plan for the service?
N/A: no such service implied from the component list
B3.4 Status page and post-mortems Does the provider publish service status and post-mortems for incidents?
N/A: falls to the institution implied from the component list
Identity and access (operator side)
B4.1 MFA for end users Can or must end users protect accounts with multi-factor authentication?
N/A: no such service implied from the component list
B4.2 MFA and separate accounts for privileged access Is privileged access protected by MFA and kept on separate accounts?
N/A: falls to the institution implied from the component list
B4.3 Periodic access reviews Are user access rights reviewed at least annually and privileged accounts at least six-monthly?
N/A: falls to the institution implied from the component list
B4.4 Segregation of duties and joiner-mover-leaver controls Is there a documented segregation-of-duties model and a joiner-mover-leaver process?
N/A: falls to the institution implied from the component list
B4.5 Session timeout Are idle interactive sessions terminated after a defined period (the partner expects 60 minutes)?
N/A: no such service implied from the component list
API and integration
B5.1 API authentication, browser to server Which standard (OAuth 2.0, OpenID Connect, SAML, JWT) protects browser-to-server API calls?
N/A: falls to the institution implied from the component list
B5.2 API authentication, server to server Are server-to-server calls authenticated with keys or PKI certificates, and are keys scoped and rotatable?
N/A: falls to the institution implied from the component list
B5.3 Token expiry Do API tokens expire, and within what period (the partner caps it at 120 minutes for public data, 30 otherwise)?
N/A: falls to the institution implied from the component list
B5.4 Export controls If an API exports data, does it limit volumes and log exports?
N/A: falls to the institution implied from the component list
Data protection and privacy governance
B6.1 Data classification and encryption Does the provider state a data classification and enforce encryption at rest and TLS 1.2 or better in transit?
N/A: falls to the institution implied from the component list
B6.2 Production data kept out of test environments Does the provider state that production or real personal data is not used in development and testing?
N/A: falls to the institution implied from the component list
B6.3 Data retention and deletion on termination What is retained, for how long, and is customer data removed on termination?
N/A: falls to the institution implied from the component list
B6.4 Data protection impact assessment and roles For systems holding personal data, has a DPIA been completed and are controller and processor defined?
N/A: falls to the institution implied from the component list
B6.5 Data processing or sharing agreement available Can a customer obtain a data processing agreement or equivalent?
N/A: falls to the institution implied from the component list
Logging and monitoring
B7.1 Audit logging Are account changes, logins and activity on important records logged and retained?
N/A: falls to the institution implied from the component list
B7.2 Central monitoring and endpoint detection Are logs sent to a managed SIEM and is endpoint detection running on all platforms?
N/A: falls to the institution implied from the component list
Hosting and network
B8.1 Hardened hosting Are hosts hardened to a recognised benchmark, with only essential ports open, IDS/IPS, a WAF for internet-facing applications and tenant isolation?
N/A: falls to the institution implied from the component list
B8.2 Deployment configuration and infrastructure as code Does the repository ship reproducible deployment configuration (containers, IaC, Helm) that a self-hoster can harden?
Evidenced
some of 9 repo(s): tornadocash/tornado-core (archived) ✗ no deployment configuration; tornadocash/tornado-classic-ui (archived) ✓ deployment configuration: Dockerfile; tornadocash/tornado-cli (archived) ✗ no deployment configuration; tornadocash/tornado-relayer (archived) ✓ deployment configuration: Dockerfile; tornadocash/tornado-governance (archived) ✗ no deployment configuration; tornadocash/tornado-subgraph (archived) ✗ no deployment configuration; tornadocash/websnark (archived) ✗ no deployment configuration; tornadocash/snarkjs (archived) ✗ no deployment configuration; tornadocash/circomlib (archived) ✗ no deployment configuration source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 · source 8 · source 9
Engineering practice in public repositories
B9.1 Default branch protected Does the default branch require reviews and passing checks, with no direct pushes?
Absent
none of 9 repo(s): tornadocash/tornado-core (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/tornado-classic-ui (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/tornado-cli (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/tornado-relayer (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/tornado-governance (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/tornado-subgraph (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/websnark (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/snarkjs (archived) ✗ no branch rules visible (classic branch protection is not readable without push access); tornadocash/circomlib (archived) ✗ no branch rules visible (classic branch protection is not readable without push access) source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 · source 8 · source 9
B9.2 CI runs on pull requests Does every pull request trigger automated checks?
B9.3 Tests run in CI Do the CI workflows run the test suite?
Evidenced
some of 9 repo(s): tornadocash/tornado-core (archived) ✓ test command in a workflow; tornadocash/tornado-classic-ui (archived) ✗ test command in a workflow; tornadocash/tornado-cli (archived) ✗ test command in a workflow; tornadocash/tornado-relayer (archived) ✓ test command in a workflow; tornadocash/tornado-governance (archived) ✓ test command in a workflow; tornadocash/tornado-subgraph (archived) ✗ test command in a workflow; tornadocash/websnark (archived) ✗ test command in a workflow; tornadocash/snarkjs (archived) ✗ test command in a workflow; tornadocash/circomlib (archived) ✗ test command in a workflow source 1 · source 2 · source 3 · source 4 · source 5 · source 6 · source 7 · source 8 · source 9
B9.4 Coverage reported Is test coverage measured and reported (the partner expects 85%)?
B10.1 Architecture documentation Is there a public architecture document covering logical, infrastructure and integration architecture and the components used?
Evidenced
Logical view only. The tornado-core README describes the deposit, commitment, proof and withdrawal design with a diagram and gas and circuit specs; there is no infrastructure or integration architecture document (the linked whitepaper URL on tornado.cash does not resolve). source 1
Commercial and financial
B11.1 Contracting entity Which legal entity would an institution contract with, and in which jurisdiction?
N/A: falls to the institution implied from the component list
B11.2 Funding of ongoing operation How is ongoing operation and maintenance funded (revenue, foundation, grants, fee switch), per a primary source?
Evidenced
No operator to fund. The pools need no maintenance; relayers fund themselves from withdrawal fees; TORN governance can fund changes to the optional registries, router and frontend by proposal. Public development stopped in 2022. CROPS S2 · CROPS S2 · CROPS C3 · CROPS O2
B11.3 Termination terms What happens to customer funds and data on termination by either side?
N/A: falls to the institution implied from the component list
AI components
B12.1 AI in the payment path Does an AI system take part in payment processing or compliance decisions (for example automated transaction screening)?
Absent
Searched: the pool contracts and the core client (no screening of any kind) and the archived classic UI, whose only check is a lookup of the connecting address in the Chainalysis sanctions oracle, a list lookup rather than an AI decision. The build served at tornadocash.eth was not inspected. CROPS C4 · CROPS C4
B12.2 AI controls documented If AI is used, are monitoring, validation, override, decommissioning and bias evaluation documented?
N/A: no such service
No AI component was found in the payment path (B12.1 absent).
Unit: 12 Ethereum mainnet pools (ETH 0.1/1/10/100, DAI 100/1k/10k/100k, USDC 100/1k, USDT 100/1k), the shared verifier 0xce17…557A and the hasher 0x8358…28fe. Pool and slot reads are pinned at blocks 26141280 and 26141552, governance and token reads at 26141584, and registry state at 26140925 (publicnode serves only recent blocks, so the reads span several blocks). The github.com/tornadocash org is archived (all 47 repos, last push 2022-08-22). We cite it for the immutable pools and the clients; later community source was not reviewed. Governance: TORN-weighted LoopbackProxy with 72 proposals at our read. Proposal 20 (May 2023) is recorded in S2 from onchain state only. The reported 2024 frontend backdoor was not evidenced from a primary source here and is not scored. The hasher is generated bytecode with no Sourcify record; Etherscan could not be loaded. No transactions, UI runs, traces, or self-host attempts were made.