a49945df (main)
and
e58132ab (PR)
+8 -3
+8 -3
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which option each voter chose. Every address that receives a ballot, its voting power, the timing and the totals per option are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Which option a voter chose: the link between a voter's address and their ballot."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Ballots stay encrypted, and only the totals per option are decrypted.",
"exposureContinued": "A mask looks like a vote, so an input to an address does not prove that its owner voted.",
"sources": [
{
"contract": "CRISPProgram",
"title": "Inputs carry only a commitment to the ciphertext"
},
{
"title": "Votes, updates and masks share one circuit",
"url": "https://github.com/theinterfold/CRISP/blob/35dbda14c4026510ba91e15d700399df115900ab/circuits/bin/crisp_onchain/src/main.nr#L28-L58"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "warning",
"exposureShort": "Voting power is public, so the totals per option can reveal how a voter with outsized weight voted.",
"exposureContinued": "A voter whose weight exceeds the totals of all but one option can only have chosen that one. The app's random weight blurs exact matches among smaller voters.",
"advice": "Keep the random weight on.",
"sources": [
{
"title": "Random weight against subset-sum matching",
"url": "https://github.com/theinterfold/the-interfold-governance/blob/28b03a8b529dfa7491f01229724391665f06bd95/app/plugins/crispVoting/utils/ballotWeight.ts#L36-L55"
},
{
"title": "Interfold: the public result can show how a voter voted",
"url": "https://github.com/theinterfold/interfold/blob/c2a28ae6b277aa72a62c34c07142bfadf7c4b4e1/docs/pages/governance.mdx#L237-L270"
}
],
"id": "chainAnalyst",
"value": "Link at risk",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "good",
"exposureShort": "The ballot leaves the browser only as ciphertext with its proof, so traffic shows at most that the user sent a ballot.",
"exposureContinued": "The app reads the chain through the CRISP server and sends ballots to it, so these requests reach no third party. WalletConnect runs with analytics off.",
"sources": [
{
"title": "Chain reads go to the CRISP server first",
"url": "https://github.com/theinterfold/the-interfold-governance/blob/28b03a8b529dfa7491f01229724391665f06bd95/app/constants.ts#L70-L82"
},
{
"title": "Ballots are sent to the CRISP server",
"url": "https://github.com/theinterfold/the-interfold-governance/blob/28b03a8b529dfa7491f01229724391665f06bd95/app/plugins/crispVoting/hooks/useCrispServer.ts#L700-L712"
},
{
"title": "WalletConnect analytics disabled",
"url": "https://github.com/theinterfold/the-interfold-governance/blob/28b03a8b529dfa7491f01229724391665f06bd95/app/context/index.tsx#L32"
}
],
"id": "networkObserver",
"value": "Link private",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "Any 10 of the 19 ciphernodes in a vote's committee can combine their key shares and decrypt every ballot of that vote.",
"exposureContinued": "Operators are unnamed, and the lottery limits only each bond-owner address to one seat. The Interfold multisigs can instantly shrink future committees to 3 members, 2 of whom decrypt, and Interfold's hosted app sees the choice before encrypting it.",
"sources": [
{
"title": "Interfold: T + 1 colluding members decrypt individual ballots",
"url": "https://github.com/theinterfold/interfold/blob/c2a28ae6b277aa72a62c34c07142bfadf7c4b4e1/docs/pages/governance.mdx#L244-L245"
},
{
"title": "Committee sizes and decryption thresholds (T + 1)",
"url": "https://github.com/theinterfold/interfold/blob/c2a28ae6b277aa72a62c34c07142bfadf7c4b4e1/packages/interfold-contracts/contracts/lib/ActiveCryptoConfig.sol#L29-L42"
},
{
"contract": "CiphernodeRegistry",
"title": "One seat per bond owner"
},
{
"section": "upgrades-and-governance"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "warning",
"exposureShort": "Archived ballots rest on lattice assumptions with no known quantum attack, so a break adds nothing to what the totals show.",
"exposureContinued": "A recovered wallet key can replace a voter's ballot in an open vote but opens no past one. The contracts that verify ballot proofs are unverified, so whether the proofs hide the vote cannot be checked.",
"exposureShort": "The ballot verifiers are unverified, so whether archived ballot proofs hide the vote from a future break cannot be checked.",
"exposureContinued": "The ballot ciphertexts rest on lattice assumptions with no known quantum attack. A recovered wallet key can replace a voter's ballot in an open vote but opens no past one.",
"sources": [
{
"title": "Key shares are BFV-encrypted and never published",
"url": "https://github.com/theinterfold/interfold/blob/c2a28ae6b277aa72a62c34c07142bfadf7c4b4e1/docs/pages/internals/dkg.mdx#L764-L772"
},
{
"contract": "CrispOnchainBallotVerifier",
"title": "Unverified ballot proof verifier"
}
],
"id": "futureAdversary",
"value": "Link at risk",
"alsoExposed": []
}
}
},
"anonymitySet": {
"type": "not-applicable",
"description": "Every ballot names the address it counts for. Only the choice is hidden, among the voters of the same vote."
},
"attributes": [
{
"id": "fhe",
"label": "FHE",
"description": "Uses fully homomorphic encryption for private computation over encrypted values."
},
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
}
],
"category": {
"id": "secretBallot",
"label": "Secret ballot",
"description": "Voters and their voting power are public, ballots are encrypted and only the tally is decrypted. Hides which option each voter chose."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "A 1-of-1 multisig plugin can upgrade the escrow that holds locked FOLD instantly, and the Interfold multisigs can upgrade the bonding registry instantly.",
"walkawayTest": {
"passed": false,
"reason": "Every ballot needs a signature from Interfold's CRISP server, whose address is fixed in CRISPProgram."
}
},
"referenceClient": {
"name": "Interfold governance app",
"repository": "https://github.com/theinterfold/the-interfold-governance",
"commit": "28b03a8b529dfa7491f01229724391665f06bd95"
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The contracts, ciphernode software, circuits, CRISP server and app are open source. The two contracts that verify ballot proofs are unverified."
},
"riskSummary": "## Funds can be stolen if\n1. the VotingEscrowMultisig upgrades the escrow that holds locked FOLD, which takes effect instantly.\n2. either Interfold multisig upgrades the bonding registry holding bonded FOLD, which takes effect instantly.\n
\n## Privacy can be lost if\n1. 10 of the 19 ciphernodes in a vote's committee combine their key shares (see privileged insider).\n2. the Interfold multisigs shrink the committee of future votes (see privileged insider).\n3. Interfold's hosted app reads the choice before encrypting it (see privileged insider).\n4. one voter's power exceeds the totals of all but one option (see chain analyst).",
"riskSummary": "## Funds can be stolen if\n1. the VotingEscrowMultisig upgrades the escrow that holds locked FOLD, which takes effect instantly.\n2. either Interfold multisig upgrades the bonding registry holding bonded FOLD, which takes effect instantly.\n
\n## Privacy can be lost if\n1. 10 of the 19 ciphernodes in a vote's committee combine their key shares (see privileged insider).\n2. the Interfold multisigs shrink the committee of future votes (see privileged insider).\n3. Interfold's hosted app reads the choice before encrypting it (see privileged insider).\n4. one voter's power exceeds the totals of all but one option (see chain analyst).\n5. the ballot proofs, whose verifiers are unverified, do not hide the vote, so archived ballots reveal choices to a future break (see future adversary).",
"tokens": [],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "InterfoldSafeA (3/5) and InterfoldSafeB (3/5) have the same signers. Through the Admin plugin, either can execute any Interfold DAO action instantly and without a vote. The DAO owns the coordinator, the ciphernode and bonding registries and their proxy admins. The multisigs can therefore upgrade these contracts and change the committee size of future votes. CRISPProgram cannot be upgraded.\n\nDAO proposals pass a CRISP vote of 5 days, then need InterfoldSafeB's approval within 5 days.\n\nVotingEscrowDAO can upgrade the escrow that holds locked FOLD. It executes whatever its 1-of-1 multisig plugin approves. The Interfold DAO can also execute through it."
},
"zkCatalogId": "barretenberg"
}
+5 -0
+5 -0
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which funds leaving Ethereum come back as which, by passing them through Monero between two custodial swaps. Both Ethereum legs are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "The Monero transactions between the deposit into a swap service and the payout from its hot wallet hide sender, recipient and amount.",
"exposureContinued": "Both Ethereum transfers show address, token and amount.",
"advice": "Exit to a new in-app Ethereum wallet made with Create New Recovery Phrase.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": {
"verdict": "exposed",
"note": "Only XMR exists inside. The source asset is public on Ethereum."
},
"linkage": {
"verdict": "atRisk",
"note": "An EVM wallet in Cake has one address, so exiting to the wallet that deposited pays the address that deposited."
}
},
"sources": [
{
"title": "The deposit is a plain transfer from the wallet to the address the service returned",
"url": "https://github.com/cake-tech/cake_wallet/blob/7ce3cd75c3fd0c0add1cead41038ab8806ffebde/lib/view_model/exchange/exchange_trade_view_model.dart#L200-L206"
},
{
"title": "An EVM wallet has a single address",
"url": "https://github.com/cake-tech/cake_wallet/blob/7ce3cd75c3fd0c0add1cead41038ab8806ffebde/cw_evm/lib/evm_chain_wallet_addresses.dart#L11-L38"
},
{
"title": "Every input names 16 ring members",
"url": "https://github.com/monero-project/monero/blob/v0.18.5.1/src/cryptonote_core/blockchain.cpp#L3268"
},
{
"title": "Amounts are encrypted to the recipient",
"url": "https://github.com/monero-project/monero/blob/v0.18.5.1/src/ringct/rctOps.cpp#L672-L720"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "Only amount and timing can pair a deposit into a swap service with a payout from a hot wallet serving every asset the service trades.",
"advice": "Withdraw common amounts rather than everything at once. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "A round trip of similar amount and timing pairs the two Ethereum legs."
}
},
"id": "chainAnalyst",
"value": "Link private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "Built-in Tor sends every call over one shared circuit for up to ten minutes, so only separate app sessions keep the legs apart.",
"exposureContinued": "Moralis receives every Ethereum wallet the app opens, so deposit and exit wallets kept in the app pair up whenever both open close together.",
"advice": "Turn on built-in Tor and restart the app, since the Ethereum client keeps the connection it started with. After the entry, delete the deposit wallet from Cake and restart, so later sessions only see the exit wallet.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "Private only over built-in Tor, with each leg in its own app session."
}
},
"sources": [
{
"title": "Built-in Tor is off unless the user enables it",
"url": "https://github.com/cake-tech/cake_wallet/blob/7ce3cd75c3fd0c0add1cead41038ab8806ffebde/lib/store/settings_store.dart#L1590"
},
{
"title": "Opening a wallet connects its node and sends its address to Moralis",
"url": "https://github.com/cake-tech/cake_wallet/blob/7ce3cd75c3fd0c0add1cead41038ab8806ffebde/lib/reactions/on_current_wallet_change.dart#L94-L113"
},
{
"title": "Embedded Tor config: one SocksPort, no isolation flags",
"url": "https://github.com/cake-tech/cake_wallet/blob/7ce3cd75c3fd0c0add1cead41038ab8806ffebde/cw_core/lib/utils/tor/torch.dart#L65-L70"
},
{
"title": "The Ethereum client binds its proxy setting once",
"url": "https://github.com/cake-tech/cake_wallet/blob/7ce3cd75c3fd0c0add1cead41038ab8806ffebde/cw_evm/lib/clients/evm_chain_client.dart#L24"
}
],
"id": "networkObserver",
"value": "Link at risk",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "Each swap service custodies its leg and can hold the funds until the user passes identity checks, and identities on both legs link them.",
"exposureContinued": "The entry service knows the XMR output it paid the user, and the exit service sees the rings of the transaction that pays it. Together they find that output in the rings behind the exit, and self-transfers only widen the search.",
"interior": {
"sender": {
"verdict": "atRisk",
"note": "Rings that reference the service's payout output point to the spend of the user's XMR."
},
"recipient": "private",
"amount": "private",
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "A service can hold either leg until the user provides identification."
}
},
"sources": [
{
"title": "Breaking Monero: poisoned outputs, the attack by a counterparty on both sides",
"url": "https://www.monerooutreach.org/breaking-monero/poisoned-outputs.html"
},
{
"title": "ChangeNOW: automated AML holds, KYC through SumSub, refund minus fees",
"url": "https://changenow.io/faq/kyc-aml"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "atRisk"
}
]
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "Whoever breaks elliptic-curve cryptography recovers every Monero output key from public chain data, so every ring shows its real spend.",
"exposureContinued": "A known address also yields its view key, and anyone learns a service's address by starting a trade. The user's XMR can then be followed from the entry service to the exit service, where amounts and timing pair it with both Ethereum legs.",
"interior": {
"sender": "exposed",
"recipient": {
"verdict": "atRisk",
"note": "Readable for outputs to known addresses, and the services know the user's address."
},
"amount": {
"verdict": "atRisk",
"note": "Readable for outputs to known addresses."
},
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "A key image is the output key hashed to a point times its private key",
"url": "https://github.com/monero-project/monero/blob/v0.18.5.1/src/crypto/crypto.cpp#L621-L628"
},
{
"title": "Zero to Monero: one-time addresses, amount encryption and key images (chapters 4 to 6)",
"url": "https://www.getmonero.org/library/Zero-to-Monero-2-0-0.pdf"
}
],
"id": "futureAdversary",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "recipient",
"exposure": "atRisk"
},
{
"field": "amount",
"exposure": "atRisk"
}
]
}
}
},
"anonymitySet": {
"type": "not-applicable",
"description": "Each Monero spend hides among the 16 members of its ring, and each self-transfer multiplies the candidates by about 30."
},
"attributes": [
{
"id": "bridged",
"label": "Bridged",
"description": "Funds leave Ethereum through a bridge and gain their privacy on another chain."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "Funds in transit sit with the swap service, which can steal them.",
"walkawayTest": {
"passed": false,
"reason": "Deposit and payout both depend on the swap service. If it stops, funds in transit are lost or refunded at its discretion."
}
},
"referenceClient": {
"name": "Cake Wallet",
"repository": "https://github.com/cake-tech/cake_wallet",
"commit": "7ce3cd75c3fd0c0add1cead41038ab8806ffebde"
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "Cake Wallet and Monero are open source. The swap services run closed systems."
},
"riskSummary": "## Funds can be stolen if\n1. a swap service does not pay out.\n2. a service's hot wallet is compromised during the trade.\n
\n## Funds can be frozen if\n1. a service holds the deposit pending identity verification.\n2. a service refunds minus fees and blacklists the deposit address.\n
\n## Privacy can be lost if\n1. a service holds a leg until the user identifies, since identities on both legs link them (see privileged insider).\n2. one party sees both legs, like one service used twice, and finds its payout in the rings behind the exit (see privileged insider).\n3. swap services, Blink, Etherscan, Moralis, the RPC and the Monero node see the user's IP, since Tor is off by default (see network observer).\n4. elliptic-curve cryptography is broken, which reveals the real spend in every ring (see future adversary).",
"tokens": [],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "Three parties change this swap route, each instantly and offchain since there are no onchain contracts.\n\n### Cake Labs LLC (the wallet)\n\nCake picks the swap services, their defaults and its API keys with each app release. Cake Wallet is MIT-licensed and self-custodial.\n\n### The swap services (the custodians)\n\nEach service sets its own terms, limits and compliance rules and can change them at any time.\n\n### Monero (the chain)\n\nRules change through scheduled hard forks. The mainnet table ends at version 16, active since block 2,689,608 (August 2022), with a ring size of 16."
}
}
+1 -1
+1 -1
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides everything inside the ledger, including which deposits fund a withdrawal. Deposits and withdrawals are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Transfers inside publish only encrypted notes.",
"exposureContinued": "Deposits and withdrawals show address, token and amount. Each epoch pairs every exit with the nullifiers and note shape of the transfer that funded it. Forced withdrawals publish the spent notes and the account, public gift exits the destination.",
"advice": "Exit through the operator's relay.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": {
"verdict": "atRisk",
"note": "Public in gateway DeFi legs."
},
"asset": {
"verdict": "atRisk",
"note": "Public in gateway DeFi legs."
},
"linkage": "private"
},
"sources": [
{
"contract": "PrivacyBoost"
},
{
"title": "Epoch calldata: withdrawals, nullifiers and transfer shapes",
"url": "https://github.com/sunnyside-io/privacy-boost-protocol/blob/5792c139b9529ed80643262d75b5489055be11b0/contracts/src/interfaces/IPrivacyBoost.sol#L828-L852"
},
{
"title": "Forced withdrawal publishes account and notes",
"url": "https://github.com/sunnyside-io/privacy-boost-protocol/blob/5792c139b9529ed80643262d75b5489055be11b0/contracts/src/interfaces/IPrivacyBoost.sol#L582-L591"
},
{
"title": "Public gift exit names the destination",
"url": "https://github.com/sunnyside-io/privacy-boost-protocol/blob/5792c139b9529ed80643262d75b5489055be11b0/contracts/src/interfaces/IPrivacyBoost.sol#L707"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "bad",
"exposureShort": "The anonymity set is very small.",
"exposureContinued": "Most pool activity is one address that keeps depositing and withdrawing 0.001 WETH, which an analyst can filter out.",
"interior": {
"sender": "atRisk",
"recipient": "atRisk",
"amount": {
"verdict": "atRisk",
"note": "Bounded by the public deposit and exit amounts."
},
"asset": "atRisk",
"linkage": {
"verdict": "exposed",
"note": "The set is too small to hide in."
}
},
"sources": [
{
"title": "Address with 0.001 WETH round trips",
"url": "https://basescan.org/address/0xf977237b7d978dde922ee4909619740c73d8a49b"
}
],
"id": "chainAnalyst",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "atRisk"
},
{
"field": "recipient",
"exposure": "atRisk"
}
]
},
"networkObserver": {
"sentiment": "bad",
"exposureShort": "The SDK's core is closed source with no open alternative, so what it sends, and where, is up to the operator and can change with any release.",
"exposureContinued": "Today, anyone on the user's network path sees their wallet deposits and app contacts with the operator, and can match both to the chain. The SDK has no Tor or proxy setting, and the operator's server tells it which endpoints to use.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": {
"verdict": "atRisk",
"note": "Public in gateway DeFi legs."
},
"asset": {
"verdict": "atRisk",
"note": "Public in gateway DeFi legs."
},
"linkage": {
"verdict": "atRisk",
"note": "Private only over Tor, which the SDK lacks."
}
},
"sources": [
{
"title": "Operator endpoint",
"url": "https://base.privacyboost.io/api/v1/info"
},
{
"title": "SDK 1.2.5, configured with one server URL",
"url": "https://www.npmjs.com/package/@sunnyside-io/privacy-boost/v/1.2.5"
},
{
"title": "The compiled core builds and sends every request, its Rust source is unpublished",
"url": "https://www.npmjs.com/package/@sunnyside-io/privacy-boost/v/1.2.5?activeTab=code"
}
],
"id": "networkObserver",
"value": "Link exposed",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "The operator's enclave holds every transfer in plaintext and a key to every note.",
"exposureContinued": "The SDK trusts the enclave key it fetches from the operator's endpoint. Auditors appointed by the admin can pull any account's history without consent.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"contract": "AuditGateway"
},
{
"section": "permissions",
"title": "Admin and operator multisigs"
},
{
"title": "SDK fetches the enclave key from the endpoint",
"url": "https://www.npmjs.com/package/@sunnyside-io/privacy-boost/v/1.2.5"
},
{
"title": "Notes wrap a key for the enclave beside the receiver",
"url": "https://github.com/sunnyside-io/privacy-boost-protocol/blob/5792c139b9529ed80643262d75b5489055be11b0/contracts/src/interfaces/IStructs.sol#L36-L56"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "recipient",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
},
{
"field": "asset",
"exposure": "exposed"
}
]
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "Every note wraps its key to the enclave's long-lived elliptic-curve public key as well as the receiver's.",
"exposureContinued": "Whoever breaks elliptic-curve cryptography decrypts the entire history.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Every output and deposit ciphertext carries an enclave key",
"url": "https://github.com/sunnyside-io/privacy-boost-protocol/blob/5792c139b9529ed80643262d75b5489055be11b0/contracts/src/interfaces/IStructs.sol#L36-L125"
}
],
"id": "futureAdversary",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "recipient",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
},
{
"field": "asset",
"exposure": "exposed"
}
]
}
}
},
"anonymitySet": {
"type": "too-small"
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "tee",
"label": "TEE",
"description": "Privacy assumptions of this project are secured by trusted hardware."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "defi",
"label": "DeFi",
"description": "Interop with DeFi (swaps, vaults) from within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "The admin multisig upgrades the pool and both registries instantly through their ProxyAdmins.",
"walkawayTest": {
"passed": false,
"reason": "Without the TEE operator, deposits and private transfers stop and only forced withdrawals remain."
}
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The circuits are published. The epoch, forced withdrawal and gift claim verification keys deployed in September 2026 remain unreproduced, and the source code of the TEE and of the SDK's compiled core is unpublished."
},
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid spends or withdrawals.\n2. all [trusted setup](#trusted-setups) participants collude or leak their secrets, allowing forged proofs.\n3. the admin multisig deploys a malicious [upgrade](#upgrades-and-governance) or registers a malicious verifying key.\n
\n## Funds can be lost if\n1. a user loses their note secrets, or both the account-owner wallet and every usable authorization key.\n
\n## Privacy can be lost if\n1. the TEE or its hardware vendor is compromised (see privileged insider).\n2. an auditor appointed by the admin multisig fetches the user's history through the Audit API (see privileged insider).\n3. a user exits through a forced withdrawal (see public observer).\n4. a user relies on today's anonymity set, which is too small to hide in (see chain analyst).\n5. the operator changes the SDK's closed-source core to send user data elsewhere, which users cannot check (see network observer).",
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid spends or withdrawals.\n2. all [trusted setup](#trusted-setups) participants collude or leak their secrets, allowing forged proofs.\n3. the admin multisig deploys a malicious [upgrade](#upgrades-and-governance) or registers a malicious verifying key.\n
\n## Funds can be lost if\n1. a user loses their note secrets, or both the account-owner wallet and every usable authorization key.\n
\n## Privacy can be lost if\n1. the TEE or its hardware vendor is compromised (see privileged insider).\n2. an auditor appointed by the admin multisig fetches the user's history through the Audit API (see privileged insider).\n3. a user exits through a forced withdrawal (see public observer).\n4. a user relies on today's anonymity set, which is too small to hide in (see chain analyst).\n5. the operator changes the SDK's closed-source core to send user data elsewhere, which users cannot check (see network observer).\n6. elliptic-curve cryptography is broken, which decrypts every note through the enclave's long-lived public key (see future adversary).",
"tokens": [
{
"token": {
"address": "0x4200000000000000000000000000000000000006",
"iconUrl": "https://coin-images.coingecko.com/coins/images/2518/large/weth.png?1696503332",
"symbol": "WETH",
"decimals": 18,
"priceId": "weth",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-WETH",
"type": "pool",
"label": "WETH",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-USDC",
"type": "pool",
"label": "USDC",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
"iconUrl": "https://coin-images.coingecko.com/coins/images/40143/large/cbbtc.webp?1726136727",
"symbol": "cbBTC",
"decimals": 8,
"priceId": "coinbase-wrapped-btc",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-cbBTC",
"type": "pool",
"label": "cbBTC",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42",
"iconUrl": "https://coin-images.coingecko.com/coins/images/26045/large/euro.png?1696525125",
"symbol": "EURC",
"decimals": 6,
"priceId": "euro-coin",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-EURC",
"type": "pool",
"label": "EURC",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x311935Cd80B76769bF2ecC9D8Ab7635b2139cf82",
"iconUrl": "https://coin-images.coingecko.com/coins/images/4128/large/solana.png?1718769756",
"symbol": "SOL",
"decimals": 9,
"priceId": "solana",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-SOL",
"type": "pool",
"label": "SOL",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
"iconUrl": "https://coin-images.coingecko.com/coins/images/39963/large/usdt.png?1724952731",
"symbol": "USDT",
"decimals": 6,
"priceId": "l2-standard-bridged-usdt-base",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-USDT",
"type": "pool",
"label": "USDT",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x940181a94A35A4569E4529A3CDfB74e38FD98631",
"iconUrl": "https://assets.coingecko.com/coins/images/31745/large/token.png?1696530564",
"symbol": "AERO",
"decimals": 18,
"priceId": "aerodrome-finance",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-AERO",
"type": "pool",
"label": "AERO",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xB2000000000000000000004c27f6523082f41D01",
"iconUrl": "https://coin-images.coingecko.com/coins/images/102175780/large/zi54rndmdx59nblfgry3d1pyckch.?1787558766",
"symbol": "Basecat",
"decimals": 18,
"priceId": "basecat",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-Basecat",
"type": "pool",
"label": "Basecat",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
"iconUrl": "https://coin-images.coingecko.com/coins/images/18834/large/wstETH.png?1696518295",
"symbol": "wstETH",
"decimals": 18,
"priceId": "wrapped-steth",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-wstETH",
"type": "pool",
"label": "wstETH",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xb200000000000000000000C2e324d24d7eEcd1fb",
"iconUrl": "https://coin-images.coingecko.com/coins/images/102175597/large/aapl_200x200.png?1787068801",
"symbol": "AAPLc",
"decimals": 8,
"priceId": "apple-coinbase-tokenized-stock",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-AAPLc",
"type": "pool",
"label": "AAPLc",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xcb585250f852C6c6bf90434AB21A00f02833a4af",
"iconUrl": "https://coin-images.coingecko.com/coins/images/66267/large/Coinbase_Wrapped_XPR_%28cbXRP%29.png?1749023398",
"symbol": "cbXRP",
"decimals": 6,
"priceId": "coinbase-wrapped-xrp",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-cbXRP",
"type": "pool",
"label": "cbXRP",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xAC1Bd2486aAf3B5C0fc3Fd868558b082a531B2B4",
"iconUrl": "https://assets.coingecko.com/coins/images/31126/large/2023-08-11_13.21.24.png?1697025145",
"symbol": "TOSHI",
"decimals": 18,
"priceId": "toshi",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-TOSHI",
"type": "pool",
"label": "TOSHI",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x532f27101965dd16442E59d40670FaF5eBB142E4",
"iconUrl": "https://assets.coingecko.com/coins/images/35529/large/1000050750.png?1709031995",
"symbol": "BRETT",
"decimals": 18,
"priceId": "based-brett",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-BRETT",
"type": "pool",
"label": "BRETT",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xbeeff7aE5E00Aae3Db302e4B0d8C883810a58100",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "bbqUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-bbqUSDC",
"type": "pool",
"label": "bbqUSDC",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x1deEfABEe758AAbdC29a542B24ca3b75aFD56765",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "gtusdcf",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-gtusdcf",
"type": "pool",
"label": "gtusdcf",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0xFeFeC33668E22677c4762d0853d56245a800ff08",
"iconUrl": "https://coin-images.coingecko.com/coins/images/2518/large/weth.png?1696503332",
"symbol": "gtwethb",
"decimals": 18,
"priceId": "weth",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-gtwethb",
"type": "pool",
"label": "gtwethb",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x1D3b1Cd0a0f242d598834b3F2d126dC6bd774657",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "CSUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-CSUSDC",
"type": "pool",
"label": "CSUSDC",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
},
{
"token": {
"address": "0x5435BC53f2C61298167cdB11Cdf0Db2BFa259ca0",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "edgeUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1788377831
},
"buckets": [
{
"id": "privacy-boost-edgeUSDC",
"type": "pool",
"label": "edgeUSDC",
"address": "base:0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40",
"sinceTimestamp": 1788377831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x71A0fD3C76E3E937d8275A3cb6a467b70123bD40"
}
}
}
]
}
],
"trackedOn": [
"base"
],
"upgradesAndGovernance": {
"content": "The 3/4 admin multisig upgrades the pool, registries and AuditGateway instantly. It can replace all five verifiers and their keys, set withdrawal and portal fees up to 10% each, configure portal minimum sweeps, appoint auditors, and change the treasury, operator and gateway route manager.\n\nThe gateway owner manages target and selector policies, picks the guardian and can pause execution. The guardian can pause and remove policies. Stranded gateway tokens return to the pool only while paused."
}
}
+12 -7
+1 -1
"Privacy Pools"
"Privacy Pools v1"
+1 -1
{
"creator": "0xbow",
"projectsForTvs": [
{
"projectId": "privacy-pools",
"sinceTimestamp": 1743265259
}
],
"proofSystemInfo": "",
"techStack": {
"zkVM": [
{
"id": "BN254",
"type": "curve",
"name": "BN254",
"description": "BN254, aka BN256, aka alt_bn128 pairing-friendly 254-bit prime field Weierstrass elliptic curve."
},
{
"id": "Snarkjs",
"type": "Groth16",
"name": "Snarkjs",
"description": "Circom / iden3 implementation of Groth16 proving system written in JS."
}
]
},
"trustedSetups": [
{
"proofSystem": {
"id": "Snarkjs",
"type": "Groth16",
"name": "Snarkjs",
"description": "Circom / iden3 implementation of Groth16 proving system written in JS."
},
"id": "PrivacyPools",
"name": "Privacy Pools",
"name": "Privacy Pools v1",
"risk": "yellow",
"participantCount": 80,
"shortDescription": "Trusted setup for two Groth16 Privacy Pools circuits. It was built on top of 80 phase 1 contributions, with 513 phase 2 participants. Proving system could be broken if either phase 1 or 2 is compromised.",
"longDescription": "Trusted setup for two Groth16 Privacy Pools circuits: the Ragequit circuit and the private Withdrawal circuit.\n\nThis trusted setup ceremony builds on top of the 80th contribution to the [Perpetual Powers of Tau ceremony](https://github.com/privacy-ethereum/perpetualpowersoftau) as phase 1.\n\nPhase 2 of the ceremony was publicly announced, open to anonymous and identified participants, and concluded in March 2025. It contains 514 contributions to the Withdraw circuit and 513 participants to the Ragequit circuit.\nThe finalized zKeys were published for independent verification, and the ceremony code and UI were open-sourced.\n\n- Phase 1 ceremony: .\n- Ceremony completion announcement: [https://0xbow.io/blog/celebrating-the-conclusion-of-the-trusted-setup-ceremony](https://0xbow.io/blog/celebrating-the-conclusion-of-the-trusted-setup-ceremony)\n- Ceremony page with finalized zKeys: [https://ceremony.pse.dev/projects/Privacy%20Pools%20Ceremony](https://ceremony.pse.dev/projects/Privacy%20Pools%20Ceremony)\n- Initial ceremony announcement: [https://0xbow.io/blog/privacy-pools-trusted-setup-ceremony-join-us-in-strengthening-privacy](https://0xbow.io/blog/privacy-pools-trusted-setup-ceremony-join-us-in-strengthening-privacy)\n- Privacy Pools repository: [https://github.com/0xbow-io/privacy-pools-core](https://github.com/0xbow-io/privacy-pools-core)"
}
],
"verifierHashes": [
{
"hash": "Privacy Pools Withdrawal and Ragequit verifiers 03.07.2026",
"name": "Privacy Pools verifiers v1.2.1",
"sourceLink": "https://github.com/0xbow-io/privacy-pools-core/tree/v1.2.1/packages/circuits",
"proofSystem": {
"id": "Snarkjs",
"type": "Groth16",
"name": "Snarkjs",
"description": "Circom / iden3 implementation of Groth16 proving system written in JS."
},
"knownDeployments": [
{
"address": "eth:0xa45ACa8604a73D80C551fAad6355A5c3A5565eC6"
},
{
"address": "eth:0x022891F938Ae7fDC8Ab9Ead0FBf50aBA8C897D6d"
}
],
"verificationStatus": "successful",
"attesters": [
{
"id": "l2beat",
"name": "L2BEAT",
"link": "https://l2beat.com"
}
],
"verificationSteps": "Privacy Pools uses two Groth16 circuits — `commitment` (named `ragequit` in the trusted-setup ceremony) and `withdraw` — whose verification keys are hard-coded in the deployed `CommitmentVerifier.sol` and `WithdrawalVerifier.sol` smart contracts. This regeneration attests that these onchain verification keys correspond to the circuits published in the Privacy Pools repo.\n\nGenerally, to regenerate the two Privacy Pools verification keys, the following has to be done:\n\n1. Checkout the `v1.2.1` tag of the [Privacy Pools core repo](https://github.com/0xbow-io/privacy-pools-core/tree/v1.2.1) (commit hash `a80836a47451e662f127af17e11430ffa976c234`).\n2. Install the repo-pinned toolchain and compile the `.circom` circuit sources into `.r1cs` binaries.\n3. Download the phase 1 trusted setup file `ppot_0080_16.ptau` (Perpetual Powers of Tau contribution #80), which underlies the ceremony final keys.\n4. Verify the checked-in final prover keys (`.zkey`) against the compiled circuits and the phase 1 file. This step also implicitly checks the integrity of the phase 2 trusted setup.\n5. Export verification keys from the final prover keys and make sure they are identical to the checked-in `.vkey` files, whose values are hard-coded in the onchain verifier smart contracts.\n\nHelper scripts that implement the flow above and more detailed explanations could be found in this [script .zip archive](https://trusted-setup-hosting.l2beat.com/privacy/privacy-pools/verification_privacy_pools.zip). This .zip must be extracted in the `privacy-pools-core` dir checked out on tag `v1.2.1` (commit hash `a80836a47451e662f127af17e11430ffa976c234`) before the execution."
}
]
}
+10 -5
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which deposit funds which withdrawal, for deposits the ASP approves. Everything else is public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "A zero-knowledge proof hides which approved deposit a withdrawal spends.",
"exposureContinued": "Partial withdrawals leave a change note and look like full ones.",
"advice": "Exit through a relayer, so none of the user's wallets pay gas for the receiving address. Ragequit only deposits the user never withdrew from, since ragequitting a change note reveals the withdrawal that left it.",
"sources": [
{
"contract": "PrivacyPoolsEntrypoint"
},
{
"title": "Withdrawal circuit",
"url": "https://github.com/0xbow-io/privacy-pools-core/blob/a80836a47451e662f127af17e11430ffa976c234/packages/circuits/circuits/withdraw.circom"
},
{
"contract": "PrivacyPoolETH",
"title": "ragequit: only the depositing address, in public"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "A relayed withdrawal of a common amount hides among all approved deposits of its pool.",
"exposureContinued": "The approved list at any block is public. Any amount is allowed, so an unusual one pairs a deposit with its withdrawal. Paying gas from the user's wallet instead of a relayer exposes its fingerprint, account implementation and fee habits, even from a fresh address.",
"advice": "Use a pool with a large anonymity set. Withdraw common amounts rather than everything at once. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"sources": [
{
"contract": "PrivacyPoolsEntrypoint",
"title": "relay: anyone can relay, the fee comes from the withdrawal"
},
{
"title": "Blockchain Privacy and Regulatory Compliance (design paper)",
"url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4563364"
},
{
"title": "Tutela (arXiv:2201.06811)",
"url": "https://arxiv.org/abs/2201.06811"
}
],
"id": "chainAnalyst",
"value": "Link private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "good",
"exposureShort": "The website works in Tor Browser and scans every pool whole, matching notes locally without revealing the user's deposits to third parties.",
"exposureContinued": "The relayer receives amount and asset for a quote and the recipient once the user confirms. With a wallet sign-in on the default RPC, Alchemy sees the wallet and then the polling for the user's withdrawal, tying the two by timing.",
"advice": "Withdraw in a new Tor Browser session, signed in with the user's recovery phrase so no wallet address is queried. Before signing in, set the user's own node as the Ethereum endpoint.",
"exposureContinued": "The relayer receives amount and asset for a quote and the recipient once the user confirms. The website finds a relayed withdrawal in bulk reads of new blocks, so no request names its hash. A wallet sign-in still shows the RPC the wallet in the session that waits for the withdrawal, which can pair the two by timing on a quiet pool.",
"advice": "Withdraw in a new Tor Browser session, signed in with the user's recovery phrase so no wallet address is queried.",
"sources": [
{
"title": "Sign-in with a recovery phrase needs no wallet",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/providers/AuthProvider.tsx#L39-L47"
},
{
"title": "Pools scanned whole from deployment",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/utils/dataService.ts#L11-L34"
},
{
"title": "A custom endpoint takes over reads and scans",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/config/chainData.ts#L660-L689"
"title": "Relayed withdrawals confirmed without naming the hash",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/utils/relayedReceipt.ts#L1-L44"
},
{
"title": "Recipient sent to the relayer on confirm",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/utils/quotePhases.ts#L4-L43"
}
],
"id": "networkObserver",
"value": "Link private",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "warning",
"exposureShort": "The ASP postman can publish a new approved list at any time with no delay, and withdrawals must prove against the latest one.",
"exposureContinued": "It can deny the user a private exit or publish a list containing only their deposit, reducing their anonymity set to one. The website counts the anonymity set it shows from 0xbow's own feed, not from the list the user's withdrawal proves against. 0xbow can also change the hosted website at any time.",
"advice": "Before withdrawing, check the size of the approved list behind the latest root, which its RootUpdated event links on IPFS. Run an inspected local build of the client instead of the hosted frontend.",
"sources": [
{
"contract": "PrivacyPoolsEntrypoint",
"title": "updateRoot: the postman sets a new root with no delay"
},
{
"contract": "PrivacyPoolETH",
"title": "validWithdrawal: only the latest ASP root is accepted"
},
{
"title": "Displayed anonymity set counted from 0xbow's amount feed",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/hooks/useASP.ts#L63-L75"
},
{
"section": "permissions",
"title": "Privacy Pools Multisig and ASP postman"
}
],
"id": "privilegedInsider",
"value": "Link at risk",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "good",
"exposureShort": "Nothing encrypted is written onchain and commitments are Poseidon hashes, so whoever breaks elliptic-curve cryptography recovers nothing from the chain.",
"exposureContinued": "Accounts created from a wallet signature reduce to that wallet's key.",
"advice": "Create the user's account from a recovery phrase, not from a wallet signature.",
"sources": [
{
"title": "Commitment circuit (Poseidon)",
"url": "https://github.com/0xbow-io/privacy-pools-core/blob/a80836a47451e662f127af17e11430ffa976c234/packages/circuits/circuits/commitment.circom"
},
{
"title": "Wallet-signature seed derivation",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/utils/walletSeed.ts#L40-L73"
},
{
"title": "Random recovery phrase option",
"url": "https://github.com/0xbow-io/privacy-pools-website/blob/7df411128f7a18a61a77f7a0371bf0b857969e2a/src/utils/seedPhrase.ts#L3-L7"
},
{
"section": "trusted-setups"
}
],
"id": "futureAdversary",
"value": "Link private",
"alsoExposed": []
}
}
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "pool",
"label": "Pool",
"description": "Funds enter a shared pool and leave it later, with no actions inside. Hides which deposit became which withdrawal."
},
"exitWindow": {
"value": "Infinite",
"sentiment": "good",
"orderHint": 9007199254740991,
"description": "The depositing address can always ragequit its funds from the immutable pools, without the Entrypoint or the ASP. A ragequit is public.",
"walkawayTest": {
"passed": false,
"reason": "Private withdrawals need the ASP to approve each deposit and keep posting roots."
}
},
"referenceClient": {
"name": "privacypools.com",
"repository": "https://github.com/0xbow-io/privacy-pools-website",
"commit": "7df411128f7a18a61a77f7a0371bf0b857969e2a"
},
"relayerTracking": {
"type": "onchainEvents",
"sources": [
{
"address": "eth:0x6818809EefCe719E480a7526D76bD3e561526b46",
"sinceTimestamp": 1743265247,
"extractor": "privacyPoolsWithdrawalRelayed"
}
]
},
"reproducibility": {
"value": "Reproducible",
"sentiment": "good",
"description": "The contracts, circuits, SDK, relayer and website are open source and build locally. The ASP service is closed."
},
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid withdrawals.\n2. the [trusted setup](#trusted-setups) is compromised or all ceremony participants collude, allowing invalid withdrawals.\n3. the Entrypoint owner deploys a malicious [upgrade](#upgrades-and-governance) that steals new deposits or withdrawals relayed after it.\n
\n## Funds can be lost if\n1. a user loses the recovery phrase that their notes derive from.\n
\n## Privacy can be lost if\n1. the ASP leaves deposits out of its latest list, which blocks their private exit, up to halting all private withdrawals (see privileged insider).\n2. the ASP keeps only a few deposits in its latest list, so withdrawals proven against it point to one of them (see privileged insider).\n3. both relayers on the website refuse a withdrawal, so the user must self-relay or find a relayer elsewhere (see chain analyst).\n4. a user withdraws signed in with a wallet on the default RPC, so Alchemy ties the wallet to the withdrawal by timing (see network observer).",
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid withdrawals.\n2. all [trusted setup](#trusted-setups) participants collude or leak their secrets, allowing forged proofs.\n3. the Entrypoint owner deploys a malicious [upgrade](#upgrades-and-governance) that steals new deposits or withdrawals relayed after it.\n
\n## Funds can be lost if\n1. a user loses the recovery phrase that their notes derive from.\n
\n## Privacy can be lost if\n1. the ASP leaves deposits out of its latest list, which blocks their private exit, up to halting all private withdrawals (see privileged insider).\n2. the ASP keeps only a few deposits in its latest list, so withdrawals proven against it point to one of them (see privileged insider).\n3. both relayers on the website refuse a withdrawal, so the user must self-relay or find a relayer elsewhere (see chain analyst).\n4. a user withdraws signed in with a wallet on the default RPC, so Alchemy ties the wallet to the withdrawal by timing (see network observer).",
"tokens": [
{
"token": {
"address": "0x6440f144b7e50D6a8439336510312d2F54beB01D",
"iconUrl": "https://coin-images.coingecko.com/coins/images/56069/large/BOLD_logo.png?1748265087",
"symbol": "BOLD",
"decimals": 18,
"priceId": "liquity-bold-2",
"sinceTimestamp": 1770806867
},
"buckets": [
{
"id": "privacy-pools-BOLD",
"type": "pool",
"label": "BOLD pool",
"address": "eth:0xb4b5Fd38Fd4788071d7287e3cB52948e0d10b23E",
"sinceTimestamp": 1770806867,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"iconUrl": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
"symbol": "DAI",
"decimals": 18,
"priceId": "dai",
"sinceTimestamp": 1752848471
},
"buckets": [
{
"id": "privacy-pools-DAI",
"type": "pool",
"label": "DAI pool",
"address": "eth:0x1c31C03B8CB2EE674D0F11De77135536db828257",
"sinceTimestamp": 1752848471,
"anonymitySet": {
"minimumAmounts": [
"200000000000000000000",
"20000000000000000000000"
]
},
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"symbol": "ETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1743265259
},
"buckets": [
{
"id": "privacy-pools-ETH",
"type": "pool",
"label": "ETH pool",
"address": "eth:0xF241d57C6DebAe225c0F2e6eA1529373C9A9C9fB",
"sinceTimestamp": 1743265259,
"anonymitySet": {
"minimumAmounts": [
"100000000000000000",
"10000000000000000000"
]
},
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xCAcd6fd266aF91b8AeD52aCCc382b4e165586E29",
"iconUrl": "https://coin-images.coingecko.com/coins/images/53963/large/frxUSD.png?1737792154",
"symbol": "frxUSD",
"decimals": 18,
"priceId": "frax-usd",
"sinceTimestamp": 1754583623
},
"buckets": [
{
"id": "privacy-pools-frxUSD",
"type": "pool",
"label": "frxUSD pool",
"address": "eth:0xC6C769fac7AABEadd31a03fAe5Ca0Ec5B4C50f84",
"sinceTimestamp": 1754583623,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0x085780639CC2cACd35E474e71f4d000e2405d8f6",
"iconUrl": "https://coin-images.coingecko.com/coins/images/36202/large/fxUSD.jpg?1710833113",
"symbol": "fxUSD",
"decimals": 18,
"priceId": "f-x-protocol-fxusd",
"sinceTimestamp": 1765446455
},
"buckets": [
{
"id": "privacy-pools-fxUSD",
"type": "pool",
"label": "fxUSD pool",
"address": "eth:0xD14F4B36E1D1D98c218db782c49149876042BC56",
"sinceTimestamp": 1765446455,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xa3931d71877C0E7a3148CB7Eb4463524FEc27fbD",
"iconUrl": "https://coin-images.coingecko.com/coins/images/52721/large/sUSDS_Coin.png?1734086971",
"symbol": "sUSDS",
"decimals": 18,
"priceId": "susds",
"sinceTimestamp": 1752782999
},
"buckets": [
{
"id": "privacy-pools-sUSDS",
"type": "pool",
"label": "sUSDS pool",
"address": "eth:0xBBdA2173CDFEA1c3bD7F2908798F1265301d750c",
"sinceTimestamp": 1752782999,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d",
"iconUrl": "https://coin-images.coingecko.com/coins/images/54977/large/USD1_1000x1000_transparent.png?1749297002",
"symbol": "USD1",
"decimals": 18,
"priceId": "usd1-wlfi",
"sinceTimestamp": 1754583179
},
"buckets": [
{
"id": "privacy-pools-USD1",
"type": "pool",
"label": "USD1 pool",
"address": "eth:0xc0A8Bc0F4F982b4d4f1fFae8F4FCCb58c9B29c98",
"sinceTimestamp": 1754583179,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1753353035
},
"buckets": [
{
"id": "privacy-pools-USDC",
"type": "pool",
"label": "USDC pool",
"address": "eth:0xb419c2867aB3CBc78921660cB95150d95A94ce86",
"sinceTimestamp": 1753353035,
"anonymitySet": {
"minimumAmounts": [
"200000000",
"20000000000"
]
},
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3",
"iconUrl": "https://assets.coingecko.com/coins/images/33613/large/3466ef_3c088c66c7d941e8856339d0bddf33cc_mv2.png?1702514458",
"symbol": "USDe",
"decimals": 18,
"priceId": "ethena-usde",
"sinceTimestamp": 1754583083
},
"buckets": [
{
"id": "privacy-pools-USDe",
"type": "pool",
"label": "USDe pool",
"address": "eth:0xe6D36B33b00A7C0cB0C2a8d39D07e7dB0c526Abc",
"sinceTimestamp": 1754583083,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xdC035D45d973E3EC169d2276DDab16f1e407384F",
"iconUrl": "https://coin-images.coingecko.com/coins/images/39926/large/usds.webp?1726666683",
"symbol": "USDS",
"decimals": 18,
"priceId": "usds",
"sinceTimestamp": 1752503003
},
"buckets": [
{
"id": "privacy-pools-USDS",
"type": "pool",
"label": "USDS pool",
"address": "eth:0x05e4DBD71B56861eeD2Aaa12d00A797F04B5D3c0",
"sinceTimestamp": 1752503003,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"iconUrl": "https://assets.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "USDT",
"decimals": 6,
"priceId": "tether",
"sinceTimestamp": 1753352915
},
"buckets": [
{
"id": "privacy-pools-USDT",
"type": "pool",
"label": "USDT pool",
"address": "eth:0xe859C0bD25f260BaEE534Fb52e307D3b64D24572",
"sinceTimestamp": 1753352915,
"anonymitySet": {
"minimumAmounts": [
"200000000",
"20000000000"
]
},
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
"iconUrl": "https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png?1696507857",
"symbol": "WBTC",
"decimals": 8,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1753975703
},
"buckets": [
{
"id": "privacy-pools-WBTC",
"type": "pool",
"label": "WBTC pool",
"address": "eth:0xF973f4B180A568157Cd7A0E6006449139E6Bfc32",
"sinceTimestamp": 1753975703,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0xDcEe70654261AF21C44c093C300eD3Bb97b78192",
"iconUrl": "https://coin-images.coingecko.com/coins/images/29734/large/woeth-200x200.png?1714796686",
"symbol": "wOETH",
"decimals": 18,
"priceId": "wrapped-oeth",
"sinceTimestamp": 1756377743
},
"buckets": [
{
"id": "privacy-pools-wOETH",
"type": "pool",
"label": "wOETH pool",
"address": "eth:0x7d2959bCFb936a84531518e8391DdBa844e03ebE",
"sinceTimestamp": 1756377743,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
},
{
"token": {
"address": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
"iconUrl": "https://assets.coingecko.com/coins/images/18834/large/wstETH.png?1696518295",
"symbol": "wstETH",
"decimals": 18,
"priceId": "wrapped-steth",
"sinceTimestamp": 1753975583
},
"buckets": [
{
"id": "privacy-pools-wstETH",
"type": "pool",
"label": "wstETH pool",
"address": "eth:0x1A604E9DFa0EFDC7FFda378AF16Cb81243b61633",
"sinceTimestamp": 1753975583,
"deposit": {
"event": "0xe3b53cd1a44fbf11535e145d80b8ef1ed6d57a73bf5daa7e939b6b01657d6549",
"extractor": "privacyPoolsValue",
"params": {}
},
"withdrawal": {
"event": "0x75e161b3e824b114fc1a33274bd7091918dd4e639cede50b78b15a4eea956a21",
"extractor": "privacyPoolsValue",
"params": {}
}
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "The 2/4 Privacy Pools Multisig holds the Entrypoint's owner role. It can upgrade the Entrypoint, register, configure and wind down pools, set fees and withdraw the vetting fees, all without delay. It also appoints the ASP postmen, who post the approved roots. The pools and verifiers are immutable. Relayed withdrawals and new deposits pass through the Entrypoint, so a malicious upgrade can steal them. Ragequit works without the Entrypoint, so funds already in the pools can always leave to their depositing addresses."
}
}
[ADDED]
privacy-pools-v2
+1691 -0
+1 -0
"privacy-pools-v2"
+1 -0
"privacy-pools-v2"
+1 -0
"Privacy Pools v2"
+1 -0
null
+1 -0
null
+1 -0
1792454400
+6 -0
{
"unverifiedContracts": [
"eth:0xd0395c08DD8eA7671a7A65bDca8E473e8E8260a8"
],
"yellowWarning": "Privacy Pools v2 opened to the public on 2026-10-20 after a capped beta. We are still early, so the ratings rest on the design and ignore the small anonymity set."
}
+17 -0
{
"badges": [],
"description": "A shielded ledger with private transfers, swaps and Aave yield inside the pool, where only deposits the ASP approves can be spent privately.",
"detailedDescription": "Privacy Pools v2 by 0xbow lets you shield ETH, USDC or USDT in one pool, then send, swap, earn Aave yield and withdraw without a visible link to the deposit. Only deposits that 0xbow's association set provider (ASP) approves can be spent privately. Depositors, recipients, amounts and timing at the pool's edges stay public.\n\nUsers trust 0xbow, which runs the ASP, the only relayer and the website, and one key that can upgrade every core contract without delay. The ASP can withhold or revoke approval for any deposit. Exiting is permissionless: a note's owner can always ragequit it from the vault, losing their privacy.\n\n### Architecture\n\nA note is a private record of value in one asset, owned by an Ethereum address and carrying the label of its deposit. The PoolVault holds all assets and a state tree of note commitments and spent nullifiers. The Keystore holds each account's registration: a hash of its nullifying key, its auth policy and an X25519 viewing public key. The ASPRegistry holds the latest root of the approved labels. USDC, USDT and ETH enter as yield shares, ppUSDC, ppUSDT and ppETH, which wrap Aave v3 deposits.\n\n### Labels\n\nEach deposit gets a label, a private ID that only the depositor and the ASP can tie to the deposit. Every note created from the deposit's funds carries the same label, including notes paid to others, so each recipient learns it. Notes from different deposits never merge. Each private spend proves that its notes' labels are on the ASP's latest list. Anyone who knows a label can hash it, find the list update that first approved it and look at the deposits made just before.\n\n### Flow\n\n1. **Register.** Two transactions from your wallet add your account to the Keystore and publish your viewing public key.\n2. **Shield.** You deposit through the Entrypoint. USDC, USDT and ETH pass through a PPRouter that supplies Aave and deposits the shares. Your address, asset and amount are public, and the data that ties the deposit to its label goes onchain encrypted to the ASP.\n3. **Approval.** The ASP screens the depositor, adds the label's hash to its list and posts the root onchain, with the list on IPFS.\n4. **Send.** A transact proof spends your notes and creates one for the recipient, encrypted to their viewing key and published onchain, plus change for you. An unregistered recipient gets a claim link instead. 0xbow's relayer submits the proof onchain and takes its fee as a public withdrawal.\n5. **Withdraw.** The relayer pays any address, minus its fee. Change stays as a note.\n\n### Keys\n\nAll keys derive from one signature of the user's wallet. Contract wallets and signers that cannot sign the same way twice can use a passkey instead. The derived account key can be exported from the app. Sharing the viewing private key reveals every incoming note, a receipt reveals one payment. The revocable key can be rotated, and the old one stays valid for 20m.\n\n### App\n\nThe ratings assume the website at [privacypools.com](https://privacypools.com), built from [public source](https://github.com/0xbow-io/privacy-pools-website-v2) and hosted by 0xbow. It reads the chain from Alchemy under 0xbow's key unless the user sets an endpoint per chain. It downloads the pool's events whole from the ASP but offers only 0xbow's relayer. Its Tor option requires a user-run Tor gateway and covers only RPC calls. It does not support connecting a local node with Tor enabled. Privacy Pools v2 is deployed on BNB Chain, Citrea, Optimism, Base, Arbitrum and Robinhood Chain, which L2BEAT does not track.\n\n### Swaps and yield\n\nThe yield shares keep a fixed share count while their value grows, so the share count encodes the exchange rate on the deposit day. Withdraw-and-swap sends the withdrawn asset through LI.FI to another token or chain, with the route bound into the proof. A reshield swaps into another pool asset and deposits again in the same transaction, as a fresh deposit that needs approval again.\n\n### Exits\n\n**Ragequit.** The note's current owner can take out its full value at any time, approved or not, directly from the vault, also while it is paused. It publishes the owner, the amount, the label and the commitment, which names the transaction that created the note.\n\n**Claim link.** A payment to an unregistered address can only be claimed with the link the payer holds. Until then the funds can neither move nor exit.\n\n**Relaying.** The contracts accept a proof from any address, and no relayer can change its recipient. A relayer other than 0xbow's needs the user's own build of the website or another client.\n\n### Compliance\n\nThe ASP screens each depositor before approving the deposit, under 0xbow's own due diligence, and may reject it. A later list can drop an approved label, which freezes every note that carries it. A rejected deposit can leave only by ragequit.\n\n### Fees\n\nDeposits pay no vetting fee today. The relayer quotes its fee per request and takes it from the sent or withdrawn asset. You accept the fee before sending, and the relayer cannot raise it. A private transfer pays that fee as a public payout from the vault. The yield shares keep 20% of the Aave yield for 0xbow.\n\n### Anonymity set\n\nOne vault holds every asset, but a withdrawal names its asset. The set is therefore the ASP-approved deposits of that asset whose notes still hold at least the withdrawn amount, including the notes that transfers and reshields created from them. We count every depositor of the asset, approved or not.",
"links": {
"websites": [
"https://privacypools.com"
],
"documentation": [
"https://privacy-pools-v2-docs.vercel.app"
],
"repositories": [
"https://github.com/0xbow-io/privacy-pools-v2-monorepo",
"https://github.com/0xbow-io/privacy-pools-website-v2"
]
}
}
+1 -0
null
+1 -0
null
+23 -0
[
{
"title": "Privacy Pools v2 public launch",
"url": "https://github.com/0xbow-io/privacy-pools-website-v2/releases/tag/v1.0.0",
"date": "2026-10-20T00:00:00Z",
"description": "The v2 app opens at privacypools.com with transfers, swaps and yield inside the pool.",
"type": "general"
},
{
"title": "Beta verifiers used single-contributor keys",
"url": "https://github.com/0xbow-io/privacy-pools-v2-monorepo/blob/61fac03acd1fc306164ddc234f7fac4147d04493/CHANGELOG.md",
"date": "2026-10-20T00:00:00Z",
"description": "From 2026-09-01 until this rotation, every verifier held a developer key, not the ceremony key.",
"type": "incident"
},
{
"title": "Mainnet beta with a $100 deposit cap",
"url": "https://github.com/0xbow-io/privacy-pools-website/pull/232",
"date": "2026-09-03T00:00:00Z",
"description": "The production contracts take their first deposits, capped at $100 each by the ASP and the app.",
"type": "general"
}
]
+1 -0
null
+15 -0
[
{
"address": "0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"chain": "ethereum",
"sinceTimestamp": 1788287903,
"tokens": [
"ETH",
"USDC",
"ppUSDC",
"ppUSDT",
"ppETH"
],
"chainId": 1
}
]
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+147 -0
{
"creator": "0xbow",
"projectsForTvs": [
{
"projectId": "privacy-pools-v2",
"sinceTimestamp": 1788287903
}
],
"proofSystemInfo": "",
"techStack": {
"zkVM": [
{
"id": "BN254",
"type": "curve",
"name": "BN254",
"description": "BN254, aka BN256, aka alt_bn128 pairing-friendly 254-bit prime field Weierstrass elliptic curve."
},
{
"id": "Snarkjs",
"type": "Groth16",
"name": "Snarkjs",
"description": "Circom / iden3 implementation of Groth16 proving system written in JS."
}
]
},
"trustedSetups": [
{
"proofSystem": {
"id": "Snarkjs",
"type": "Groth16",
"name": "Snarkjs",
"description": "Circom / iden3 implementation of Groth16 proving system written in JS."
},
"id": "PrivacyPoolsV2",
"name": "Privacy Pools v2",
"risk": "yellow",
"participantCount": 80,
"shortDescription": "Trusted setup for the 27 Groth16 Privacy Pools v2 circuits. It was built on top of 80 phase 1 contributions, with 500 phase 2 contributions per circuit from 597 participants and a RANDAO beacon. Proving system could be broken if either phase 1 or 2 is compromised.",
"longDescription": "Trusted setup for the 27 Groth16 Privacy Pools v2 circuits: deposit, ragequit and 25 transact circuits, one per combination of 1 to 5 spent notes and 1 to 5 created notes.\n\nPhase 1 is the 80th contribution to the [Perpetual Powers of Tau ceremony](https://github.com/privacy-ethereum/perpetualpowersoftau), prepared for 2^18 constraints.\n\nPhase 2, named ppv2-ceremony, ran publicly from 2026-07-08 to 2026-07-14 with 500 contributions per circuit from 597 distinct participants, followed by one beacon contribution from the RANDAO reveal of beacon-chain slot 14767039. Participants are pseudonymous in the published transcript. The final proving keys, their verification keys and the transcript are published with release v1.0.0 of the monorepo, and the ceremony code is open source.\n\n- Phase 1 ceremony: .\n- Ceremony code and UI: .\n- Ceremony description and key hashes: .\n- Final keys and transcript: ."
}
],
"verifierHashes": [
{
"hash": "Privacy Pools v2 verifiers 20.10.2026",
"name": "Privacy Pools v2 verifiers v1.0.1",
"sourceLink": "https://github.com/0xbow-io/privacy-pools-v2-monorepo/tree/61fac03acd1fc306164ddc234f7fac4147d04493/packages/circuits",
"proofSystem": {
"id": "Snarkjs",
"type": "Groth16",
"name": "Snarkjs",
"description": "Circom / iden3 implementation of Groth16 proving system written in JS."
},
"knownDeployments": [
{
"address": "eth:0xEe96Ca04d2Ab2eC9A8803eb78F39b2875dFF6fdf"
},
{
"address": "eth:0x5a06582115953E2cAbeD8e6A0EeAE35BA430118f"
},
{
"address": "eth:0x21347145497569b34efAB7d73952208866520042"
},
{
"address": "eth:0x0e13d94235d8a0d8f9fC3B63BB41D666eF0677Ed"
},
{
"address": "eth:0xC5E1D9D9CF12E796Ec8E072646c6BF29A1e55382"
},
{
"address": "eth:0x3ee4A00e0ba1AC0Ef8aD3e4b541CA42FBB4592c3"
},
{
"address": "eth:0xfa0138C5dE45E520AbA349BE38a827DAb470f70A"
},
{
"address": "eth:0x338625F2199675D2aC4Fbf7A89567864ac990710"
},
{
"address": "eth:0xAc716f21626994c4264eA457Fe208071050611B5"
},
{
"address": "eth:0xB8aa00333b8D6958da72A15D59179BbDD1e49064"
},
{
"address": "eth:0xF1C6c55B70EC3Df923f5E9bcd64aee5c3073C42c"
},
{
"address": "eth:0x62Cf8963300F284016daE0cD19f5D9BC60846a46"
},
{
"address": "eth:0x579f6734d35937b8432BA8FfC17C3120eb657c82"
},
{
"address": "eth:0x76D574559765fd4b90903fFa682964Ae7e7e878a"
},
{
"address": "eth:0xAeCDf3E27A602f23cEc2E5CE250093b3E806D041"
},
{
"address": "eth:0xe0aec1eE10eBfCDcB09b6e5a7ea6Ae34D066219d"
},
{
"address": "eth:0xFdF4EbC7645E1F4c04aE33285b6e3f78e4A3a275"
},
{
"address": "eth:0x909ECAF2A4959726a2BC3d82Fc837B8D3F1c61d3"
},
{
"address": "eth:0x454F1Da26DD4c7c89a849019BeC4c7C7C404d3A4"
},
{
"address": "eth:0x95dEC97ac78E8C0FfDc6315FDc0A0791238b93A3"
},
{
"address": "eth:0x4Cb752CEF56a5095321Ed72699cD7A699D48F4b5"
},
{
"address": "eth:0x01b4954E3b3C1F68785f60D7465c38C31266bfab"
},
{
"address": "eth:0x61573Cf3c3A20C9739b68B8e742Ca51971387Cb5"
},
{
"address": "eth:0x8ABfb288dAc87392EaFdD59F6809825fcA0e8b85"
},
{
"address": "eth:0x20D4B794A2A1ae7A34AF184172dd931d3ff2Fa32"
},
{
"address": "eth:0x766c2F31483935CD55355fcE00fc5eDB82A15acC"
},
{
"address": "eth:0x7BeE2554970A749D7671424DFa3fAbE15d7e4BD8"
}
],
"verificationStatus": "successful",
"attesters": [
{
"id": "l2beat",
"name": "L2BEAT",
"link": "https://l2beat.com"
}
],
"verificationSteps": "Privacy Pools v2 uses 27 Groth16 circuits: `deposit`, `ragequit` and `transact_NxM` for 1 to 5 spent notes (N) and 1 to 5 created notes (M). The PoolVault holds the deposit and ragequit verifier addresses and routes each transact proof to the verifier registered for its (N, M). Each verifier contract hard-codes its verification key. The steps below tie the deployed bytecode to the published circuit sources and ceremony keys.\n\nSteps, all on monorepo tag `v1.0.2` (commit `61fac03acd1fc306164ddc234f7fac4147d04493`), whose circuit sources, `.r1cs` files and keys are those of release `v1.0.0`:\n\n1. Compile every main circuit under `packages/circuits/circuits/main` with circom 2.2.3, `--O1`, circomlib 2.0.5 and `@zk-kit/binary-merkle-root.circom` 2.0.0, the toolchain `circomkit.json` and `package.json` pin. The sha256 of each produced `.r1cs` equals the committed `packages/circuits/build//.r1cs` (Git LFS).\n2. Download the circuit tarballs and `transcript.json` of release `v1.0.0` and check them against `circuits-v1.0.0-SHA256SUMS.txt`. The sha256 of each `groth16_pkey.zkey` equals the hash in `packages/circuits/CEREMONY.md` and the transcript's `finalZkeyHash`.\n3. Download the phase 1 file `ppot_0080_18.ptau` (Perpetual Powers of Tau contribution 80, sha256 `9693220206afab749e3d88d4ab5fdf5d36120ea102e7e587ccea0e7a5208e711`).\n4. Run `snarkjs zkey verify .r1cs ppot_0080_18.ptau .zkey` (snarkjs 0.7.5) for all 27 circuits. Each key verifies with 500 contributions and the beacon contribution 501. For `deposit`, the 500 contribution hashes equal the transcript's `serverContributionHash` values in order and contribution 501 equals its `finalContributionHash`.\n5. Read the runtime bytecode of the 27 verifiers the PoolVault names at block 26235496 and check that every coordinate of `vk_alpha_1`, `vk_beta_2`, `vk_gamma_2`, `vk_delta_2` and `IC` in the committed `groth16_vkey.json` appears in it as a PUSH constant (values with leading zero bytes use shorter pushes). All 27 match.\n6. Build `packages/contracts/src/verifiers/VerifierArtifacts.sol` with `forge build` under `packages/contracts/foundry.toml` (solc 0.8.32, via-IR, 10,000 optimizer runs, EVM version prague). The runtime bytecode of each verifier equals the deployed one, metadata hash included."
}
]
}
+1 -0
null
+541 -0
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which deposit funds which withdrawal and who pays whom inside the pool, for deposits the ASP approves. Deposits and withdrawals are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "A zero-knowledge proof hides which approved notes a withdrawal or transfer spends, and a transfer publishes only encrypted notes.",
"exposureContinued": "A relayed transfer pays its fee as a public withdrawal to the relayer, so transfers are visible as events. A ragequit publishes the owner, the amount, the label and the commitment, which names the transaction that created the note. Claiming a payment to an unregistered address registers that wallet.",
"advice": "Exit through a relayer, so none of your wallets pay gas for the receiving address. Ragequit only notes you deposited and never spent from. On any other note, a ragequit names the private transaction that created it.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "private",
"linkage": {
"verdict": "atRisk",
"note": "A ragequit names the transaction that created the note."
}
},
"sources": [
{
"contract": "PoolVault"
},
{
"title": "Transact circuit",
"url": "https://github.com/0xbow-io/privacy-pools-v2-monorepo/blob/61fac03acd1fc306164ddc234f7fac4147d04493/packages/circuits/circuits/templates/Transact.circom"
},
{
"title": "Relayed transfers pay the fee as a public output",
"url": "https://privacy-pools-v2-docs.vercel.app/operations/transfer"
},
{
"title": "Ragequit publishes the label and owner",
"url": "https://privacy-pools-v2-docs.vercel.app/operations/ragequit"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "warning",
"exposureShort": "A note's label passes to every later payee, and the ASP update that first approved it often leaves one candidate deposit.",
"exposureContinued": "The ASP adds ten labels per update, decoys included, so an update that follows a single deposit names it. Without a payee, a relayed exit of a common amount hides among every approved deposit of its asset. Any amount is allowed, so an unusual one pairs a deposit with its withdrawal, and a yield deposit's share count encodes the day it was made. Paying gas from the user's wallet instead of a relayer exposes its fingerprint, account implementation and fee habits, even from a fresh address.",
"advice": "Reshield into another asset before paying someone who should not learn the deposit, since the reshield deposits the funds again under a new label. Use a pool with a large anonymity set. Withdraw common amounts rather than everything at once. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "private",
"linkage": {
"verdict": "atRisk",
"note": "A received note's label, an unusual amount or a share count only one deposit day produces can pair the two ends."
}
},
"sources": [
{
"title": "Every output note inherits the label of an input",
"url": "https://github.com/0xbow-io/privacy-pools-v2-monorepo/blob/61fac03acd1fc306164ddc234f7fac4147d04493/packages/circuits/circuits/templates/helpers/ValueConservation.circom"
},
{
"contract": "ASPRegistry",
"title": "Each root update links its list on IPFS"
},
{
"title": "Share counts encode the exchange rate at deposit",
"url": "https://privacy-pools-v2-docs.vercel.app/concepts/yield-shares"
},
{
"title": "Tutela (arXiv:2201.06811)",
"url": "https://arxiv.org/abs/2201.06811"
}
],
"id": "chainAnalyst",
"value": "Link at risk",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "The default RPCs, Alchemy under 0xbow's key with a public node as fallback, see the account at sign-in and can time it against the withdrawal.",
"exposureContinued": "Network services like the LI.FI swap service and Sentry error reporting receive your IP address unless the app is used over Tor or a VPN, while the Tor mode is not compatible with a local Ethereum node. The app confirms a relayed withdrawal from bulk reads, so no request names it, and the pairing rests on timing, which Tor does not hide. The app downloads the pool's events whole from the ASP and matches notes locally. The relayer learns the recipient at quote time. Tor Browser works, but the relayer refuses many Tor exits and the app offers no other relayer.",
"advice": "Set your own node, served over https, as the endpoint for the chain before signing in. Withdraw in a new Tor Browser session signed in with your account key, so no wallet is connected, and retry on a new circuit when the relayer refuses.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "private",
"linkage": {
"verdict": "atRisk",
"note": "Private only from an own node, with a new Tor Browser session for the exit."
}
},
"sources": [
{
"title": "Alchemy first, public node last",
"url": "https://github.com/0xbow-io/privacy-pools-website-v2/blob/bfb752cdf7c0659bb4fd25e97933e04fce844c4a/config/rpc-order.ts#L55-L70"
},
{
"title": "Allowlist refuses per-note reads and topic filters",
"url": "https://github.com/0xbow-io/privacy-pools-website-v2/blob/bfb752cdf7c0659bb4fd25e97933e04fce844c4a/services/egress-policy.ts#L447-L520"
},
{
"title": "The receive quote carries the recipient",
"url": "https://github.com/0xbow-io/privacy-pools-website-v2/blob/bfb752cdf7c0659bb4fd25e97933e04fce844c4a/services/egress-policy.ts#L606-L617"
},
{
"title": "Tor needs a gateway the user runs",
"url": "https://github.com/0xbow-io/privacy-pools-website-v2/blob/bfb752cdf7c0659bb4fd25e97933e04fce844c4a/config/tor.ts#L1-L50"
}
],
"id": "networkObserver",
"value": "Link at risk",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "warning",
"exposureShort": "The ASP postman can publish a new approved list at any time with no delay, and every private spend must prove against the latest one.",
"exposureContinued": "A list without a deposit's label freezes every note descending from it, and a list with few labels narrows the set to them. 0xbow's relayer sees the IP and recipient of every private exit and its ASP feeds see the IP of every session, so one operator can pair a deposit session with its withdrawal. The request logs of its Alchemy key show it the account each sign-in looks up, which it can time against the withdrawals its relayer submits. One key holds every admin role and can upgrade the four core contracts without delay.",
"advice": "Before withdrawing, check the size of the approved list behind the latest root, which the ASPRegistry links on IPFS. Exit as the network observer advice says, so 0xbow sees no IP it saw at the deposit and no account lookup.",
"interior": {
"sender": "private",
"recipient": {
"verdict": "atRisk",
"note": "The relayer sees the recipient of every exit, with the IP that asked."
},
"amount": "private",
"asset": "private",
"linkage": {
"verdict": "atRisk",
"note": "The ASP can narrow the approved list, and 0xbow can pair sessions across ASP, relayer and its Alchemy logs."
}
},
"sources": [
{
"contract": "ASPRegistry",
"title": "updateASPRoot: the postman sets a new root with no delay"
},
{
"contract": "PoolVault",
"title": "transact: only the latest ASP root is accepted"
},
{
"title": "What the relayer receives, the IP included",
"url": "https://privacy-pools-v2-docs.vercel.app/introduction/threat-model"
},
{
"title": "Alchemy request logs show the key owner each payload",
"url": "https://www.alchemy.com/docs/alchemy-request-logs"
}
],
"id": "privilegedInsider",
"value": "Link at risk",
"alsoExposed": [
{
"field": "recipient",
"exposure": "atRisk"
}
]
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "Every registered account's viewing public key sits in the Keystore, so whoever breaks elliptic-curve cryptography decrypts every note ever sent to it from the chain.",
"exposureContinued": "A decrypted note holds value, token and deposit lineage, which pairs each transfer's commitments with their deposit and recipient. Accounts created from a wallet signature reduce to that wallet's key. Breaking the ASP's key the same way decrypts the data that ties each deposit to its label.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"contract": "Keystore",
"title": "viewingKeys: X25519 public key per account"
},
{
"title": "Notes encrypted with X25519 ECDH and XChaCha20",
"url": "https://github.com/0xbow-io/privacy-pools-v2-monorepo/blob/61fac03acd1fc306164ddc234f7fac4147d04493/packages/core-sdk/src/services/NoteComputationService.ts#L242-L260"
},
{
"title": "Three keys from one wallet signature",
"url": "https://github.com/0xbow-io/privacy-pools-v2-monorepo/blob/61fac03acd1fc306164ddc234f7fac4147d04493/packages/core-sdk/src/services/AbstractCryptoService.ts#L147-L195"
},
{
"section": "trusted-setups"
}
],
"id": "futureAdversary",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "recipient",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
},
{
"field": "asset",
"exposure": "exposed"
}
]
}
}
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "defi",
"label": "DeFi",
"description": "Interop with DeFi (swaps, vaults) from within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "The upgrader role can replace the PoolVault that escrows deposits without delay, so a malicious upgrade takes the funds before anyone can leave. Ragequit works while the vault is paused, but not against a new implementation.",
"walkawayTest": {
"passed": false,
"reason": "New deposits need the ASP's approval to be spent privately. The app offers only 0xbow's relayer."
}
},
"referenceClient": {
"name": "privacypools.com",
"repository": "https://github.com/0xbow-io/privacy-pools-website-v2",
"commit": "bfb752cdf7c0659bb4fd25e97933e04fce844c4a"
},
"relayerTracking": {
"type": "onchainEvents",
"sources": [
{
"address": "eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"sinceTimestamp": 1788287903,
"extractor": "privacyPoolsV2Withdrawal"
}
]
},
"reproducibility": {
"value": "Reproducible",
"sentiment": "good",
"description": "Contracts, circuits, SDK, relayer and website are public and build locally, the contracts under a Business Source License. The 27 verifiers rebuild from the circuit sources and ceremony keys. The ASP service is closed."
},
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid spends or withdrawals.\n2. all [trusted setup](#trusted-setups) participants collude or leak their secrets, allowing forged proofs.\n3. the upgrader key deploys a malicious [upgrade](#upgrades-and-governance) of the PoolVault, which holds every deposit, or a verifier that accepts any proof, with no delay.\n
\n## Funds can be lost if\n1. a user loses the wallet whose signature derives their keys and the exported account key.\n2. the payer loses a claim link before the recipient claims it.\n3. Aave suffers a loss on the reserve behind a yield share.\n
\n## Use can be stopped if\n1. the upgrader key pauses deposits and spends, or raises the vetting fee on deposits up to 99.99% of their value.\n
\n## Privacy can be lost if\n1. the ASP leaves deposits out of its latest list, which freezes every note from them, up to halting all private spends (see privileged insider).\n2. the ASP keeps only a few labels in its latest list, so spends proven against it point to one of them (see privileged insider).\n3. 0xbow's relayer refuses a withdrawal, so the user must self-relay from a public wallet (see chain analyst).\n4. a note's label, which passes to every later payee, links to its deposit when timed against the ASP's updates (see chain analyst).\n5. 0xbow pairs the IP of a deposit session with the IP of a withdrawal request across its ASP and relayer (see privileged insider).\n6. a user keeps the default RPCs, which see their account at sign-in and can time it against the withdrawal (see network observer).\n7. elliptic-curve cryptography is broken, which decrypts every onchain note from the published viewing keys (see future adversary).",
"tokens": [
{
"token": {
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"symbol": "ETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1788287903
},
"buckets": [
{
"id": "privacy-pools-v2-ETH",
"type": "pool",
"label": "ETH",
"address": "eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"sinceTimestamp": 1788287903,
"anonymitySet": {
"minimumAmounts": [
"100000000000000000",
"10000000000000000000"
]
},
"deposit": {
"event": "0xed45e0df2bf0e287a792a7b79b19292af5cbab76cc8819049bf37aa067bf8501",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
}
},
"withdrawal": {
"event": "0x10763cc44bf9290f53ec1afd9f70684d93fe62b7d1956d9a18410ae38da9d048",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
}
},
"additionalWithdrawals": [
{
"event": "0x507455b25c1a4595720da5b6a8f6b76e4aa36db987a63b47266112d3cbf2e103",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
}
}
]
}
]
},
{
"token": {
"address": "0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "ppUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1788287903
},
"buckets": [
{
"id": "privacy-pools-v2-ppUSDC",
"type": "pool",
"label": "ppUSDC",
"address": "eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"sinceTimestamp": 1788287903,
"anonymitySet": {
"minimumAmounts": [
"200000000000000000000",
"20000000000000000000000"
]
},
"deposit": {
"event": "0xed45e0df2bf0e287a792a7b79b19292af5cbab76cc8819049bf37aa067bf8501",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6"
}
},
"withdrawal": {
"event": "0x10763cc44bf9290f53ec1afd9f70684d93fe62b7d1956d9a18410ae38da9d048",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6"
}
},
"additionalWithdrawals": [
{
"event": "0x507455b25c1a4595720da5b6a8f6b76e4aa36db987a63b47266112d3cbf2e103",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6"
}
}
]
}
]
},
{
"token": {
"address": "0xA4cF419558Ef36CC6FfB666195684dC963910426",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "ppUSDT",
"decimals": 18,
"priceId": "tether",
"sinceTimestamp": 1788287903
},
"buckets": [
{
"id": "privacy-pools-v2-ppUSDT",
"type": "pool",
"label": "ppUSDT",
"address": "eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"sinceTimestamp": 1788287903,
"anonymitySet": {
"minimumAmounts": [
"200000000000000000000",
"20000000000000000000000"
]
},
"deposit": {
"event": "0xed45e0df2bf0e287a792a7b79b19292af5cbab76cc8819049bf37aa067bf8501",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xA4cF419558Ef36CC6FfB666195684dC963910426"
}
},
"withdrawal": {
"event": "0x10763cc44bf9290f53ec1afd9f70684d93fe62b7d1956d9a18410ae38da9d048",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xA4cF419558Ef36CC6FfB666195684dC963910426"
}
},
"additionalWithdrawals": [
{
"event": "0x507455b25c1a4595720da5b6a8f6b76e4aa36db987a63b47266112d3cbf2e103",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0xA4cF419558Ef36CC6FfB666195684dC963910426"
}
}
]
}
]
},
{
"token": {
"address": "0x66051920D25af4E3596A8a46309F4D045F9D83B7",
"iconUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628",
"symbol": "ppETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1788287903
},
"buckets": [
{
"id": "privacy-pools-v2-ppETH",
"type": "pool",
"label": "ppETH",
"address": "eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"sinceTimestamp": 1788287903,
"anonymitySet": {
"minimumAmounts": [
"100000000000000000",
"10000000000000000000"
]
},
"deposit": {
"event": "0xed45e0df2bf0e287a792a7b79b19292af5cbab76cc8819049bf37aa067bf8501",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0x66051920D25af4E3596A8a46309F4D045F9D83B7"
}
},
"withdrawal": {
"event": "0x10763cc44bf9290f53ec1afd9f70684d93fe62b7d1956d9a18410ae38da9d048",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0x66051920D25af4E3596A8a46309F4D045F9D83B7"
}
},
"additionalWithdrawals": [
{
"event": "0x507455b25c1a4595720da5b6a8f6b76e4aa36db987a63b47266112d3cbf2e103",
"extractor": "privacyPoolsV2Value",
"params": {
"tokenAddress": "0x66051920D25af4E3596A8a46309F4D045F9D83B7"
}
}
]
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "One EOA holds the default admin, ops admin, upgrader, pauser, unpauser and entrypoint manager roles in the AccessRouter. It can upgrade the PoolVault, Entrypoint, Keystore and ASPRegistry, replace the verifiers, pause deposits and spends, enable assets, set a vetting fee of up to 99.99% on deposits and cap relayer fees, all without delay. It also administers the three yield shares, with a fee of at most 20% of the yield. The shares hold Aave v3 deposits, whose contracts Aave governance can upgrade after a public vote and delay. Aave's guardian multisig can pause a reserve instantly, which blocks redeeming its shares. A second EOA holds the postman role that publishes approved-label roots. A third owns RelaySwaps and curates its routers. No timelock or multisig is deployed. Ragequit cannot be paused, so funds already in the vault can leave to their owners as long as the implementation is not changed."
}
}
+1 -0
null
+1 -0
null
+1 -0
null
+4 -0
{
"associatedTokens": [],
"warnings": []
}
+97 -0
[
{
"mode": "auto",
"id": "privacy-pools-v2-ETH",
"priceId": "ethereum",
"symbol": "ETH",
"name": "Ether",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"amount": {
"type": "balanceOfEscrow",
"chain": "ethereum",
"sinceTimestamp": 1788287903,
"address": "native",
"decimals": 18,
"escrowAddress": "0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed"
},
"category": "ether",
"source": "canonical",
"isAssociated": false
},
{
"mode": "auto",
"id": "privacy-pools-v2-ppETH",
"priceId": "ethereum",
"symbol": "ppETH",
"name": "Privacy Pool ETH",
"iconUrl": "https://coin-images.coingecko.com/coins/images/279/large/ethereum.png?1696501628",
"amount": {
"type": "balanceOfEscrow",
"chain": "ethereum",
"sinceTimestamp": 1789501751,
"address": "0x66051920D25af4E3596A8a46309F4D045F9D83B7",
"decimals": 18,
"escrowAddress": "0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed"
},
"category": "ether",
"source": "canonical",
"isAssociated": false
},
{
"mode": "auto",
"id": "privacy-pools-v2-ppUSDC",
"priceId": "usd-coin",
"symbol": "ppUSDC",
"name": "Privacy Pool USDC",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"amount": {
"type": "balanceOfEscrow",
"chain": "ethereum",
"sinceTimestamp": 1788511139,
"address": "0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6",
"decimals": 18,
"escrowAddress": "0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed"
},
"category": "stablecoin",
"source": "canonical",
"isAssociated": false
},
{
"mode": "auto",
"id": "privacy-pools-v2-ppUSDT",
"priceId": "tether",
"symbol": "ppUSDT",
"name": "Privacy Pool USDT",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"amount": {
"type": "balanceOfEscrow",
"chain": "ethereum",
"sinceTimestamp": 1788527363,
"address": "0xA4cF419558Ef36CC6FfB666195684dC963910426",
"decimals": 18,
"escrowAddress": "0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed"
},
"category": "stablecoin",
"source": "canonical",
"isAssociated": false
},
{
"mode": "auto",
"id": "privacy-pools-v2-USDC",
"priceId": "usd-coin",
"symbol": "USDC",
"name": "USD Coin",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"amount": {
"type": "balanceOfEscrow",
"chain": "ethereum",
"sinceTimestamp": 1788287903,
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"decimals": 6,
"escrowAddress": "0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed"
},
"category": "stablecoin",
"source": "canonical",
"isAssociated": false
}
]
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+74 -0
{
"ethereum": {
"roles": [],
"actors": [
{
"id": "Entrypoint",
"name": "Entrypoint",
"accounts": [
{
"address": "eth:0xca1e072236D231130059eeA6Bfceb7F4e9a1F0C3",
"type": "Contract",
"isVerified": true,
"name": "0xca1e…F0C3",
"url": "https://etherscan.io/address/0xca1e072236D231130059eeA6Bfceb7F4e9a1F0C3"
}
],
"chain": "ethereum",
"description": "Deposit gate of Privacy Pools v2. It checks each deposit against its asset's configuration and keeps the vetting fee.\n* Can interact with AccessRouter\n * deposit into the PoolVault on behalf of users ",
"discoveryDrivenData": true
},
{
"id": "EOA-1",
"name": "EOA 1",
"accounts": [
{
"address": "eth:0x12Dbd6335d7f529F8922420Ba9c15c9E7A324c92",
"type": "EOA",
"isVerified": true,
"name": "0x12Db…4c92",
"url": "https://etherscan.io/address/0x12Dbd6335d7f529F8922420Ba9c15c9E7A324c92",
"displayName": "EOA 1"
}
],
"chain": "ethereum",
"description": "* Can interact with AccessRouter\n * enable or disable assets, set minimum deposits, vetting fees of up to 99.99% and relayer fee caps, and sweep fees held by the Entrypoint \n * grant and revoke the ops admin, upgrader, unpauser and depositor roles \n * grant and revoke the pauser, entrypoint manager and postman roles \n * pause deposits and transacts in the PoolVault \n * unpause the PoolVault \n * upgrade the PoolVault, Entrypoint, Keystore and ASPRegistry, and replace the vault's verifiers, registries and tree limits \n* Can interact with ppETH\n * set the yield fee up to 20%, claim fees, pause minting, set the Aave rewards controller and rescue tokens other than the backing aToken \n* Can interact with ppUSDT\n * set the yield fee up to 20%, claim fees, pause minting, set the Aave rewards controller and rescue tokens other than the backing aToken \n* Can interact with ppUSDC\n * set the yield fee up to 20%, claim fees, pause minting, set the Aave rewards controller and rescue tokens other than the backing aToken ",
"discoveryDrivenData": true
},
{
"id": "EOA-2",
"name": "EOA 2",
"accounts": [
{
"address": "eth:0xa05B43E1dcdCe0c6A40471a602038BC346900758",
"type": "EOA",
"isVerified": true,
"name": "0xa05B…0758",
"url": "https://etherscan.io/address/0xa05B43E1dcdCe0c6A40471a602038BC346900758",
"displayName": "EOA 2"
}
],
"chain": "ethereum",
"description": "* Can interact with AccessRouter\n * publish the approved-label root every private spend must match ",
"discoveryDrivenData": true
},
{
"id": "EOA-3",
"name": "EOA 3",
"accounts": [
{
"address": "eth:0x0967755AfA2016866D12EefB820705026842dCe8",
"type": "EOA",
"isVerified": true,
"name": "0x0967…dCe8",
"url": "https://etherscan.io/address/0x0967755AfA2016866D12EefB820705026842dCe8",
"displayName": "EOA 3"
}
],
"chain": "ethereum",
"description": "* Can interact with RelaySwaps\n * approve the aggregator routers and yield zaps that RelaySwaps sends withdrawn funds through ",
"discoveryDrivenData": true
}
]
}
}
+708 -0
{
"addresses": {
"ethereum": [
{
"name": "PrivacyPoolRelay",
"isVerified": true,
"address": "eth:0x01a8Fa4dbb60187aD8d3c3d08E7Fb8C14198A461",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Withdrawal processor that submits the transact proof and pays the recipient and the relayer's fee, capped per asset.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x01a8Fa4dbb60187aD8d3c3d08E7Fb8C14198A461#code"
},
{
"name": "PoolVault",
"isVerified": true,
"address": "eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x0000000000000000000000000000000000000000"
],
"implementations": [
"eth:0x5F89cD5c3610c2AD870B1b33126d209fECdb69c7"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1788287903,
"transactionHash": "0x2739363102ee08c72a6dd6c96e3c3241bff7507f23a71498c51b25dd5224f0c9",
"implementations": [
"eth:0x5F89cD5c3610c2AD870B1b33126d209fECdb69c7"
]
}
],
"description": "Holds every pool asset and the state tree of note commitments and spent nullifiers.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed#code"
},
{
"name": "PPRouterUSDT",
"isVerified": true,
"address": "eth:0x13a0b86bac3e0C29bd64fED7BCD2EE84f371f41C",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Yield router for one share token. It wraps deposits of the underlying into shares, and unwraps withdrawn shares to pay the recipient and the relayer fee.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x13a0b86bac3e0C29bd64fED7BCD2EE84f371f41C#code"
},
{
"name": "ASPRegistry",
"isVerified": true,
"address": "eth:0x259C0BEa1d783c202509BD3b2688d23b8AEf58B0",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x0000000000000000000000000000000000000000"
],
"implementations": [
"eth:0x046991310B099e86af239d3A4F3AB3e196F24EC7"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1788287435,
"transactionHash": "0xc4c8179cb77006b5190cba6d0ecae70485773ad0abd596fc1f96bdc2cb4120aa",
"implementations": [
"eth:0x046991310B099e86af239d3A4F3AB3e196F24EC7"
]
}
],
"description": "Publishes the association set provider's approved-label roots with their IPFS CIDs, and receives the data that ties each deposit to its label, encrypted to the ASP.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x259C0BEa1d783c202509BD3b2688d23b8AEf58B0#code"
},
{
"name": "PPYieldTokenZapETH",
"isVerified": true,
"address": "eth:0x33c1eEf370bBb447414156CFc4fDABD434776EAf",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Converts between a share token and its underlying in one call, through Aave v3.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x33c1eEf370bBb447414156CFc4fDABD434776EAf#code"
},
{
"name": "AccessRouter",
"isVerified": true,
"address": "eth:0x40a6bC296D87f71Ab31Ca3Bfb50513441fBD5160",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Role registry the Privacy Pools v2 core contracts check. No role has a delay.\n* Roles:\n * **defaultAdmins**: EOA 1\n * **depositors**: Entrypoint\n * **entrypointManagers**: EOA 1\n * **opsAdmins**: EOA 1\n * **pausers**: EOA 1\n * **postmen**: EOA 2\n * **unpausers**: EOA 1\n * **upgraders**: EOA 1",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x40a6bC296D87f71Ab31Ca3Bfb50513441fBD5160#code"
},
{
"name": "ppETH",
"isVerified": true,
"address": "eth:0x66051920D25af4E3596A8a46309F4D045F9D83B7",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "ERC-4626 share token over an Aave v3 aToken, the asset the pool holds for a yield deposit. The admin's fee applies to the yield only.\n* Roles:\n * **owner**: EOA 1",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x66051920D25af4E3596A8a46309F4D045F9D83B7#code"
},
{
"name": "Keystore",
"isVerified": true,
"address": "eth:0x6E463391c79b7e1A88eF26E0B023f9A6C9938a71",
"upgradeability": {
"proxyType": "EIP1967 proxy",
"admins": [
"eth:0x0000000000000000000000000000000000000000"
],
"implementations": [
"eth:0x7b915008ffa267271e9E328430FE328eA02C5F04"
]
},
"chain": "ethereum",
"pastUpgrades": [
{
"timestamp": 1788287351,
"transactionHash": "0x50b876488cdaab2020765918b7270329ab4d9194f34126ed5192e33402c1753e",
"implementations": [
"eth:0x7b915008ffa267271e9E328430FE328eA02C5F04"
]
}
],
"description": "Account registry of Privacy Pools v2: one leaf per account with its nullifying key hash and auth policy, plus an optional X25519 viewing public key.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x6E463391c79b7e1A88eF26E0B023f9A6C9938a71#code"
},
{
"name": "PPRouterETH",
"isVerified": true,
"address": "eth:0x77613D670BB9fD48A9898D0eac8ebf21B566F960",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Yield router for one share token. It wraps deposits of the underlying into shares, and unwraps withdrawn shares to pay the recipient and the relayer fee.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x77613D670BB9fD48A9898D0eac8ebf21B566F960#code"
},
{
"name": "PPYieldTokenZapUSDC",
"isVerified": true,
"address": "eth:0x9Ea986BcDF6784D85B518b15bEEE1E65b585817B",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Converts between a share token and its underlying in one call, through Aave v3.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x9Ea986BcDF6784D85B518b15bEEE1E65b585817B#code"
},
{
"name": "ppUSDT",
"isVerified": true,
"address": "eth:0xA4cF419558Ef36CC6FfB666195684dC963910426",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "ERC-4626 share token over an Aave v3 aToken, the asset the pool holds for a yield deposit. The admin's fee applies to the yield only.\n* Roles:\n * **owner**: EOA 1",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xA4cF419558Ef36CC6FfB666195684dC963910426#code"
},
{
"name": "ppUSDC",
"isVerified": true,
"address": "eth:0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "ERC-4626 share token over an Aave v3 aToken, the asset the pool holds for a yield deposit. The admin's fee applies to the yield only.\n* Roles:\n * **owner**: EOA 1",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6#code"
},
{
"name": "PPYieldTokenZapUSDT",
"isVerified": true,
"address": "eth:0xDC3D922df81FC7B7f58229431ED91acB0482f3A5",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Converts between a share token and its underlying in one call, through Aave v3.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xDC3D922df81FC7B7f58229431ED91acB0482f3A5#code"
},
{
"name": "PPRouterUSDC",
"isVerified": true,
"address": "eth:0xe76E793d776c1e207aD7a7fa7C57d27420d85110",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Yield router for one share token. It wraps deposits of the underlying into shares, and unwraps withdrawn shares to pay the recipient and the relayer fee.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xe76E793d776c1e207aD7a7fa7C57d27420d85110#code"
},
{
"name": "Transact4x5Verifier",
"isVerified": true,
"address": "eth:0x01b4954E3b3C1F68785f60D7465c38C31266bfab",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x01b4954E3b3C1F68785f60D7465c38C31266bfab#code"
},
{
"name": "Transact1x2Verifier",
"isVerified": true,
"address": "eth:0x0e13d94235d8a0d8f9fC3B63BB41D666eF0677Ed",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x0e13d94235d8a0d8f9fC3B63BB41D666eF0677Ed#code"
},
{
"name": "Transact5x3Verifier",
"isVerified": true,
"address": "eth:0x20D4B794A2A1ae7A34AF184172dd931d3ff2Fa32",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x20D4B794A2A1ae7A34AF184172dd931d3ff2Fa32#code"
},
{
"name": "Transact1x1Verifier",
"isVerified": true,
"address": "eth:0x21347145497569b34efAB7d73952208866520042",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x21347145497569b34efAB7d73952208866520042#code"
},
{
"name": "Transact2x1Verifier",
"isVerified": true,
"address": "eth:0x338625F2199675D2aC4Fbf7A89567864ac990710",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x338625F2199675D2aC4Fbf7A89567864ac990710#code"
},
{
"name": "Transact1x4Verifier",
"isVerified": true,
"address": "eth:0x3ee4A00e0ba1AC0Ef8aD3e4b541CA42FBB4592c3",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x3ee4A00e0ba1AC0Ef8aD3e4b541CA42FBB4592c3#code"
},
{
"name": "Transact4x2Verifier",
"isVerified": true,
"address": "eth:0x454F1Da26DD4c7c89a849019BeC4c7C7C404d3A4",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x454F1Da26DD4c7c89a849019BeC4c7C7C404d3A4#code"
},
{
"name": "Transact4x4Verifier",
"isVerified": true,
"address": "eth:0x4Cb752CEF56a5095321Ed72699cD7A699D48F4b5",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x4Cb752CEF56a5095321Ed72699cD7A699D48F4b5#code"
},
{
"name": "Transact3x1Verifier",
"isVerified": true,
"address": "eth:0x579f6734d35937b8432BA8FfC17C3120eb657c82",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x579f6734d35937b8432BA8FfC17C3120eb657c82#code"
},
{
"name": "RagequitVerifier",
"isVerified": true,
"address": "eth:0x5a06582115953E2cAbeD8e6A0EeAE35BA430118f",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x5a06582115953E2cAbeD8e6A0EeAE35BA430118f#code"
},
{
"name": "Transact5x1Verifier",
"isVerified": true,
"address": "eth:0x61573Cf3c3A20C9739b68B8e742Ca51971387Cb5",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x61573Cf3c3A20C9739b68B8e742Ca51971387Cb5#code"
},
{
"name": "Transact2x5Verifier",
"isVerified": true,
"address": "eth:0x62Cf8963300F284016daE0cD19f5D9BC60846a46",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x62Cf8963300F284016daE0cD19f5D9BC60846a46#code"
},
{
"name": "Transact5x4Verifier",
"isVerified": true,
"address": "eth:0x766c2F31483935CD55355fcE00fc5eDB82A15acC",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x766c2F31483935CD55355fcE00fc5eDB82A15acC#code"
},
{
"name": "Transact3x2Verifier",
"isVerified": true,
"address": "eth:0x76D574559765fd4b90903fFa682964Ae7e7e878a",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x76D574559765fd4b90903fFa682964Ae7e7e878a#code"
},
{
"name": "Transact5x5Verifier",
"isVerified": true,
"address": "eth:0x7BeE2554970A749D7671424DFa3fAbE15d7e4BD8",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x7BeE2554970A749D7671424DFa3fAbE15d7e4BD8#code"
},
{
"name": "Transact5x2Verifier",
"isVerified": true,
"address": "eth:0x8ABfb288dAc87392EaFdD59F6809825fcA0e8b85",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x8ABfb288dAc87392EaFdD59F6809825fcA0e8b85#code"
},
{
"name": "Transact4x1Verifier",
"isVerified": true,
"address": "eth:0x909ECAF2A4959726a2BC3d82Fc837B8D3F1c61d3",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x909ECAF2A4959726a2BC3d82Fc837B8D3F1c61d3#code"
},
{
"name": "Transact4x3Verifier",
"isVerified": true,
"address": "eth:0x95dEC97ac78E8C0FfDc6315FDc0A0791238b93A3",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0x95dEC97ac78E8C0FfDc6315FDc0A0791238b93A3#code"
},
{
"name": "Transact2x2Verifier",
"isVerified": true,
"address": "eth:0xAc716f21626994c4264eA457Fe208071050611B5",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xAc716f21626994c4264eA457Fe208071050611B5#code"
},
{
"name": "Transact3x3Verifier",
"isVerified": true,
"address": "eth:0xAeCDf3E27A602f23cEc2E5CE250093b3E806D041",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xAeCDf3E27A602f23cEc2E5CE250093b3E806D041#code"
},
{
"name": "Transact2x3Verifier",
"isVerified": true,
"address": "eth:0xB8aa00333b8D6958da72A15D59179BbDD1e49064",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xB8aa00333b8D6958da72A15D59179BbDD1e49064#code"
},
{
"name": "Transact1x3Verifier",
"isVerified": true,
"address": "eth:0xC5E1D9D9CF12E796Ec8E072646c6BF29A1e55382",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xC5E1D9D9CF12E796Ec8E072646c6BF29A1e55382#code"
},
{
"name": "Transact3x4Verifier",
"isVerified": true,
"address": "eth:0xe0aec1eE10eBfCDcB09b6e5a7ea6Ae34D066219d",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xe0aec1eE10eBfCDcB09b6e5a7ea6Ae34D066219d#code"
},
{
"name": "DepositVerifier",
"isVerified": true,
"address": "eth:0xEe96Ca04d2Ab2eC9A8803eb78F39b2875dFF6fdf",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xEe96Ca04d2Ab2eC9A8803eb78F39b2875dFF6fdf#code"
},
{
"name": "Transact2x4Verifier",
"isVerified": true,
"address": "eth:0xF1C6c55B70EC3Df923f5E9bcd64aee5c3073C42c",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xF1C6c55B70EC3Df923f5E9bcd64aee5c3073C42c#code"
},
{
"name": "Transact1x5Verifier",
"isVerified": true,
"address": "eth:0xfa0138C5dE45E520AbA349BE38a827DAb470f70A",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xfa0138C5dE45E520AbA349BE38a827DAb470f70A#code"
},
{
"name": "Transact3x5Verifier",
"isVerified": true,
"address": "eth:0xFdF4EbC7645E1F4c04aE33285b6e3f78e4A3a275",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xFdF4EbC7645E1F4c04aE33285b6e3f78e4A3a275#code"
},
{
"name": "RelaySwaps",
"isVerified": false,
"address": "eth:0xd0395c08DD8eA7671a7A65bDca8E473e8E8260a8",
"upgradeability": {
"proxyType": "immutable",
"admins": [],
"implementations": [],
"immutable": true
},
"chain": "ethereum",
"description": "Withdrawal processor that swaps the withdrawn asset through an approved aggregator router, with the swap calldata bound into the proof.\n* Roles:\n * **owner**: EOA 3",
"discoveryDrivenData": true,
"url": "https://etherscan.io/address/0xd0395c08DD8eA7671a7A65bDca8E473e8E8260a8#code"
}
]
},
"risks": [
{
"category": "Funds can be stolen if",
"text": "the source code of unverified contracts contains malicious code.",
"isCritical": true
}
],
"zkVerifiers": [
"eth:0xEe96Ca04d2Ab2eC9A8803eb78F39b2875dFF6fdf",
"eth:0x5a06582115953E2cAbeD8e6A0EeAE35BA430118f",
"eth:0x21347145497569b34efAB7d73952208866520042",
"eth:0x0e13d94235d8a0d8f9fC3B63BB41D666eF0677Ed",
"eth:0xC5E1D9D9CF12E796Ec8E072646c6BF29A1e55382",
"eth:0x3ee4A00e0ba1AC0Ef8aD3e4b541CA42FBB4592c3",
"eth:0xfa0138C5dE45E520AbA349BE38a827DAb470f70A",
"eth:0x338625F2199675D2aC4Fbf7A89567864ac990710",
"eth:0xAc716f21626994c4264eA457Fe208071050611B5",
"eth:0xB8aa00333b8D6958da72A15D59179BbDD1e49064",
"eth:0xF1C6c55B70EC3Df923f5E9bcd64aee5c3073C42c",
"eth:0x62Cf8963300F284016daE0cD19f5D9BC60846a46",
"eth:0x579f6734d35937b8432BA8FfC17C3120eb657c82",
"eth:0x76D574559765fd4b90903fFa682964Ae7e7e878a",
"eth:0xAeCDf3E27A602f23cEc2E5CE250093b3E806D041",
"eth:0xe0aec1eE10eBfCDcB09b6e5a7ea6Ae34D066219d",
"eth:0xFdF4EbC7645E1F4c04aE33285b6e3f78e4A3a275",
"eth:0x909ECAF2A4959726a2BC3d82Fc837B8D3F1c61d3",
"eth:0x454F1Da26DD4c7c89a849019BeC4c7C7C404d3A4",
"eth:0x95dEC97ac78E8C0FfDc6315FDc0A0791238b93A3",
"eth:0x4Cb752CEF56a5095321Ed72699cD7A699D48F4b5",
"eth:0x01b4954E3b3C1F68785f60D7465c38C31266bfab",
"eth:0x61573Cf3c3A20C9739b68B8e742Ca51971387Cb5",
"eth:0x8ABfb288dAc87392EaFdD59F6809825fcA0e8b85",
"eth:0x20D4B794A2A1ae7A34AF184172dd931d3ff2Fa32",
"eth:0x766c2F31483935CD55355fcE00fc5eDB82A15acC",
"eth:0x7BeE2554970A749D7671424DFa3fAbE15d7e4BD8"
]
}
+7 -0
{
"baseTimestamp": 1792559137,
"contractsDiscoDriven": false,
"hasDiscoUi": false,
"isDiscoDriven": false,
"permissionsDiscoDriven": false
}
+16 -0
[
{
"id": "75f84d35",
"date": "Thu, 22 Oct 2026 10:01:44 GMT",
"timestamp": 1792559137,
"description": "Initial discovery of Privacy Pools v2 on Ethereum: Entrypoint, PoolVault, Keystore, ASPRegistry, AccessRouter, PrivacyPoolRelay, RelaySwaps, the yield routers, shares and zaps, and the 27 Groth16 verifiers.",
"isHighSeverity": false,
"changeCount": 45,
"sections": [
{
"kind": "initial-discovery",
"body": "```diff\n+ Status: CREATED\n contract PrivacyPoolRelay (eth:0x01a8Fa4dbb60187aD8d3c3d08E7Fb8C14198A461) [privacy-pools-v2/PrivacyPoolRelay]\n +++ description: Withdrawal processor that submits the transact proof and pays the recipient and the relayer's fee, capped per asset.\n```\n\n```diff\n+ Status: CREATED\n contract Transact4x5Verifier (eth:0x01b4954E3b3C1F68785f60D7465c38C31266bfab) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n EOA (eth:0x0967755AfA2016866D12EefB820705026842dCe8)\n +++ description: None\n```\n\n```diff\n+ Status: CREATED\n contract Transact1x2Verifier (eth:0x0e13d94235d8a0d8f9fC3B63BB41D666eF0677Ed) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract PoolVault (eth:0x0Eb42804BF897662aF851370eaeAdcDBEC1b97ed) [privacy-pools-v2/PoolVault]\n +++ description: Holds every pool asset and the state tree of note commitments and spent nullifiers.\n```\n\n```diff\n+ Status: CREATED\n EOA (eth:0x12Dbd6335d7f529F8922420Ba9c15c9E7A324c92)\n +++ description: None\n```\n\n```diff\n+ Status: CREATED\n contract PPRouterUSDT (eth:0x13a0b86bac3e0C29bd64fED7BCD2EE84f371f41C) [privacy-pools-v2/PPRouter]\n +++ description: Yield router for one share token. It wraps deposits of the underlying into shares, and unwraps withdrawn shares to pay the recipient and the relayer fee.\n```\n\n```diff\n+ Status: CREATED\n contract Transact5x3Verifier (eth:0x20D4B794A2A1ae7A34AF184172dd931d3ff2Fa32) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact1x1Verifier (eth:0x21347145497569b34efAB7d73952208866520042) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract ASPRegistry (eth:0x259C0BEa1d783c202509BD3b2688d23b8AEf58B0) [privacy-pools-v2/ASPRegistry]\n +++ description: Publishes the association set provider's approved-label roots with their IPFS CIDs, and receives the data that ties each deposit to its label, encrypted to the ASP.\n```\n\n```diff\n+ Status: CREATED\n contract Transact2x1Verifier (eth:0x338625F2199675D2aC4Fbf7A89567864ac990710) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract PPYieldTokenZapETH (eth:0x33c1eEf370bBb447414156CFc4fDABD434776EAf) [privacy-pools-v2/PPYieldTokenZap]\n +++ description: Converts between a share token and its underlying in one call, through Aave v3.\n```\n\n```diff\n+ Status: CREATED\n contract Transact1x4Verifier (eth:0x3ee4A00e0ba1AC0Ef8aD3e4b541CA42FBB4592c3) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract AccessRouter (eth:0x40a6bC296D87f71Ab31Ca3Bfb50513441fBD5160) [privacy-pools-v2/AccessRouter]\n +++ description: Role registry the Privacy Pools v2 core contracts check. No role has a delay.\n```\n\n```diff\n+ Status: CREATED\n contract Transact4x2Verifier (eth:0x454F1Da26DD4c7c89a849019BeC4c7C7C404d3A4) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact4x4Verifier (eth:0x4Cb752CEF56a5095321Ed72699cD7A699D48F4b5) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact3x1Verifier (eth:0x579f6734d35937b8432BA8FfC17C3120eb657c82) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract RagequitVerifier (eth:0x5a06582115953E2cAbeD8e6A0EeAE35BA430118f) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact5x1Verifier (eth:0x61573Cf3c3A20C9739b68B8e742Ca51971387Cb5) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact2x5Verifier (eth:0x62Cf8963300F284016daE0cD19f5D9BC60846a46) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract ppETH (eth:0x66051920D25af4E3596A8a46309F4D045F9D83B7) [privacy-pools-v2/PPYieldToken]\n +++ description: ERC-4626 share token over an Aave v3 aToken, the asset the pool holds for a yield deposit. The admin's fee applies to the yield only.\n```\n\n```diff\n+ Status: CREATED\n contract Keystore (eth:0x6E463391c79b7e1A88eF26E0B023f9A6C9938a71) [privacy-pools-v2/Keystore]\n +++ description: Account registry of Privacy Pools v2: one leaf per account with its nullifying key hash and auth policy, plus an optional X25519 viewing public key.\n```\n\n```diff\n+ Status: CREATED\n contract Transact5x4Verifier (eth:0x766c2F31483935CD55355fcE00fc5eDB82A15acC) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact3x2Verifier (eth:0x76D574559765fd4b90903fFa682964Ae7e7e878a) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract PPRouterETH (eth:0x77613D670BB9fD48A9898D0eac8ebf21B566F960) [privacy-pools-v2/PPRouter]\n +++ description: Yield router for one share token. It wraps deposits of the underlying into shares, and unwraps withdrawn shares to pay the recipient and the relayer fee.\n```\n\n```diff\n+ Status: CREATED\n contract Transact5x5Verifier (eth:0x7BeE2554970A749D7671424DFa3fAbE15d7e4BD8) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact5x2Verifier (eth:0x8ABfb288dAc87392EaFdD59F6809825fcA0e8b85) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact4x1Verifier (eth:0x909ECAF2A4959726a2BC3d82Fc837B8D3F1c61d3) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact4x3Verifier (eth:0x95dEC97ac78E8C0FfDc6315FDc0A0791238b93A3) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract PPYieldTokenZapUSDC (eth:0x9Ea986BcDF6784D85B518b15bEEE1E65b585817B) [privacy-pools-v2/PPYieldTokenZap]\n +++ description: Converts between a share token and its underlying in one call, through Aave v3.\n```\n\n```diff\n+ Status: CREATED\n contract ppUSDT (eth:0xA4cF419558Ef36CC6FfB666195684dC963910426) [privacy-pools-v2/PPYieldToken]\n +++ description: ERC-4626 share token over an Aave v3 aToken, the asset the pool holds for a yield deposit. The admin's fee applies to the yield only.\n```\n\n```diff\n+ Status: CREATED\n contract Transact2x2Verifier (eth:0xAc716f21626994c4264eA457Fe208071050611B5) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact3x3Verifier (eth:0xAeCDf3E27A602f23cEc2E5CE250093b3E806D041) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact2x3Verifier (eth:0xB8aa00333b8D6958da72A15D59179BbDD1e49064) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract ppUSDC (eth:0xC246aFb23482fF9596E9cee5f1f678eFe0EB1ad6) [privacy-pools-v2/PPYieldToken]\n +++ description: ERC-4626 share token over an Aave v3 aToken, the asset the pool holds for a yield deposit. The admin's fee applies to the yield only.\n```\n\n```diff\n+ Status: CREATED\n contract Transact1x3Verifier (eth:0xC5E1D9D9CF12E796Ec8E072646c6BF29A1e55382) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Entrypoint (eth:0xca1e072236D231130059eeA6Bfceb7F4e9a1F0C3) [privacy-pools-v2/Entrypoint]\n +++ description: Deposit gate of Privacy Pools v2. It checks each deposit against its asset's configuration and keeps the vetting fee.\n```\n\n```diff\n+ Status: CREATED\n contract RelaySwaps (eth:0xd0395c08DD8eA7671a7A65bDca8E473e8E8260a8) [N/A]\n +++ description: Withdrawal processor that swaps the withdrawn asset through an approved aggregator router, with the swap calldata bound into the proof.\n```\n\n```diff\n+ Status: CREATED\n contract PPYieldTokenZapUSDT (eth:0xDC3D922df81FC7B7f58229431ED91acB0482f3A5) [privacy-pools-v2/PPYieldTokenZap]\n +++ description: Converts between a share token and its underlying in one call, through Aave v3.\n```\n\n```diff\n+ Status: CREATED\n contract Transact3x4Verifier (eth:0xe0aec1eE10eBfCDcB09b6e5a7ea6Ae34D066219d) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract PPRouterUSDC (eth:0xe76E793d776c1e207aD7a7fa7C57d27420d85110) [privacy-pools-v2/PPRouter]\n +++ description: Yield router for one share token. It wraps deposits of the underlying into shares, and unwraps withdrawn shares to pay the recipient and the relayer fee.\n```\n\n```diff\n+ Status: CREATED\n contract DepositVerifier (eth:0xEe96Ca04d2Ab2eC9A8803eb78F39b2875dFF6fdf) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact2x4Verifier (eth:0xF1C6c55B70EC3Df923f5E9bcd64aee5c3073C42c) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact1x5Verifier (eth:0xfa0138C5dE45E520AbA349BE38a827DAb470f70A) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```\n\n```diff\n+ Status: CREATED\n contract Transact3x5Verifier (eth:0xFdF4EbC7645E1F4c04aE33285b6e3f78e4A3a275) [privacy-pools-v2/Groth16Verifier]\n +++ description: Groth16 verifier for one Privacy Pools v2 circuit, with that circuit's trusted-setup verification key hard-coded.\n```"
}
]
}
]
+1 -0
null
+1 -0
null
+1 -0
null
+1 -0
null
+10 -1
+10 -1
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides everything inside the pool, including which shield funds which unshield. Shields and unshields are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Everything inside the pool is hidden, including which shield funds which unshield.",
"exposureContinued": "Shields and unshields show address, token and amount. DeFi bundles unshield to the adapter in cleartext.",
"advice": "Exit through a broadcaster, so none of the user's wallets pay gas for the receiving address.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"asset": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"linkage": "private"
},
"sources": [
{
"contract": "RailgunSmartWallet",
"title": "Shield and unshield"
},
{
"contract": "RelayAdapt",
"title": "DeFi bundles"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "The candidates for an unshield are the shields of the same token.",
"exposureContinued": "In-pool transfers break a one-to-one match, while timing and exact amounts narrow it.",
"exposureContinued": "In-pool transfers break a one-to-one match, while timing and exact amounts narrow it. RailOxide shows the payer's 0zk address to every payee.",
"advice": "Withdraw common amounts rather than everything at once. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"asset": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"linkage": "private"
},
"sources": [
{
"title": "RailOxide marks every note sender as visible",
"url": "https://github.com/triamazikamno/railgun-rust/blob/b602c7d516a3f58bd83911a0a704a53fa0dc0c47/crates/railgun-wallet/src/notes.rs#L26-L48"
},
{
"title": "A Tattered Cloak of Invisibility (arXiv:2606.25926)",
"url": "https://arxiv.org/abs/2606.25926"
},
{
"title": "The Anonymity Gap (arXiv:2608.22987)",
"url": "https://arxiv.org/abs/2608.22987"
}
],
"id": "chainAnalyst",
"value": "Link private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "good",
"exposureShort": "RailOxide sends all traffic over built-in Tor, broadcaster messages included, and finds the user's notes by decrypting every note locally.",
"exposureContinued": "All traffic shares one Tor session, so the public RPCs it picks at random see the user's public addresses, shields and the gas estimate of each private transaction from one exit. The user's own node as its RPC keeps these from third parties.",
"advice": "Use RailOxide, the wallet these ratings assume, and set the user's own node as its Ethereum RPC.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"asset": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"linkage": {
"verdict": "atRisk",
"note": "Private only with the user's own node as RPC, over the default Tor."
}
},
"sources": [
{
"title": "Built-in Tor is the default",
"url": "https://github.com/triamazikamno/railoxide/blob/8773f4ecb00c6ac7cf164ba1f989eb77dd4b0ec5/crates/wallet-ops/src/settings/network_chains.rs#L10-L15"
},
{
"title": "Every stream uses one Tor session",
"url": "https://github.com/triamazikamno/railoxide/blob/8773f4ecb00c6ac7cf164ba1f989eb77dd4b0ec5/crates/wallet-ops/src/http.rs#L1549-L1559"
},
{
"title": "A custom RPC list replaces the public pool",
"url": "https://github.com/triamazikamno/railoxide/blob/8773f4ecb00c6ac7cf164ba1f989eb77dd4b0ec5/crates/wallet-ops/src/settings/effective.rs#L263-L277"
}
],
"id": "networkObserver",
"value": "Link private",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "good",
"exposureShort": "Only the user holds viewing keys, and DAO upgrades wait 7 days.",
"exposureContinued": "PPoI list providers can refuse a shield, which leaves a self-broadcast exit. RailOxide builds PPoIs from a local copy of the lists. After each transaction it sends the PPoI node only that transaction's new notes with their proofs.",
"advice": "Watch governance proposals and unshield before an upgrade the user rejects executes.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"asset": {
"verdict": "atRisk",
"note": "Public in DeFi bundles."
},
"linkage": {
"verdict": "atRisk",
"note": "Private only with a wallet that builds PPoIs locally, like RailOxide."
}
},
"sources": [
{
"section": "upgrades-and-governance"
},
{
"title": "RailOxide builds PPoIs locally",
"url": "https://github.com/triamazikamno/railoxide/blob/8773f4ecb00c6ac7cf164ba1f989eb77dd4b0ec5/crates/wallet-ops/src/poi_contexts.rs#L116-L150"
}
],
"id": "privilegedInsider",
"value": "Link private",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "warning",
"exposureShort": "Notes are encrypted with elliptic-curve key exchange.",
"exposureContinued": "Whoever breaks elliptic-curve cryptography decrypts every note sent to a 0zk address that was ever shared, broadcaster fee notes included.",
"advice": "Share the user's 0zk address privately, with a fresh one per counterparty where possible.",
"interior": {
"sender": "atRisk",
"recipient": "atRisk",
"amount": "atRisk",
"asset": "atRisk",
"linkage": {
"verdict": "atRisk",
"note": "Private only while the user's 0zk address stays unshared."
}
},
"sources": [
{
"title": "Shared key derivation (Ed25519 ECDH)",
"url": "https://github.com/Railgun-Community/engine/blob/6e2614d53a106dd62abad91e7ce03ee4a3956138/src/utils/keys-utils.ts#L186-L224"
},
{
"title": "AES-GCM note encryption",
"url": "https://github.com/Railgun-Community/engine/blob/6e2614d53a106dd62abad91e7ce03ee4a3956138/src/utils/encryption/aes.ts#L24-L40"
}
],
"id": "futureAdversary",
"value": "Link at risk",
"alsoExposed": [
{
"field": "sender",
"exposure": "atRisk"
},
{
"field": "recipient",
"exposure": "atRisk"
}
]
}
}
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "defi",
"label": "DeFi",
"description": "Interop with DeFi (swaps, vaults) from within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "7d",
"sentiment": "warning",
"orderHint": 604800,
"description": "DAO-approved upgrades wait 7d before execution, so users can unshield before a change they reject.",
"walkawayTest": {
"passed": true
}
},
"referenceClient": {
"name": "RailOxide",
"repository": "https://github.com/triamazikamno/railoxide",
"commit": "8773f4ecb00c6ac7cf164ba1f989eb77dd4b0ec5"
},
"relayerTracking": {
"type": "railgunWaku",
"chainId": 1,
"sinceTimestamp": 1788134400
},
"reproducibility": {
"value": "Reproducible",
"sentiment": "good",
"description": "The contracts, circuits, and supporting software needed to participate in the protocol are publicly available and can be run locally."
},
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid spends or withdrawals.\n2. all [trusted setup](#trusted-setups) participants collude or leak their secrets, allowing forged proofs.\n3. the DAO passes a malicious [upgrade](#upgrades-and-governance) and users stay in the pool past its 7 days execution delay.\n
\n## Funds can be lost if\n1. a user loses the keys of their private balance.\n
\n## Privacy can be lost if\n1. a user sends transactions from their own public address (see public observer).\n2. elliptic-curve cryptography is broken, which decrypts every note sent to a 0zk address that was ever shared (see future adversary).",
"tokens": [
{
"token": {
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"iconUrl": "https://assets.coingecko.com/coins/images/2518/large/weth.png?1696503332",
"symbol": "WETH",
"decimals": 18,
"priceId": "weth",
"sinceTimestamp": 1573689600
},
"buckets": [
{
"id": "railgun-WETH",
"type": "pool",
"label": "WETH",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"anonymitySet": {
"minimumAmounts": [
"100000000000000000",
"10000000000000000000"
]
},
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
}
}
]
},
{
"token": {
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"iconUrl": "https://assets.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "USDT",
"decimals": 6,
"priceId": "tether",
"sinceTimestamp": 1573689600
},
"buckets": [
{
"id": "railgun-USDT",
"type": "pool",
"label": "USDT",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"anonymitySet": {
"minimumAmounts": [
"200000000",
"20000000000"
]
},
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
}
}
}
]
},
{
"token": {
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1573689600
},
"buckets": [
{
"id": "railgun-USDC",
"type": "pool",
"label": "USDC",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"anonymitySet": {
"minimumAmounts": [
"200000000",
"20000000000"
]
},
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
}
}
]
},
{
"token": {
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"iconUrl": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
"symbol": "DAI",
"decimals": 18,
"priceId": "dai",
"sinceTimestamp": 1574121600
},
"buckets": [
{
"id": "railgun-DAI",
"type": "pool",
"label": "DAI",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"anonymitySet": {
"minimumAmounts": [
"200000000000000000000",
"20000000000000000000000"
]
},
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
}
}
]
},
{
"token": {
"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
"iconUrl": "https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png?1696507857",
"symbol": "WBTC",
"decimals": 8,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1573689600
},
"buckets": [
{
"id": "railgun-WBTC",
"type": "pool",
"label": "WBTC",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
}
}
}
]
},
{
"token": {
"address": "0x85F17Cf997934a597031b2E18a9aB6ebD4B9f6a4",
"iconUrl": "https://coin-images.coingecko.com/coins/images/71681/large/near.png?1768905174",
"symbol": "NEAR",
"decimals": 24,
"priceId": "rainbow-bridged-near-ethereum",
"sinceTimestamp": 1768867200
},
"buckets": [
{
"id": "railgun-NEAR",
"type": "pool",
"label": "NEAR",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1768867200,
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0x85F17Cf997934a597031b2E18a9aB6ebD4B9f6a4"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0x85F17Cf997934a597031b2E18a9aB6ebD4B9f6a4"
}
}
}
]
},
{
"token": {
"address": "0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb",
"iconUrl": "https://coin-images.coingecko.com/coins/images/14688/large/Logo_1_%28brighter%29.png?1734430693",
"symbol": "FLUID",
"decimals": 18,
"priceId": "instadapp",
"sinceTimestamp": 1623801600
},
"buckets": [
{
"id": "railgun-FLUID",
"type": "pool",
"label": "FLUID",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb"
}
}
}
]
},
{
"token": {
"address": "0xe76C6c83af64e4C60245D8C7dE953DF673a7A33D",
"iconUrl": "https://coin-images.coingecko.com/coins/images/16840/large/railgun.jpeg?1696516407",
"symbol": "RAIL",
"decimals": 18,
"priceId": "railgun",
"sinceTimestamp": 1625270400
},
"buckets": [
{
"id": "railgun-RAIL",
"type": "pool",
"label": "RAIL",
"address": "eth:0xFA7093CDD9EE6932B4eb2c9e1cde7CE00B1FA4b9",
"sinceTimestamp": 1651422389,
"deposit": {
"event": "0x3a5b9dc26075a3801a6ddccf95fec485bb7500a91b44cec1add984c21ee6db3b",
"extractor": "railgunShield",
"params": {
"tokenAddress": "0xe76C6c83af64e4C60245D8C7dE953DF673a7A33D"
}
},
"withdrawal": {
"event": "0xd93cf895c7d5b2cd7dc7a098b678b3089f37d91f48d9b83a0800a91cbdf05284",
"extractor": "railgunUnshield",
"params": {
"tokenAddress": "0xe76C6c83af64e4C60245D8C7dE953DF673a7A33D"
}
}
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "RAIL stakers govern Railgun through a DAO. It can upgrade the core contract and its circuits, which changes the rules for every shielded token. It can also block tokens from new shields, mint RAIL and manage governance rewards. [Governance docs](https://docs.railgun.org/wiki/rail-token/protocol-governance).",
"governanceInfo": {
"upgrades": {
"Normal upgrade path": "Create a proposal with an IPFS link and onchain calldata in the [Voting contract](https://etherscan.io/address/0xc480F68A3dcC3EdD82134FAB45C14A0FcF1dA3CC) → collect **500.00 K RAIL** sponsorship within 1mo → wait 2d → cast Yay votes within 5d and Nay votes within 6d → pass with a simple majority and **2.00 M RAIL** quorum → wait 7d → permissionless execution through the Delegator within 14d.",
"Exit window": "**7d** — a passed proposal must wait this long before it can be executed, giving users time to unshield funds."
},
"tokenGovernance": {
"Governance token": "`RAIL` 1 token = 1 vote, delegated. Total supply: **60.00 M RAIL**, DAO-owned treasury (unavailable for voting): **2.30 M RAIL**, staked for voting: **41.61 M RAIL**, the rest is circulating supply.",
"Stake lock": "Unstaking has **1mo** delay.",
"Voting venue": "[Voting contract](https://etherscan.io/address/0xc480F68A3dcC3EdD82134FAB45C14A0FcF1dA3CC) on Ethereum. Proposal text is distributed over IPFS, its CID is available as a parameter of `createPropsal()` call on the voting contract.",
"Proposal threshold": "**No threshold to create a proposal.** A proposal must receive sponsorship from **500.00 K RAIL** stake within 1mo.",
"Quorum": "**2.00 M RAIL**, with a simple majority required for acceptance.",
"Execution model": "**Onchain calldata · Permissionless execution through the Delegator.** A passed proposal waits 7d, after which anyone can execute it through the [Delegator contract](https://etherscan.io/address/0xB6d513f6222Ee92Fff975E901bd792E2513fB53B) within 14d."
}
}
}
}
+1 -1
+1 -1
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides amounts, senders and the link between deposit and withdrawal inside the pool. The first payment to each new contact is public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "warning",
"exposureShort": "Transfers inside the pool are encrypted, but the first payment to each new contact writes the recipient's address in cleartext.",
"exposureContinued": "Deposits and withdrawals show address, token and amount. The fee payment names the token the user pays it in. DeFi actions name their target contract, and a shadow account shows its funding, calls and positions. A new account must be funded publicly before it can receive privately.",
"advice": "Submit every pool action through a paymaster and pay its fee in the most common token. Treat the first payment to a new contact, and any DeFi action, as public.",
"interior": {
"sender": "private",
"recipient": {
"verdict": "exposed",
"note": "Opening a channel writes the recipient address in cleartext; later transfers do not."
},
"amount": "private",
"asset": {
"verdict": "atRisk",
"note": "The fee payment names the token; DeFi actions name the target contract."
},
"linkage": "private"
},
"sources": [
{
"title": "PrivacyPool contract on Voyager",
"url": "https://voyager.online/contract/0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
{
"title": "Channel opening carries the recipient address",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/packages/privacy/src/actions.cairo#L329-L334"
},
{
"title": "Deposit and withdrawal events carry address, token and amount",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/packages/privacy/src/events.cairo#L17-L40"
}
],
"id": "publicObserver",
"value": "Link at risk",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "warning",
"exposureShort": "The set of active users is small and split further by token and by fee token.",
"exposureContinued": "A channel opened in the same transaction as a deposit ties the two together, and most withdrawal addresses have also deposited. Paying gas from the user's wallet instead of a paymaster exposes its fingerprint, account implementation and fee habits, even from a fresh address.",
"advice": "Open channels in a transaction without a deposit, pay fees in the most common token, and withdraw uneven amounts that match no deposit. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"interior": {
"sender": {
"verdict": "atRisk",
"note": "A channel opened in the same transaction as a deposit names the depositor."
},
"recipient": "exposed",
"amount": "private",
"asset": "atRisk",
"linkage": {
"verdict": "atRisk",
"note": "Most withdrawal addresses have also deposited, which pairs the two ends."
}
},
"sources": [
{
"title": "PrivacyPool contract on Voyager",
"url": "https://voyager.online/contract/0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
{
"title": "Deposit and withdrawal events carry address, token and amount",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/packages/privacy/src/events.cairo#L17-L40"
}
],
"id": "chainAnalyst",
"value": "Link at risk",
"alsoExposed": [
{
"field": "sender",
"exposure": "atRisk"
}
]
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "Ready and Xverse are closed source, so what they send to third parties is up to their makers and can change at any time.",
"exposureContinued": "Today both wallets send each action to their own servers for proving and note discovery. The paymaster receives the finished transaction before broadcast.",
"advice": "Use a client built on the open SDK with the user's own prover and note discovery, and turn on its oblivious relay.",
"interior": {
"sender": "unverifiable",
"recipient": "unverifiable",
"amount": "unverifiable",
"asset": "atRisk",
"linkage": "unverifiable"
},
"sources": [
{
"title": "Ready extension (proving and discovery on Ready servers)",
"url": "https://chromewebstore.google.com/detail/dlcobpjiigpikoobohmabehhmhfoodbb"
},
{
"title": "Xverse extension (proving and discovery on Xverse servers)",
"url": "https://chromewebstore.google.com/detail/idnnbdplmphpflfnlkomgpfbpcgelopg"
},
{
"title": "The SDK takes prover and discovery endpoints from the client",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/sdk/src/factory.ts#L45-L62"
},
{
"title": "Oblivious relay is an option of the proving client",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/sdk/src/internal/proving-service-provider.ts#L73-L80"
}
],
"id": "networkObserver",
"value": "Link at risk",
"alsoExposed": [
{
"field": "sender",
"exposure": "unverifiable"
},
{
"field": "amount",
"exposure": "unverifiable"
}
]
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "Every user's viewing key is escrowed onchain, encrypted to one auditor key that a role holder can replace at any time with no delay.",
"exposureContinued": "The wallet's prover receives the user's viewing key with every action, and for most Ready accounts Ready's servers create that key. Apps that drive a shadow account or a swap through the pool get the user's main address from the wallet connection. The holder of the screener key can block any screened depositor.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Viewing key escrowed to the auditor key onchain",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/packages/privacy/src/events.cairo#L5-L13"
},
{
"title": "Proving request carries the viewing key",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/sdk/src/internal/proof-invocation-factory.ts#L132-L136"
},
{
"title": "Deposits require a screening attestation",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/packages/privacy/src/interface.cairo#L530-L545"
},
{
"title": "The wallet API hands the connected account to the app",
"url": "https://github.com/starknet-io/types-js/blob/0b483f51f4bc33c7253b209a25136d9d6ec1bc41/src/wallet-api/methods.ts#L42-L51"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
},
{
"field": "asset",
"exposure": "exposed"
}
]
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "The proofs rest only on hashes, the encryption on elliptic curves.",
"exposureContinued": "Channel keys, note contents and the auditor escrow all use this encryption. Whoever breaks elliptic-curve cryptography recovers the auditor key from its onchain public key, and with it every escrowed viewing key and the whole history.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Stark-curve ECDH encryption of channel and note data",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/sdk/src/utils/encryptions.ts"
},
{
"title": "Viewing key escrowed under the onchain auditor public key",
"url": "https://github.com/starkware-libs/starknet-privacy/blob/fcc7c90f544ceb08621c32616bde29f1fdcbeb54/packages/privacy/src/events.cairo#L5-L13"
},
{
"title": "Auditor public key in pool storage",
"url": "https://voyager.online/contract/0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
}
],
"id": "futureAdversary",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
},
{
"field": "asset",
"exposure": "exposed"
}
]
}
}
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "defi",
"label": "DeFi",
"description": "Interop with DeFi (swaps, vaults) from within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "The pool and the anonymizer that owns every shadow account are immediately upgradeable, so users have no delay to withdraw before a malicious upgrade can take effect.",
"walkawayTest": {
"passed": false,
"reason": "Although the full software stack needed to generate proofs and exit is published and self-hostable, STRK-20 heavily relies on the permissioned Starknet sequencer: it alone verifies client proofs and must include pool transactions, so users cannot exit without its cooperation."
}
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The pool contract, SDK, discovery service and prover are open source. The deployed pool, anonymizer and bridge helpers rebuild from their published source. Source for the AVNU, Endur and escrow helpers is not published, and the wallets are closed."
},
"riskSummary": "## Funds can be stolen if\n1. the proof system or virtual Starknet execution model is broken, allowing invalid actions.\n2. the Starknet sequencer includes a transaction with fabricated proof facts.\n3. a multisig deploys a malicious pool upgrade, which takes effect without delay.\n4. an external DeFi helper or target protocol invoked by the user mishandles assets.\n5. a multisig upgrades the anonymizer, which takes effect without delay and can move everything shadow accounts hold (see [upgrades and governance](#upgrades-and-governance)).\n
\n## Funds can be lost if\n1. a user loses the Starknet account key or viewing key required to spend their notes.\n2. the pool is paused or upgraded so that valid actions fail.\n
\n## Privacy can be lost if\n1. the holder of the auditor key decrypts users' viewing keys, which exposes their whole history (see privileged insider).\n2. the wallet's prover or note discovery service, which receives the viewing key with every action, leaks or keeps it (see privileged insider).\n3. an app driving a shadow account or a swap through the pool links it to the user's main address (see privileged insider).\n4. a first payment to a new contact, a channel opened beside a deposit or a unique amount links activity (see public observer, chain analyst).\n5. elliptic-curve cryptography is broken, which opens the auditor key and with it every user's history (see future adversary).",
"riskSummary": "## Funds can be stolen if\n1. the proof system or virtual Starknet execution model is broken, allowing invalid actions.\n2. the Starknet sequencer includes a transaction with fabricated proof facts.\n3. a multisig deploys a malicious pool upgrade, which takes effect without delay.\n4. an external DeFi helper or target protocol invoked by the user mishandles assets.\n5. a multisig upgrades the anonymizer, which takes effect without delay and can move everything shadow accounts hold (see [upgrades and governance](#upgrades-and-governance)).\n
\n## Funds can be lost if\n1. a user loses the Starknet account key or viewing key required to spend their notes.\n2. the pool is paused or upgraded so that valid actions fail.\n
\n## Privacy can be lost if\n1. the holder of the auditor key decrypts users' viewing keys, which exposes their whole history (see privileged insider).\n2. the wallet's prover or note discovery service, which receives the viewing key with every action, leaks or keeps it (see privileged insider).\n3. an app driving a shadow account or a swap through the pool links it to the user's main address (see privileged insider).\n4. a first payment to a new contact, a channel opened beside a deposit or a unique amount links activity (see public observer and chain analyst).\n5. Ready or Xverse, both closed source, change what they send to third parties, which users cannot check (see network observer).\n6. elliptic-curve cryptography is broken, which opens the auditor key and with it every user's history (see future adversary).",
"tokens": [
{
"token": {
"address": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
"iconUrl": "https://assets.coingecko.com/coins/images/26433/large/starknet.png?1696525507",
"symbol": "STRK",
"decimals": 18,
"priceId": "starknet",
"sinceTimestamp": 1776679728
},
"buckets": [
{
"id": "strk20-STRK",
"type": "pool",
"label": "STRK pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1776679728,
"anonymitySet": {
"minimumAmounts": [
"5000000000000000000000",
"500000000000000000000000"
]
},
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d"
}
}
}
]
},
{
"token": {
"address": "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696501661",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1776679728
},
"buckets": [
{
"id": "strk20-USDC",
"type": "pool",
"label": "USDC pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1776679728,
"anonymitySet": {
"minimumAmounts": [
"200000000",
"20000000000"
]
},
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x033068f6539f8e6e6b131e6b2b814e6c34a5224bc66947c47dab9dfee93b35fb"
}
}
}
]
},
{
"token": {
"address": "0x0787150e306e6eae6e3f79dea881770e8bbff2c1b8eb490f969669ee945b3135",
"iconUrl": "https://coin-images.coingecko.com/coins/images/102173511/large/strkBTC_Logo.png?1779888214",
"symbol": "strkBTC",
"decimals": 8,
"priceId": "strkbtc",
"sinceTimestamp": 1777893725
},
"buckets": [
{
"id": "strk20-strkBTC",
"type": "pool",
"label": "strkBTC pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1777893725,
"anonymitySet": {
"minimumAmounts": [
"250000",
"25000000"
]
},
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x0787150e306e6eae6e3f79dea881770e8bbff2c1b8eb490f969669ee945b3135"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x0787150e306e6eae6e3f79dea881770e8bbff2c1b8eb490f969669ee945b3135"
}
}
}
]
},
{
"token": {
"address": "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac",
"iconUrl": "https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png?1696507857",
"symbol": "WBTC",
"decimals": 8,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1776679728
},
"buckets": [
{
"id": "strk20-WBTC",
"type": "pool",
"label": "WBTC pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1776679728,
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac"
}
}
}
]
},
{
"token": {
"address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"symbol": "ETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1776679728
},
"buckets": [
{
"id": "strk20-ETH",
"type": "pool",
"label": "ETH pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1776679728,
"anonymitySet": {
"minimumAmounts": [
"100000000000000000",
"10000000000000000000"
]
},
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"
}
}
}
]
},
{
"token": {
"address": "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a",
"iconUrl": "https://assets.coingecko.com/coins/images/54172/standard/logo200x200.png?1738561141",
"symbol": "XSTRK",
"decimals": 18,
"priceId": "endur-fi-staked-strk",
"sinceTimestamp": 1776679728
},
"buckets": [
{
"id": "strk20-XSTRK",
"type": "pool",
"label": "XSTRK pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1776679728,
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x028d709c875c0ceac3dce7065bec5328186dc89fe254527084d1689910954b0a"
}
}
}
]
},
{
"token": {
"address": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8",
"iconUrl": "https://assets.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"decimals": 6,
"symbol": "USDT",
"priceId": "tether",
"sinceTimestamp": 1776679728
},
"buckets": [
{
"id": "strk20-USDT",
"type": "pool",
"label": "USDT pool",
"address": {
"chain": "starknet",
"address": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a"
},
"sinceTimestamp": 1776679728,
"anonymitySet": {
"minimumAmounts": [
"200000000",
"20000000000"
]
},
"deposit": {
"event": "0x9149d2123147c5f43d258257fef0b7b969db78269369ebcf5ebb9eef8592f2",
"extractor": "strk20Deposit",
"params": {
"tokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8"
}
},
"withdrawal": {
"event": "0x2eed7e29b3502a726faf503ac4316b7101f3da813654e8df02c13449e03da8",
"extractor": "strk20Withdrawal",
"params": {
"tokenAddress": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8"
}
}
}
]
}
],
"trackedOn": [
"starknet"
],
"upgradesAndGovernance": {
"content": "A 7/12 multisig holds the pool's governance, security and upgrade roles and can replace the pool's code at once. It and a 2/4 multisig both hold the app role, which sets the fee, the fee collector, the proof validity window and which DeFi helpers need screening. The 2/4 also owns a delayed executor that holds the upgrade role behind a one-day delay. The security governor role, held by the 7/12, can replace the auditor and screener keys at once. Pausing needs a role nobody holds today, which the 7/12 can grant.\n\nThe anonymizer has no upgrade delay. A 1/3 multisig holds its governance and upgrade roles, and the 7/12 can upgrade it too."
},
"zkCatalogId": "stwo"
}
+7 -6
+7 -6
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which deposit funds which withdrawal. Everything else is public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Each pool has one fixed amount and no in-pool transfers, so every withdrawal spends exactly one deposit.",
"advice": "Exit through a relayer, so none of the user's wallets pay gas for the receiving address.",
"sources": [
{
"contract": "Pool_1_ETH",
"title": "1 ETH pool"
},
{
"title": "Withdrawal circuit",
"url": "https://github.com/tornadocash/tornado-core/blob/a533ad9ffb62163a42d4fa9a09984c5dd4e5c41d/circuits/withdraw.circom"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "A relayed withdrawal hides among all unspent deposits of its pool, the anonymity set, which differs sharply between pools.",
"exposureContinued": "Timing, address reuse and relayer choice narrow it further. Paying gas from the user's wallet instead of a relayer exposes its fingerprint, account implementation and fee habits, even from a fresh address.",
"advice": "Use a pool with a large anonymity set. Deposit and withdraw several notes at different times, not in batches. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"sources": [
{
"contract": "Pool_1_ETH",
"title": "withdraw: any relayer, paid from the withdrawn amount"
},
{
"title": "Tutela (arXiv:2201.06811)",
"url": "https://arxiv.org/abs/2201.06811"
},
{
"title": "Blockchain is Watching You (arXiv:2005.14051)",
"url": "https://arxiv.org/abs/2005.14051"
}
],
"id": "chainAnalyst",
"value": "Link private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "good",
"exposureShort": "The app works in Tor Browser and downloads every deposit of a pool, so its services learn the pool but never the user's note.",
"exposureContinued": "Every listed relayer gets a status request, and the chosen one receives the finished withdrawal.",
"advice": "Read the chain from the user's own node, send through a public RPC over Tor, and use a popular relayer. If using a VPN instead of Tor, choose a trusted provider: it hides the user's IP from the relayer but sees it itself. Withdraw without connecting a wallet.",
"advice": "Use the app in Tor Browser and withdraw through a popular relayer without connecting a wallet.",
"sources": [
{
"title": "Deposits fetched per pool and matched locally",
"url": "https://github.com/tornado-dao/classic-ui/blob/17c54dae9ad91bb3c6d62a7860df6cd365ab76d4/services/events.js#L90-L115"
},
{
"title": "The relayer receives only the finished withdrawal",
"url": "https://github.com/tornado-dao/classic-ui/blob/17c54dae9ad91bb3c6d62a7860df6cd365ab76d4/store/relayer.js#L430-L460"
},
{
"title": "Custom RPC setting",
"url": "https://github.com/tornado-dao/classic-ui/blob/17c54dae9ad91bb3c6d62a7860df6cd365ab76d4/components/Settings.vue#L8-L50"
},
{
"title": "Only withdrawals without a relayer need a wallet",
"url": "https://github.com/tornado-dao/classic-ui/blob/17c54dae9ad91bb3c6d62a7860df6cd365ab76d4/components/withdraw/Withdraw.vue#L224-L226"
}
],
"id": "networkObserver",
"value": "Link private",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "good",
"exposureShort": "The pools cannot be paused, upgraded or made to reveal anything.",
"exposureContinued": "Token governance controls the app pinned on tornadocash.eth, the router's pool list and the relayer list. Every change waits at least 7 days from proposal to execution.",
"advice": "Load the app from the IPFS hash on tornadocash.eth through the user's own IPFS node. Run an inspected local build of the client instead of the hosted frontend.",
"sources": [
{
"contract": "Pool_0.1_ETH",
"title": "0.1 ETH pool (no operator)"
},
{
"section": "upgrades-and-governance"
},
{
"title": "Build recipe that recomputes the pinned app's IPFS hash",
"url": "https://github.com/tornado-dao/tornado-ipfs-ui"
}
],
"id": "privilegedInsider",
"value": "Link private",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "warning",
"exposureShort": "Commitments use a Pedersen hash on an elliptic curve.",
"exposureContinued": "Whoever breaks elliptic-curve cryptography could test whether a given deposit can fund a withdrawal, shrinking the candidate set without singling out one deposit. Notes backed up onchain are encrypted with elliptic-curve keys and become readable.",
"advice": "Keep the note on the user's device and leave the onchain backup off.",
"sources": [
{
"title": "Pedersen hash circuit (pinned circomlib fork)",
"url": "https://github.com/tornadocash/circomlib/blob/c372f14d324d57339c88451834bf2824e73bbdbc/circuits/pedersen.circom"
},
{
"title": "Commitment and nullifier hashing",
"url": "https://github.com/tornadocash/tornado-core/blob/a533ad9ffb62163a42d4fa9a09984c5dd4e5c41d/circuits/withdraw.circom"
},
{
"contract": "TornadoRouter",
"title": "Onchain note backups"
}
],
"id": "futureAdversary",
"value": "Link at risk",
"alsoExposed": []
}
}
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "fixedAmounts",
"label": "Fixed amounts",
"description": "Pre-defined transfer amounts use distinct buckets (anonymity sets)."
}
],
"category": {
"id": "pool",
"label": "Pool",
"description": "Funds enter a shared pool and leave it later, with no actions inside. Hides which deposit became which withdrawal."
},
"exitWindow": {
"value": "Infinite",
"sentiment": "good",
"orderHint": 9007199254740991,
"description": "The core Tornado Cash contracts are immutable and have no admin upgrade path, so users can always withdraw with a valid note and proof.",
"walkawayTest": {
"passed": true
}
},
"referenceClient": {
"name": "Tornado Cash classic app",
"repository": "https://github.com/tornado-dao/classic-ui",
"commit": "17c54dae9ad91bb3c6d62a7860df6cd365ab76d4"
},
"relayerTracking": {
"type": "onchainEvents",
"sources": [
{
"address": "eth:0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc",
"sinceTimestamp": 1576523323,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936",
"sinceTimestamp": 1576534673,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF",
"sinceTimestamp": 1576536415,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0xA160cdAB225685dA1d56aa342Ad8841c3b53f291",
"sinceTimestamp": 1577296976,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3",
"sinceTimestamp": 1576534688,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144",
"sinceTimestamp": 1577297383,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x07687e702b410Fa43f4cB4Af7FA097918ffD2730",
"sinceTimestamp": 1616114822,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x23773E65ed146A459791799d01336DB287f25334",
"sinceTimestamp": 1616115387,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x22aaA7720ddd5388A3c0A3333430953C68f1849b",
"sinceTimestamp": 1577297782,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x03893a7c7463AE47D46bc7f091665f1893656003",
"sinceTimestamp": 1616155055,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x2717c5e28cf931547B621a5dddb772Ab6A35B701",
"sinceTimestamp": 1616135923,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af",
"sinceTimestamp": 1616115450,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0xd96f2B1c14Db8458374d9Aca76E26c3D18364307",
"sinceTimestamp": 1577298068,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D",
"sinceTimestamp": 1577298155,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x169AD27A470D064DEDE56a2D3ff727986b15D52B",
"sinceTimestamp": 1577298900,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f",
"sinceTimestamp": 1577298985,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x178169B423a011fff22B9e3F3abeA13414dDD0F1",
"sinceTimestamp": 1616134868,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0x610B717796ad172B316836AC95a2ffad065CeaB4",
"sinceTimestamp": 1616123193,
"extractor": "tornadoCashWithdrawal"
},
{
"address": "eth:0xbB93e510BbCD0B7beb5A853875f9eC60275CF498",
"sinceTimestamp": 1616135758,
"extractor": "tornadoCashWithdrawal"
}
]
},
"reproducibility": {
"value": "Reproducible",
"sentiment": "good",
"description": "The circuits, contracts, app and relayer are open source. Each app release names its commit and a build recipe for its IPFS hash, and rebuilding the current release reproduces it."
},
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid withdrawals.\n2. the [trusted setup](#trusted-setups) is compromised or all ceremony participants collude, allowing invalid withdrawals.\n3. governance pins a malicious app on tornadocash.eth, which can steal the notes, and with them the funds, of users who load it (see privileged insider).\n
\n## Funds can be lost if\n1. a user loses the note required to withdraw.\n
\n## Privacy can be lost if\n1. elliptic-curve cryptography is broken, which lets an attacker test candidate deposits for each withdrawal and read notes backed up onchain (see future adversary).",
"riskSummary": "## Funds can be stolen if\n1. the zk proof system is broken, allowing invalid withdrawals.\n2. all [trusted setup](#trusted-setups) participants collude or leak their secrets, allowing forged proofs.\n3. governance pins a malicious app on tornadocash.eth, which can steal the notes, and with them the funds, of users who load it (see privileged insider).\n
\n## Funds can be lost if\n1. a user loses the note required to withdraw.\n
\n## Privacy can be lost if\n1. elliptic-curve cryptography is broken, which lets an attacker test candidate deposits for each withdrawal and read notes backed up onchain (see future adversary).",
"tokens": [
{
"token": {
"address": "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643",
"iconUrl": "https://assets.coingecko.com/coins/images/9281/large/cDAI.png?1696509390",
"symbol": "cDAI",
"decimals": 8,
"priceId": "cdai",
"sinceTimestamp": 1577297782
},
"buckets": [
{
"id": "tornado-cDAI-5000",
"type": "denomination",
"label": "cDAI 5000",
"address": "eth:0x22aaA7720ddd5388A3c0A3333430953C68f1849b",
"sinceTimestamp": 1577297782,
"denomination": "5000",
"anonymitySet": {
"minimumAmounts": [
"500000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "500000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "500000000000"
}
}
},
{
"id": "tornado-cDAI-50000",
"type": "denomination",
"label": "cDAI 50000",
"address": "eth:0x03893a7c7463AE47D46bc7f091665f1893656003",
"sinceTimestamp": 1616155055,
"denomination": "50000",
"anonymitySet": {
"minimumAmounts": [
"5000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "5000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "5000000000000"
}
}
},
{
"id": "tornado-cDAI-500000",
"type": "denomination",
"label": "cDAI 500000",
"address": "eth:0x2717c5e28cf931547B621a5dddb772Ab6A35B701",
"sinceTimestamp": 1616135923,
"denomination": "500000",
"anonymitySet": {
"minimumAmounts": [
"50000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "50000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "50000000000000"
}
}
},
{
"id": "tornado-cDAI-5000000",
"type": "denomination",
"label": "cDAI 5000000",
"address": "eth:0xD21be7248e0197Ee08E0c20D4a96DEBdaC3D20Af",
"sinceTimestamp": 1616115450,
"denomination": "5000000",
"anonymitySet": {
"minimumAmounts": [
"500000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "500000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "500000000000000"
}
}
}
]
},
{
"token": {
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"iconUrl": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
"symbol": "DAI",
"decimals": 18,
"priceId": "dai",
"sinceTimestamp": 1576534688
},
"buckets": [
{
"id": "tornado-DAI-100",
"type": "denomination",
"label": "DAI 100",
"address": "eth:0xD4B88Df4D29F5CedD6857912842cff3b20C8Cfa3",
"sinceTimestamp": 1576534688,
"denomination": "100",
"anonymitySet": {
"minimumAmounts": [
"100000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000000"
}
}
},
{
"id": "tornado-DAI-1000",
"type": "denomination",
"label": "DAI 1000",
"address": "eth:0xFD8610d20aA15b7B2E3Be39B396a1bC3516c7144",
"sinceTimestamp": 1577297383,
"denomination": "1000",
"anonymitySet": {
"minimumAmounts": [
"1000000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000000000000000"
}
}
},
{
"id": "tornado-DAI-10000",
"type": "denomination",
"label": "DAI 10000",
"address": "eth:0x07687e702b410Fa43f4cB4Af7FA097918ffD2730",
"sinceTimestamp": 1616114822,
"denomination": "10000",
"anonymitySet": {
"minimumAmounts": [
"10000000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "10000000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "10000000000000000000000"
}
}
},
{
"id": "tornado-DAI-100000",
"type": "denomination",
"label": "DAI 100000",
"address": "eth:0x23773E65ed146A459791799d01336DB287f25334",
"sinceTimestamp": 1616115387,
"denomination": "100000",
"anonymitySet": {
"minimumAmounts": [
"100000000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000000000"
}
}
}
]
},
{
"token": {
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"symbol": "ETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1576523323
},
"buckets": [
{
"id": "tornado-ETH-0.1",
"type": "denomination",
"label": "ETH 0.1",
"address": "eth:0x12D66f87A04A9E220743712cE6d9bB1B5616B8Fc",
"sinceTimestamp": 1576523323,
"denomination": "0.1",
"anonymitySet": {
"minimumAmounts": [
"100000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000"
}
}
},
{
"id": "tornado-ETH-1",
"type": "denomination",
"label": "ETH 1",
"address": "eth:0x47CE0C6eD5B0Ce3d3A51fdb1C52DC66a7c3c2936",
"sinceTimestamp": 1576534673,
"denomination": "1",
"anonymitySet": {
"minimumAmounts": [
"1000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000000000000"
}
}
},
{
"id": "tornado-ETH-10",
"type": "denomination",
"label": "ETH 10",
"address": "eth:0x910Cbd523D972eb0a6f4cAe4618aD62622b39DbF",
"sinceTimestamp": 1576536415,
"denomination": "10",
"anonymitySet": {
"minimumAmounts": [
"10000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "10000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "10000000000000000000"
}
}
},
{
"id": "tornado-ETH-100",
"type": "denomination",
"label": "ETH 100",
"address": "eth:0xA160cdAB225685dA1d56aa342Ad8841c3b53f291",
"sinceTimestamp": 1577296976,
"denomination": "100",
"anonymitySet": {
"minimumAmounts": [
"100000000000000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000000000000000"
}
}
}
]
},
{
"token": {
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1577298068
},
"buckets": [
{
"id": "tornado-USDC-100",
"type": "denomination",
"label": "USDC 100",
"address": "eth:0xd96f2B1c14Db8458374d9Aca76E26c3D18364307",
"sinceTimestamp": 1577298068,
"denomination": "100",
"anonymitySet": {
"minimumAmounts": [
"100000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000"
}
}
},
{
"id": "tornado-USDC-1000",
"type": "denomination",
"label": "USDC 1000",
"address": "eth:0x4736dCf1b7A3d580672CcE6E7c65cd5cc9cFBa9D",
"sinceTimestamp": 1577298155,
"denomination": "1000",
"anonymitySet": {
"minimumAmounts": [
"1000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000"
}
}
}
]
},
{
"token": {
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"iconUrl": "https://assets.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "USDT",
"decimals": 6,
"priceId": "tether",
"sinceTimestamp": 1577298900
},
"buckets": [
{
"id": "tornado-USDT-100",
"type": "denomination",
"label": "USDT 100",
"address": "eth:0x169AD27A470D064DEDE56a2D3ff727986b15D52B",
"sinceTimestamp": 1577298900,
"denomination": "100",
"anonymitySet": {
"minimumAmounts": [
"100000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000"
}
}
},
{
"id": "tornado-USDT-1000",
"type": "denomination",
"label": "USDT 1000",
"address": "eth:0x0836222F2B2B24A3F36f98668Ed8F0B38D1a872f",
"sinceTimestamp": 1577298985,
"denomination": "1000",
"anonymitySet": {
"minimumAmounts": [
"1000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000"
}
}
}
]
},
{
"token": {
"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
"iconUrl": "https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png?1696507857",
"symbol": "WBTC",
"decimals": 8,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1616123193
},
"buckets": [
{
"id": "tornado-WBTC-0.1",
"type": "denomination",
"label": "WBTC 0.1",
"address": "eth:0x178169B423a011fff22B9e3F3abeA13414dDD0F1",
"sinceTimestamp": 1616134868,
"denomination": "0.1",
"anonymitySet": {
"minimumAmounts": [
"10000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "10000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "10000000"
}
}
},
{
"id": "tornado-WBTC-1",
"type": "denomination",
"label": "WBTC 1",
"address": "eth:0x610B717796ad172B316836AC95a2ffad065CeaB4",
"sinceTimestamp": 1616123193,
"denomination": "1",
"anonymitySet": {
"minimumAmounts": [
"100000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "100000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "100000000"
}
}
},
{
"id": "tornado-WBTC-10",
"type": "denomination",
"label": "WBTC 10",
"address": "eth:0xbB93e510BbCD0B7beb5A853875f9eC60275CF498",
"sinceTimestamp": 1616135758,
"denomination": "10",
"anonymitySet": {
"minimumAmounts": [
"1000000000"
]
},
"deposit": {
"event": "0xa945e51eec50ab98c161376f0db4cf2aeba3ec92755fe2fcd388bdbbb80ff196",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000"
}
},
"withdrawal": {
"event": "0xe9e508bad6d4c3227e881ca19068f099da81b5164dd6d62b2eaf1e8bc6c34931",
"extractor": "fixedAmount",
"params": {
"amount": "1000000000"
}
}
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "TORN holders govern through the Governance contract, after a vote and a timelock. They cannot change the pools. They control the InstanceRegistry the router reads its pool list from, the RelayerRegistry, the FeeManager, the TORN token and the IPFS hash of the app on tornadocash.eth. A malicious registry upgrade could steal tokens users approved to the router. A malicious app could steal the notes of users who load it. Removing relayers from the registry hides them from the app, while the pools still accept any relayer.",
"governanceInfo": {
"upgrades": {
"Normal upgrade path": "Lock and optionally delegate TORN in the [Governance contract](https://etherscan.io/address/0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce) → submit a proposal with at least **1.00 K TORN** → wait 1m 15s → vote for 5d (extended by 6h if the outcome changes during the last 1h) → pass with a simple majority and **100.00 K TORN** quorum → wait 2d → permissionless execution within 3d. The DAO controls protocol and periphery components, but cannot upgrade or modify existing pools.",
"Exit window": "**2d** for DAO-controlled changes — an accepted proposal remains timelocked for this period before it can be executed. Existing Tornado Cash pools are immutable and cannot be upgraded by the DAO."
},
"tokenGovernance": {
"Governance token": "`TORN`, 1 token = 1 vote, delegated. Total supply: **9.99 M TORN**, DAO-owned TORN (unavailable for voting): **4.73 M TORN**, staked for voting: **2.57 M TORN**, the rest is circulating supply.",
"Stake lock": "After voting or proposing, staked tokens are locked for **5d 6h** after proposal ends, preventing governance hopping.",
"Voting venue": "[Governance contract](https://etherscan.io/address/0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce) on Ethereum. Proposals are viewable on the governance page of the app, see the App section above.",
"Proposal threshold": "**1.00 K TORN** locked in governance.",
"Quorum": "**100.00 K TORN**, with a simple majority required for acceptance.",
"Execution model": "**Permissionless execution after an onchain vote and timelock.** An accepted proposal waits 2d and can then be executed by anyone within 3d. Proposal executable payload is committed in the `propose()` transaction."
}
}
}
}
+6 -1
+6 -1
{
"adversaries": {
"promise": {
"protects": "recipient",
"text": "Hides which registered recipient a stealth payment is for. The payer knows; sender, asset, amount and where the funds go next are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Each payment goes to a fresh stealth address, and only the recipient's viewing key shows whose it is.",
"exposureContinued": "The registry lists every recipient who could be behind it, with their key history.",
"advice": "Withdraw to a fresh address that is not registered and has no public link to the user.",
"sources": [
{
"contract": "Umbra",
"title": "Announcement and TokenWithdrawal publish the fund path"
},
{
"contract": "StealthKeyRegistry",
"title": "StealthKeyChanged publishes recipients and key changes"
},
{
"title": "Matching decrypts the secret with the viewing key and checks the stealth address",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/classes/Umbra.ts#L707-L721"
}
],
"id": "publicObserver",
"value": "Recipient private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "Any of the 11,983 registered recipients could be behind a stealth address.",
"exposureContinued": "Registrations are rare and public, so a payment that lands minutes after one points to that registrant. Several payments withdrawn to one address share a recipient.",
"advice": "Register long before anyone pays the user, and withdraw each payment to its own address. Exit through a relayer for tokens, so none of the user's wallets pay gas for the receiving address.",
"sources": [
{
"contract": "StealthKeyRegistry",
"title": "Each registration is public with its block"
},
{
"title": "Kovács and Seres: reuse heuristics and their reach on mainnet (sections 6 and 7)",
"url": "https://arxiv.org/html/2308.01703v2#S6"
},
{
"title": "The app warns about registered, named and sender destinations, and lets the user proceed",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/utils/address.ts#L146-L241"
}
],
"id": "chainAnalyst",
"value": "Recipient private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "The hosted app checks the payee's address with its Alchemy RPC seconds before each payment, so timing ties the payee to the payment.",
"exposureContinued": "When the payee withdraws, the same RPC receives their wallet address and the withdrawal address in one session. The wallet's own RPC receives the wallet address together with the matched stealth addresses. On connect, the wallet library also sends the user's wallet address to Cloudflare's RPC to look up its ENS name.",
"advice": "Pay and withdraw from a local build with all RPC URLs and the user's wallet pointed at their own node, and block cloudflare-eth.com.",
"sources": [
{
"title": "Sending checks the recipient against a sanctions list through the app's mainnet RPC",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/classes/Umbra.ts#L219-L227"
},
{
"title": "Connecting checks the wallet address through the same RPC",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/store/wallet.ts#L273"
},
{
"title": "Withdrawing checks the destination through the same RPC",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/components/AccountReceiveTable.vue#L736"
},
{
"title": "Matched stealth addresses go to the wallet RPC in one balance call",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/components/AccountReceiveTable.vue#L606-L625"
}
],
"id": "networkObserver",
"value": "Recipient at risk",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "warning",
"exposureShort": "The hosted app gives the operator the user's wallet address on every scan and withdrawal address in the same session.",
"exposureContinued": "Token withdrawals also hand its relayer the stealth address. The operator serves the app and can change it at any time. The contracts are immutable, and only the user holds their viewing key.",
"advice": "Run an inspected local build of the client instead of the hosted frontend. Leave its indexer URL empty, so it reads payments from the user's node.",
"sources": [
{
"title": "Each scan first asks the indexer for the connected wallet's registration",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/utils/utils.ts#L336-L349"
},
{
"title": "The registry read stores no block, so the lookup repeats on every scan",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/store/wallet.ts#L605-L615"
},
{
"title": "Every withdrawal sends the destination to the operator's API",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/utils/address.ts#L201-L214"
},
{
"title": "Token withdrawals send the stealth address to the relayer",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/components/AccountReceiveTable.vue#L767-L768"
}
],
"id": "privilegedInsider",
"value": "Recipient at risk",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "Whoever breaks elliptic-curve cryptography matches every past payment to its registered recipient from chain data alone.",
"exposureContinued": "The registry holds each recipient's public keys, and each announcement the payer's one-time key and the encrypted secret. Recovering the private keys decrypts the secret and confirms the stealth address.",
"sources": [
{
"contract": "Umbra",
"title": "Announcement archives the one-time key and ciphertext"
},
{
"contract": "StealthKeyRegistry",
"title": "Historical public viewing and spending keys"
},
{
"title": "A shared secret from elliptic-curve keys encrypts the secret",
"url": "https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/classes/KeyPair.ts#L121-L157"
}
],
"id": "futureAdversary",
"value": "Recipient exposed",
"alsoExposed": []
}
}
},
"anonymitySet": {
"type": "key-registrations",
"registry": "eth:0x31fe56609C65Cd0C510E7125f051D440424D38f3",
"sinceTimestamp": 1629943007,
"event": "0xe879dede910dd3b22239a11044df83c95adcd4b54003516f42866cc1fe4f0a19",
"extractor": "umbraStealthKeyChanged"
},
"attributes": [
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
},
{
"id": "stealthAddresses",
"label": "Stealth addresses",
"description": "Uses fresh, one-time recipient addresses to obscure who controls the receiving address."
}
],
"category": {
"id": "stealthAddress",
"label": "Stealth address",
"description": "Payments land on fresh one-time addresses. Hides which recipient a payment is for."
},
"exitWindow": {
"value": "Infinite",
"sentiment": "good",
"orderHint": 9007199254740991,
"description": "The contracts are immutable. The toll applies only to new payments, so recipients can always withdraw what they received.",
"walkawayTest": {
"passed": true
}
},
"referenceClient": {
"name": "Umbra app",
"repository": "https://github.com/ScopeLift/umbra-protocol",
"commit": "947c4f3b9b89f6cf5d69b2d43d3cffec673da655"
},
"reproducibility": {
"value": "Reproducible",
"sentiment": "good",
"description": "The contracts, the umbra-js library and the frontend are open source and build locally. The indexer and the relayer API behind the hosted app are closed."
},
"riskSummary": "## Funds can be lost if\n1. an unsupported ERC-20, such as a fee-on-transfer or rebasing token, causes the Umbra contract's internal accounting to diverge from its token balance.\n
\n## Privacy can be lost if\n1. the operator links the user's wallet to their stealth addresses, since the hosted app sends it both in one session (see privileged insider).\n2. Alchemy, the hosted app's RPC, receives the payee's address seconds before each payment, so timing ties the payee to it (see network observer).\n3. elliptic-curve cryptography is broken, which matches every past payment to its registered recipient (see future adversary).\n
\n## New payments can be stopped if\n1. the Umbra owner raises the toll on payments through the contract, which has no cap.",
"riskSummary": "## Funds can be lost if\n1. an unsupported ERC-20, such as a fee-on-transfer or rebasing token, causes the Umbra contract's internal accounting to diverge from its token balance.\n
\n## Use can be stopped if\n1. the Umbra owner raises the toll on payments through the contract, which has no cap.\n
\n## Privacy can be lost if\n1. the operator links the user's wallet to their stealth addresses, since the hosted app sends it both in one session (see privileged insider).\n2. Alchemy, the hosted app's RPC, receives the payee's address seconds before each payment, so timing ties the payee to it (see network observer).\n3. elliptic-curve cryptography is broken, which matches every past payment to its registered recipient (see future adversary).",
"tokens": [
{
"token": {
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"iconUrl": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
"symbol": "DAI",
"decimals": 18,
"priceId": "dai",
"sinceTimestamp": 1619813937
},
"buckets": [
{
"id": "umbra-DAI",
"type": "pool",
"label": "DAI",
"address": "eth:0xFb2dc580Eed955B528407b4d36FfaFe3da685401",
"sinceTimestamp": 1619813937,
"deposit": {
"event": "0x29877766fa2bfe3b90008d6d92f965eca91cbc5757ed775740e460799fb92219",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
},
"withdrawal": {
"event": "0x30eb3583ad09933b693a45452ab07512244cdbc5868701aa004c27b7b267c249",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F"
}
}
}
]
},
{
"token": {
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"symbol": "ETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1619813937
},
"buckets": [
{
"id": "umbra-ETH",
"type": "pool",
"label": "ETH",
"address": "eth:0xFb2dc580Eed955B528407b4d36FfaFe3da685401",
"sinceTimestamp": 1619813937,
"deposit": {
"event": "0x29877766fa2bfe3b90008d6d92f965eca91cbc5757ed775740e460799fb92219",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
}
},
"withdrawal": {
"event": "0x29877766fa2bfe3b90008d6d92f965eca91cbc5757ed775740e460799fb92219",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
}
}
}
]
},
{
"token": {
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1619813937
},
"buckets": [
{
"id": "umbra-USDC",
"type": "pool",
"label": "USDC",
"address": "eth:0xFb2dc580Eed955B528407b4d36FfaFe3da685401",
"sinceTimestamp": 1619813937,
"deposit": {
"event": "0x29877766fa2bfe3b90008d6d92f965eca91cbc5757ed775740e460799fb92219",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
},
"withdrawal": {
"event": "0x30eb3583ad09933b693a45452ab07512244cdbc5868701aa004c27b7b267c249",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
}
}
}
]
},
{
"token": {
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"iconUrl": "https://assets.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "USDT",
"decimals": 6,
"priceId": "tether",
"sinceTimestamp": 1619813937
},
"buckets": [
{
"id": "umbra-USDT",
"type": "pool",
"label": "USDT",
"address": "eth:0xFb2dc580Eed955B528407b4d36FfaFe3da685401",
"sinceTimestamp": 1619813937,
"deposit": {
"event": "0x29877766fa2bfe3b90008d6d92f965eca91cbc5757ed775740e460799fb92219",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
}
},
"withdrawal": {
"event": "0x30eb3583ad09933b693a45452ab07512244cdbc5868701aa004c27b7b267c249",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7"
}
}
}
]
},
{
"token": {
"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
"iconUrl": "https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png?1696507857",
"symbol": "WBTC",
"decimals": 8,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1619813937
},
"buckets": [
{
"id": "umbra-WBTC",
"type": "pool",
"label": "WBTC",
"address": "eth:0xFb2dc580Eed955B528407b4d36FfaFe3da685401",
"sinceTimestamp": 1619813937,
"deposit": {
"event": "0x29877766fa2bfe3b90008d6d92f965eca91cbc5757ed775740e460799fb92219",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
}
},
"withdrawal": {
"event": "0x30eb3583ad09933b693a45452ab07512244cdbc5868701aa004c27b7b267c249",
"extractor": "umbraAmount",
"params": {
"tokenAddress": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
}
}
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "The Umbra and StealthKeyRegistry contracts are immutable. The Umbra owner sets the ETH toll on every payment through the contract and the addresses that collect it, instantly and without a cap. A high toll stops new payments. ScopeLift changes the hosted app, its indexer and its relayer at will."
}
}
+1 -1
+1 -1
{
"adversaries": {
"promise": {
"protects": "amount",
"text": "Hides balances and transfer amounts. Senders, recipients and every wrap and unwrap amount are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "warning",
"exposureShort": "Wraps and unwraps publish their amounts, while confidential transfers keep theirs encrypted.",
"exposureContinued": "Either party to a transfer can disclose its amount onchain at any time.",
"advice": "Pay and get paid inside the confidential token, and unwrap only what the user needs.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "private",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Wrap event carries the clear amount",
"url": "https://github.com/OpenZeppelin/openzeppelin-confidential-contracts/blob/23ba15402346027f2416667acbb1e741179f8485/contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol#L256"
},
{
"title": "Unwrap makes the burned amount publicly decryptable",
"url": "https://github.com/OpenZeppelin/openzeppelin-confidential-contracts/blob/23ba15402346027f2416667acbb1e741179f8485/contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol#L262-L268"
},
{
"title": "Either party can disclose a transfer amount",
"url": "https://github.com/OpenZeppelin/openzeppelin-confidential-contracts/blob/23ba15402346027f2416667acbb1e741179f8485/contracts/token/ERC7984/ERC7984.sol#L202-L209"
}
],
"id": "publicObserver",
"value": "Amounts at risk",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "warning",
"exposureShort": "An account's balance is bounded by its public wraps and unwraps, and exact if it never took part in a confidential transfer.",
"exposureContinued": "Transfer partners and timing are public, so a wrap, a transfer and an unwrap in a row pair up by amount. In October 2026, 95% of unwraps could be linked to a single wrap.",
"advice": "Transfer often, even zero amounts, and unwrap only after a while. Withdraw common amounts rather than everything at once.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": {
"verdict": "atRisk",
"note": "Hidden only within an account's confidential transfers."
},
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "ERC-7984: public sender, recipient and encrypted amount per transfer",
"url": "https://eips.ethereum.org/EIPS/eip-7984"
},
{
"title": "Explorer linking unwraps to their wraps, searchable by address, handle and transaction",
"url": "https://sekuba.github.io/zama-graph/"
}
],
"id": "chainAnalyst",
"value": "Amounts at risk",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "Zama's app is closed source, so what it sends to third parties is up to Zama and can change at any time.",
"exposureContinued": "Through Zama's open SDK, amounts leave the user's device only as FHE ciphertext and return encrypted to a key held only by that device. Today the app sends the user's address, chain reads and decryption requests to Zama's own servers, which forward chain reads to an RPC provider Zama does not name. Analytics wait for the user's consent.",
"advice": "Use a client built on Zama's open SDK.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "private",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Inputs are encrypted on the device",
"url": "https://github.com/zama-ai/relayer-sdk/blob/d06f1e585a78181135cb602109e5fa3da523b48d/src/relayer/sendEncryption.ts#L133-L146"
},
{
"title": "Balance reads use a device ML-KEM key pair",
"url": "https://github.com/zama-ai/relayer-sdk/blob/d06f1e585a78181135cb602109e5fa3da523b48d/src/relayer/userDecrypt.ts#L85-L89"
},
{
"title": "The app's content security policy lists every endpoint it contacts",
"url": "https://app.zama.org"
},
{
"title": "The SDK the app bundles (@zama-fhe/sdk 3.6.0) is open source",
"url": "https://github.com/zama-ai/sdk"
}
],
"id": "networkObserver",
"value": "Amounts at risk",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "Any 5 of the 13 KMS operators can combine their key shares and decrypt every balance and transfer ever made.",
"exposureContinued": "The token owner can instantly appoint an observer that sees all amounts forever, or upgrade the token and the ACL. Zama serves its closed-source app, so it can read amounts before they are encrypted.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "KMS parties and key-share threshold",
"url": "https://github.com/zama-ai/kms/blob/b5cd5cf465dc488ff04ac8c19f3ef12877abffa0/ai-docs/ARCHITECTURE.md#L22-L25"
},
{
"title": "Observer gets a wildcard delegation without expiration",
"url": "https://github.com/zama-ai/protocol-apps/blob/85eef95c797da20875fe7eeae7f8d212d760486f/contracts/confidential-wrapper/contracts/ConfidentialWrapper.sol#L395-L403"
},
{
"title": "Zama's official app",
"url": "https://docs.zama.org/protocol/protocol-apps/apps"
}
],
"id": "privilegedInsider",
"value": "Amounts exposed",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "Whoever breaks elliptic-curve cryptography recovers a user's wallet key from any past transaction and can have the KMS decrypt that user's history.",
"exposureContinued": "A wallet signature alone authorizes decryption, permissions on past balances and transfers never expire, and the KMS encrypts its replies to whatever key the request names. The ciphertexts themselves rest on lattice assumptions with no known quantum attack, and anyone can download them today.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"contract": "Decryption",
"title": "A wallet signature authorizes a user decryption request"
},
{
"contract": "ACL",
"title": "Permissions on past ciphertexts have no expiry"
},
{
"title": "Replies are encrypted to the key the request names",
"url": "https://github.com/zama-ai/kms/blob/b5cd5cf465dc488ff04ac8c19f3ef12877abffa0/core/service/src/cryptography/hybrid_ml_kem.rs"
},
{
"title": "Coprocessor ciphertext store (public listing)",
"url": "https://coprocessor-1.mainnet.zama.org/"
}
],
"id": "futureAdversary",
"value": "Amounts exposed",
"alsoExposed": []
}
}
},
"anonymitySet": {
"type": "not-applicable",
"description": "Only amounts are hidden. Every transfer names its sender and recipient."
},
"attributes": [
{
"id": "fhe",
"label": "FHE",
"description": "Uses fully homomorphic encryption for private computation over encrypted values."
},
{
"id": "privateAmounts",
"label": "Private amounts",
"description": "Transfer amounts are private, while sender and recipient addresses remain public."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
},
{
"id": "defi",
"label": "DeFi",
"description": "Interop with DeFi vaults from within the confidential token."
}
],
"category": {
"id": "confidentialAmounts",
"label": "Confidential amounts",
"description": "Accounts and counterparties are public, balances and transfer amounts are encrypted."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "The governance multisigs upgrade the contracts instantly, before users can leave.",
"walkawayTest": {
"passed": false,
"reason": "Every unwrap needs a decryption signed by 7 of 13 KMS operators, and every input needs Zama's coprocessor."
}
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The contracts, the SDK and the KMS and coprocessor sources are public. Zama's app source is unpublished."
},
"riskSummary": "## Funds can be stolen if\n1. either governance multisig passes a malicious upgrade of the confidential tokens or Zama's protocol contracts, which takes effect instantly.\n2. the current or any retained KMS signer set, which either multisig can create or retune instantly, attests an inflated unwrap amount.\n3. Zama's coprocessor (1/1) accepts invalid encrypted inputs that bypass balance checks.\n
\n## Funds can be lost if\n1. an underlying token issuer blacklists a confidential token's address.\n2. the token owner or an underlying denylist blocks a user before they unwrap.\n3. an appointed pauser halts a token and the owner keeps it paused.\n4. the KMS or Zama's coprocessor stops or loses ciphertext data, which halts every unwrap.\n
\n## Privacy can be lost if\n1. 5 of 13 KMS operators combine their key shares (see privileged insider).\n2. the token owner appoints an observer or upgrades the token (see privileged insider).\n3. Zama changes its closed-source app to leak amounts to itself or to third parties (see privileged insider and network observer).\n4. public wraps and unwraps bound a user's balance (see chain analyst).\n5. elliptic-curve cryptography is broken, so anyone can impersonate a user to the KMS and decrypt that user's history (see future adversary).",
"riskSummary": "## Funds can be stolen if\n1. either governance multisig passes a malicious upgrade of the confidential tokens or Zama's protocol contracts, which takes effect instantly.\n2. the current or any retained KMS signer set, which either multisig can create or retune instantly, attests an inflated unwrap amount.\n3. Zama's coprocessor (1/1) accepts invalid encrypted inputs that bypass balance checks.\n
\n## Funds can be lost if\n1. an underlying token issuer blacklists a confidential token's address.\n2. the token owner or an underlying denylist blocks a user before they unwrap.\n3. an appointed pauser halts a token and the owner keeps it paused.\n4. the KMS or Zama's coprocessor stops or loses ciphertext data, which halts every unwrap.\n
\n## Privacy can be lost if\n1. 5 of 13 KMS operators combine their key shares (see privileged insider).\n2. the token owner appoints an observer or upgrades the token (see privileged insider).\n3. Zama changes its closed-source app to leak amounts to itself or to third parties (see privileged insider and network observer).\n4. public wraps and unwraps bound a user's balance (see public observer and chain analyst).\n5. elliptic-curve cryptography is broken, so anyone can impersonate a user to the KMS and decrypt that user's history (see future adversary).",
"tokens": [
{
"token": {
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"iconUrl": "https://assets.coingecko.com/coins/images/6319/large/usdc.png?1696506694",
"symbol": "USDC",
"decimals": 6,
"priceId": "usd-coin",
"sinceTimestamp": 1766750819
},
"buckets": [
{
"id": "zama-cw-cUSDC",
"type": "pool",
"label": "cUSDC token",
"address": "eth:0xe978F22157048E5DB8E5d07971376e86671672B2",
"sinceTimestamp": 1766750819,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xe978F22157048E5DB8E5d07971376e86671672B2"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xe978F22157048E5DB8E5d07971376e86671672B2"
}
}
}
]
},
{
"token": {
"address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"iconUrl": "https://assets.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "USDT",
"decimals": 6,
"priceId": "tether",
"sinceTimestamp": 1766750831
},
"buckets": [
{
"id": "zama-cw-cUSDT",
"type": "pool",
"label": "cUSDT token",
"address": "eth:0xAe0207C757Aa2B4019Ad96edD0092ddc63EF0c50",
"sinceTimestamp": 1766750831,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xAe0207C757Aa2B4019Ad96edD0092ddc63EF0c50"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xAe0207C757Aa2B4019Ad96edD0092ddc63EF0c50"
}
}
}
]
},
{
"token": {
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"iconUrl": "https://assets.coingecko.com/coins/images/2518/large/weth.png?1696503332",
"symbol": "WETH",
"decimals": 18,
"priceId": "weth",
"sinceTimestamp": 1766750843
},
"buckets": [
{
"id": "zama-cw-cWETH",
"type": "pool",
"label": "cWETH token",
"address": "eth:0xda9396b82634Ea99243cE51258B6A5Ae512D4893",
"sinceTimestamp": 1766750843,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xda9396b82634Ea99243cE51258B6A5Ae512D4893"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xda9396b82634Ea99243cE51258B6A5Ae512D4893"
}
}
}
]
},
{
"token": {
"address": "0xA12CC123ba206d4031D1c7f6223D1C2Ec249f4f3",
"iconUrl": "https://coin-images.coingecko.com/coins/images/70921/large/zama.png?1764591992",
"symbol": "ZAMA",
"decimals": 18,
"priceId": "zama",
"sinceTimestamp": 1766750867
},
"buckets": [
{
"id": "zama-cw-cZAMA",
"type": "pool",
"label": "cZAMA token",
"address": "eth:0x80CB147Fd86dC6dEe3Eee7e4Cee33d1397d98071",
"sinceTimestamp": 1766750867,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x80CB147Fd86dC6dEe3Eee7e4Cee33d1397d98071"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x80CB147Fd86dC6dEe3Eee7e4Cee33d1397d98071"
}
}
}
]
},
{
"token": {
"address": "0x27f6c8289550fCE67f6B50BeD1F519966aFE5287",
"iconUrl": "https://coin-images.coingecko.com/coins/images/70647/large/tgbp-square.png?1762953800",
"symbol": "tGBP",
"decimals": 18,
"priceId": "tokenised-gbp",
"sinceTimestamp": 1767000887
},
"buckets": [
{
"id": "zama-cw-ctGBP",
"type": "pool",
"label": "ctGBP token",
"address": "eth:0xa873750ccBafD5ec7Dd13bfD5237d7129832eDD9",
"sinceTimestamp": 1767000887,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xa873750ccBafD5ec7Dd13bfD5237d7129832eDD9"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xa873750ccBafD5ec7Dd13bfD5237d7129832eDD9"
}
}
}
]
},
{
"token": {
"address": "0x68749665FF8D2d112Fa859AA293F07A622782F38",
"iconUrl": "https://assets.coingecko.com/coins/images/10481/large/Tether_Gold.png?1696510471",
"symbol": "XAUt",
"decimals": 6,
"priceId": "tether-gold",
"sinceTimestamp": 1772116091
},
"buckets": [
{
"id": "zama-cw-cXAUt",
"type": "pool",
"label": "cXAUt token",
"address": "eth:0x73cc9aF9d6BEFdb3c3fAf8a5E8c05Cb95FdaEEf1",
"sinceTimestamp": 1772116091,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x73cc9aF9d6BEFdb3c3fAf8a5E8c05Cb95FdaEEf1"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x73cc9aF9d6BEFdb3c3fAf8a5E8c05Cb95FdaEEf1"
}
}
}
]
},
{
"token": {
"address": "0xbeeffABcd0dB09589Dd21854aa760C52aB4bf04F",
"iconUrl": "https://coin-images.coingecko.com/coins/images/70647/large/tgbp-square.png?1762953800",
"symbol": "bbqTGBP",
"decimals": 18,
"priceId": "tokenised-gbp",
"sinceTimestamp": 1780585031
},
"buckets": [
{
"id": "zama-cw-cbbqTGBP",
"type": "pool",
"label": "cbbqTGBP token",
"address": "eth:0xBA4cFF6ED6F7Cb2A58776dECa4E984b498446762",
"sinceTimestamp": 1780585031,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xBA4cFF6ED6F7Cb2A58776dECa4E984b498446762"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xBA4cFF6ED6F7Cb2A58776dECa4E984b498446762"
}
}
}
]
},
{
"token": {
"address": "0xbEEF00A59B577423653A1526c7009bdE103F542B",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "steakcUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1781877707
},
"buckets": [
{
"id": "zama-cw-csteakcUSDC",
"type": "pool",
"label": "csteakcUSDC token",
"address": "eth:0x66Bf74E96900D1a19c7070D939D124f2F565C458",
"sinceTimestamp": 1781877707,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x66Bf74E96900D1a19c7070D939D124f2F565C458"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x66Bf74E96900D1a19c7070D939D124f2F565C458"
}
}
}
]
},
{
"token": {
"address": "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
"iconUrl": "https://assets.coingecko.com/coins/images/7598/large/wrapped_bitcoin_wbtc.png?1696507857",
"symbol": "WBTC",
"decimals": 8,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1789148087
},
"buckets": [
{
"id": "zama-cw-cWBTC",
"type": "pool",
"label": "cWBTC token",
"address": "eth:0xd86aE89C089B380f064Fe01899B4071F1eb6Bb3d",
"sinceTimestamp": 1789148087,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xd86aE89C089B380f064Fe01899B4071F1eb6Bb3d"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xd86aE89C089B380f064Fe01899B4071F1eb6Bb3d"
}
}
}
]
},
{
"token": {
"address": "0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a",
"iconUrl": "https://coin-images.coingecko.com/coins/images/39284/large/AUSD_1024px.png?1764684132",
"symbol": "AUSD",
"decimals": 6,
"priceId": "agora-dollar",
"sinceTimestamp": 1789146719
},
"buckets": [
{
"id": "zama-cw-cAUSD",
"type": "pool",
"label": "cAUSD token",
"address": "eth:0xEa9A15A29DD180c40442142CaeEfC491d37bfDB2",
"sinceTimestamp": 1789146719,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xEa9A15A29DD180c40442142CaeEfC491d37bfDB2"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xEa9A15A29DD180c40442142CaeEfC491d37bfDB2"
}
}
}
]
},
{
"token": {
"address": "0x808507121B80c02388fAd14726482e061B8da827",
"iconUrl": "https://assets.coingecko.com/coins/images/15069/large/Pendle_Logo_Normal-03.png?1696514728",
"symbol": "PENDLE",
"decimals": 18,
"priceId": "pendle",
"sinceTimestamp": 1789150991
},
"buckets": [
{
"id": "zama-cw-cPENDLE",
"type": "pool",
"label": "cPENDLE token",
"address": "eth:0x8900123F7e17709C1D80eda1E611A9503Cf1B3df",
"sinceTimestamp": 1789150991,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x8900123F7e17709C1D80eda1E611A9503Cf1B3df"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x8900123F7e17709C1D80eda1E611A9503Cf1B3df"
}
}
}
]
},
{
"token": {
"address": "0xbeef003C68896c7D2c3c60d363e8d71a49Ab2bf9",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "steakUSDT",
"decimals": 18,
"priceId": "tether",
"sinceTimestamp": 1789152239
},
"buckets": [
{
"id": "zama-cw-csteakUSDT",
"type": "pool",
"label": "csteakUSDT token",
"address": "eth:0x1F6A937119c0c34Db0a2c4F000386a3BfD4A9e73",
"sinceTimestamp": 1789152239,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x1F6A937119c0c34Db0a2c4F000386a3BfD4A9e73"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x1F6A937119c0c34Db0a2c4F000386a3BfD4A9e73"
}
}
}
]
},
{
"token": {
"address": "0xbeeff07d991C04CD640DE9F15C08ba59c4FEDEb7",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "bbqUSDT",
"decimals": 18,
"priceId": "tether",
"sinceTimestamp": 1789152695
},
"buckets": [
{
"id": "zama-cw-cbbqUSDT",
"type": "pool",
"label": "cbbqUSDT token",
"address": "eth:0x80Ae7dbCe3c1696d3eeD04Ec8348c3C432322273",
"sinceTimestamp": 1789152695,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x80Ae7dbCe3c1696d3eeD04Ec8348c3C432322273"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x80Ae7dbCe3c1696d3eeD04Ec8348c3C432322273"
}
}
}
]
},
{
"token": {
"address": "0xbeeff2C5bF38f90e3482a8b19F12E5a6D2FCa757",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "bbqUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1789153067
},
"buckets": [
{
"id": "zama-cw-cbbqUSDC",
"type": "pool",
"label": "cbbqUSDC token",
"address": "eth:0x501b014f86a73A7199E00cB31C0e9565Ac51e51B",
"sinceTimestamp": 1789153067,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x501b014f86a73A7199E00cB31C0e9565Ac51e51B"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x501b014f86a73A7199E00cB31C0e9565Ac51e51B"
}
}
}
]
},
{
"token": {
"address": "0x3d5EcCb62974178236A768A7ef14D3ce468Fbe91",
"iconUrl": "https://coin-images.coingecko.com/coins/images/7598/large/WBTCLOGO.png?1764496367",
"symbol": "armcWBTC",
"decimals": 18,
"priceId": "wrapped-bitcoin",
"sinceTimestamp": 1789148987
},
"buckets": [
{
"id": "zama-cw-carmcWBTC",
"type": "pool",
"label": "carmcWBTC token",
"address": "eth:0xF921A5B0634f4236B21A4e948317abf9a2E86B6f",
"sinceTimestamp": 1789148987,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xF921A5B0634f4236B21A4e948317abf9a2E86B6f"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xF921A5B0634f4236B21A4e948317abf9a2E86B6f"
}
}
}
]
},
{
"token": {
"address": "0x500aE64100D7DbDb640531085C2F5d40cDC8930D",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "armUSDTs",
"decimals": 18,
"priceId": "tether",
"sinceTimestamp": 1789150187
},
"buckets": [
{
"id": "zama-cw-carmUSDTs",
"type": "pool",
"label": "carmUSDTs token",
"address": "eth:0xbaC6DeDf2C10D6D381F9DBd9EFd69D93FfCef50B",
"sinceTimestamp": 1789150187,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xbaC6DeDf2C10D6D381F9DBd9EFd69D93FfCef50B"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xbaC6DeDf2C10D6D381F9DBd9EFd69D93FfCef50B"
}
}
}
]
},
{
"token": {
"address": "0xA2EAaD0D586cF9FD73bb2c09cF6A7E3e187D68cd",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "armUSDCs",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1789151411
},
"buckets": [
{
"id": "zama-cw-carmUSDCs",
"type": "pool",
"label": "carmUSDCs token",
"address": "eth:0x77F8207ee451441336538bA07a2F425780dED8DB",
"sinceTimestamp": 1789151411,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x77F8207ee451441336538bA07a2F425780dED8DB"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x77F8207ee451441336538bA07a2F425780dED8DB"
}
}
}
]
},
{
"token": {
"address": "0xBf29043164660C60A2a72Cd15FFe2304e87B6838",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "armUSDTp",
"decimals": 18,
"priceId": "tether",
"sinceTimestamp": 1789153331
},
"buckets": [
{
"id": "zama-cw-carmUSDTp",
"type": "pool",
"label": "carmUSDTp token",
"address": "eth:0x63a60aCC304b84eF829b263f28e7b636Bf77d45A",
"sinceTimestamp": 1789153331,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x63a60aCC304b84eF829b263f28e7b636Bf77d45A"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x63a60aCC304b84eF829b263f28e7b636Bf77d45A"
}
}
}
]
},
{
"token": {
"address": "0x5dc53a23AdC9f2Bed98de6F59F7F309a7c71FF2B",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "armUSDCp",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1789150751
},
"buckets": [
{
"id": "zama-cw-carmUSDCp",
"type": "pool",
"label": "carmUSDCp token",
"address": "eth:0x2ebBd099f66b0ca94DD82B4c06fe3eEf6AFf853c",
"sinceTimestamp": 1789150751,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x2ebBd099f66b0ca94DD82B4c06fe3eEf6AFf853c"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x2ebBd099f66b0ca94DD82B4c06fe3eEf6AFf853c"
}
}
}
]
},
{
"token": {
"address": "0x55C1B6e461a6334B567bAF0FEb5D728715446f05",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "pendleUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1789150499
},
"buckets": [
{
"id": "zama-cw-cpendleUSDC",
"type": "pool",
"label": "cpendleUSDC token",
"address": "eth:0xb6e5299fc56053DD5440104Fd6Fd2A3CD064edbC",
"sinceTimestamp": 1789150499,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xb6e5299fc56053DD5440104Fd6Fd2A3CD064edbC"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xb6e5299fc56053DD5440104Fd6Fd2A3CD064edbC"
}
}
}
]
},
{
"token": {
"address": "0x32401B9fb79065Bc15949DE0BD43927492f02F0C",
"iconUrl": "https://coin-images.coingecko.com/coins/images/39284/large/AUSD_1024px.png?1764684132",
"symbol": "fAUSDe",
"decimals": 18,
"priceId": "agora-dollar",
"sinceTimestamp": 1789148387
},
"buckets": [
{
"id": "zama-cw-cfAUSDe",
"type": "pool",
"label": "cfAUSDe token",
"address": "eth:0x76A3f985315aAc9789Cb5BF8A5bb83BFF55FD5a6",
"sinceTimestamp": 1789148387,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x76A3f985315aAc9789Cb5BF8A5bb83BFF55FD5a6"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x76A3f985315aAc9789Cb5BF8A5bb83BFF55FD5a6"
}
}
}
]
},
{
"token": {
"address": "0xb48C056C5608bA2Ee4cD94AF2bF4b1F25295Bd7e",
"iconUrl": "https://coin-images.coingecko.com/coins/images/325/large/Tether.png?1696501661",
"symbol": "fcUSDT",
"decimals": 18,
"priceId": "tether",
"sinceTimestamp": 1789388567
},
"buckets": [
{
"id": "zama-cw-cfcUSDT",
"type": "pool",
"label": "cfcUSDT token",
"address": "eth:0xA28A369Df348ac232E4DAF7B0Ef90280d8707D7F",
"sinceTimestamp": 1789388567,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xA28A369Df348ac232E4DAF7B0Ef90280d8707D7F"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xA28A369Df348ac232E4DAF7B0Ef90280d8707D7F"
}
}
}
]
},
{
"token": {
"address": "0xc207d3f66537D7F66456808379A0E560cF20Da36",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "roxcUSDC",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1789153955
},
"buckets": [
{
"id": "zama-cw-croxcUSDC",
"type": "pool",
"label": "croxcUSDC token",
"address": "eth:0xB1B18Ad1F16D744c470cb6B09Cb826AfFcc9EB30",
"sinceTimestamp": 1789153955,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0xB1B18Ad1F16D744c470cb6B09Cb826AfFcc9EB30"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0xB1B18Ad1F16D744c470cb6B09Cb826AfFcc9EB30"
}
}
}
]
},
{
"token": {
"address": "0xE0181090c22579B6A217f1522cbf8c9f1F0C1965",
"iconUrl": "https://coin-images.coingecko.com/coins/images/6319/large/USDC.png?1769615602",
"symbol": "roxUSDCy",
"decimals": 18,
"priceId": "usd-coin",
"sinceTimestamp": 1789154375
},
"buckets": [
{
"id": "zama-cw-croxUSDCy",
"type": "pool",
"label": "croxUSDCy token",
"address": "eth:0x4FCCF8046FB7FB7AB76321BD39C27453e396B88f",
"sinceTimestamp": 1789154375,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x4FCCF8046FB7FB7AB76321BD39C27453e396B88f"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x4FCCF8046FB7FB7AB76321BD39C27453e396B88f"
}
}
}
]
},
{
"token": {
"address": "0xB344e331A3cDa61D329fb3Cca2Be5942da87c418",
"iconUrl": "https://coin-images.coingecko.com/coins/images/39284/large/AUSD_1024px.png?1764684132",
"symbol": "PAPY",
"decimals": 18,
"priceId": "agora-dollar",
"sinceTimestamp": 1789151975
},
"buckets": [
{
"id": "zama-cw-cPAPY",
"type": "pool",
"label": "cPAPY token",
"address": "eth:0x9ABb8f3dC2863B1F108DeD7ea41902fEF6732A8c",
"sinceTimestamp": 1789151975,
"deposit": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"to": "0x9ABb8f3dC2863B1F108DeD7ea41902fEF6732A8c"
}
},
"withdrawal": {
"event": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"extractor": "erc20Transfer",
"params": {
"from": "0x9ABb8f3dC2863B1F108DeD7ea41902fEF6732A8c"
}
}
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "ZamaGovMultisigA (9/17) and ZamaGovMultisigB (3/6) each control, alone and instantly, the Aragon contract that owns the confidential tokens and Zama's protocol contracts on Ethereum. Either multisig can upgrade these contracts, change every compliance setting, manage KMS signer sets and trigger FHE key generation.\n\nSafeL2 (3/5) owns the Gateway contracts and can change coprocessors and KMS settings there or disconnect Ethereum. Any of 17 pausers can pause the ACL, and any of 17 the Gateway. Either halts every token until its owner unpauses."
}
}
+5 -0
+5 -0
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which funds leaving Ethereum come back as which, by passing through Zcash's shielded pool. Everything on Ethereum and NEAR is public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Zcash's shielded pool hides which payout into it funds which later exit.",
"exposureContinued": "Everything up to the pool edge is public: the Ethereum deposit and the NEAR entries that credit, swap and withdraw it. The bridge encrypts each payout so that anyone can decrypt its Zcash address and amount.",
"interior": {
"sender": "private",
"recipient": {
"verdict": "atRisk",
"note": "Payout notes are decryptable by anyone, so a reused address ties payouts together."
},
"amount": "private",
"asset": {
"verdict": "exposed",
"note": "Only ZEC exists inside the pool. The assets swapped from and to are public on NEAR."
},
"linkage": "private"
},
"sources": [
{
"title": "Custodial bridge mint carries the Ethereum transaction hash in its memo",
"url": "https://nearblocks.io/address/eth.omft.near"
},
{
"title": "Withdrawal message names the target Zcash address",
"url": "https://github.com/Near-One/btc-bridge/blob/4711c2f1d035a208464b9729bb24e45ed9ab7831/contracts/satoshi-bridge/src/api/token_receiver.rs#L8-L16"
},
{
"title": "Payouts are encrypted to an all-zero outgoing viewing key",
"url": "https://github.com/Near-One/btc-bridge/blob/4711c2f1d035a208464b9729bb24e45ed9ab7831/contracts/satoshi-bridge/src/zcash_utils/orchard_policy.rs#L13-L63"
},
{
"title": "Zodl creates a fresh shielded address for every quote",
"url": "https://github.com/zodl-inc/zodl-ios/blob/75b83d7601573e165e2dacdfaffb69750dadd05f/secant/Sources/Features/SwapAndPayForm/SwapAndPayStore.swift#L908-L955"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "Only the amount and timing of a round trip can pair a payout into the pool with a later deposit to the bridge.",
"exposureContinued": "Deposit addresses are fresh per quote and spent together with the bridge change address, which marks every exit as NEAR Intents.",
"advice": "Hold the ZEC in the pool for days, split or merge it with other shielded funds, and swap back amounts that match no payout.",
"interior": {
"sender": "private",
"recipient": {
"verdict": "atRisk",
"note": "Payout notes are decryptable by anyone, so a reused address ties payouts together."
},
"amount": "private",
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "Round-trip amount and timing across the pool edge pair a payout with a later deposit."
}
},
"sources": [
{
"title": "Kappos et al., An Empirical Analysis of Anonymity in Zcash (USENIX 2018)",
"url": "https://arxiv.org/abs/1805.03180"
},
{
"title": "Deposit address derived per quote from the deposit message",
"url": "https://github.com/Near-One/btc-bridge/blob/4711c2f1d035a208464b9729bb24e45ed9ab7831/contracts/satoshi-bridge/src/deposit_msg.rs#L49-L52"
},
{
"title": "Bridge change address and UTXO set",
"url": "https://nearblocks.io/address/zcash-connector.bridge.near"
}
],
"id": "chainAnalyst",
"value": "Link private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "Each sync sends the user's transparent addresses to lightwalletd outside Tor, tying both the payout fetch and the exit to that user by timing.",
"exposureContinued": "Zodl's Tor isolates each 1Click request, payout fetch and transaction, while block sync and these address lookups stay direct.",
"advice": "Turn on Tor in Zodl and point it at a lightwalletd server the user runs.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "Private only with Tor on and the user's own lightwalletd server."
}
},
"sources": [
{
"title": "Tor is off unless the user enables it",
"url": "https://github.com/zodl-inc/zodl-ios/blob/75b83d7601573e165e2dacdfaffb69750dadd05f/secant/Sources/Dependencies/SDKSynchronizer/SDKSynchronizerLive.swift#L45"
},
{
"title": "Every sync looks up the account's transparent addresses directly",
"url": "https://github.com/zodl-inc/zodl-swift-wallet-sdk/blob/191d0347186a1c6fcd207eead24a891049444041/Sources/ZcashLightClientKit/Block/FetchUnspentTxOutputs/UTXOFetcher.swift#L39-L52"
},
{
"title": "Each transaction fetch and send gets its own Tor connection",
"url": "https://github.com/zodl-inc/zodl-swift-wallet-sdk/blob/191d0347186a1c6fcd207eead24a891049444041/Sources/ZcashLightClientKit/Modules/Service/LightWalletService.swift#L146-L159"
},
{
"title": "Compact blocks download over a direct connection",
"url": "https://github.com/zodl-inc/zodl-swift-wallet-sdk/blob/191d0347186a1c6fcd207eead24a891049444041/Sources/ZcashLightClientKit/Block/Download/BlockDownloader.swift#L187"
}
],
"id": "networkObserver",
"value": "Link at risk",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "The operator custodies both legs in transit and can freeze any account or deposit, setting the terms on which the user's funds return.",
"exposureContinued": "Over Tor, its 1Click API sees each leg only as NEAR publishes it, with a fresh shielded address per swap. It holds no key into the shielded pool.",
"interior": {
"sender": "private",
"recipient": "private",
"amount": "private",
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "The operator can freeze either leg and set the terms of its release."
}
},
"sources": [
{
"title": "1Click terms: IP and wallet data, screening, custody",
"url": "https://docs.near-intents.org/security-compliance/terms-of-service"
},
{
"title": "Any account can be locked by the multisig or a locker",
"url": "https://github.com/near/intents/blob/fa44ede9e874931c39a6c4246de82bc40f4f8d99/defuse/src/contract/accounts/force.rs#L21-L33"
},
{
"title": "Owner-only mint of the wrapped Ethereum assets",
"url": "https://github.com/near/intents/blob/fa44ede9e874931c39a6c4246de82bc40f4f8d99/poa-token/src/contract.rs#L79-L81"
},
{
"title": "Zodl sends its partner key and a fresh refund address with each quote",
"url": "https://github.com/zodl-inc/zodl-ios/blob/75b83d7601573e165e2dacdfaffb69750dadd05f/secant/Sources/Dependencies/SwapAndPay/sources/Near1Click.swift#L313-L352"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": []
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "All of an account's rotated addresses share one incoming viewing key on the Pallas curve, and every payout address is public on NEAR.",
"exposureContinued": "Whoever breaks elliptic-curve cryptography recovers that key from any one address and decrypts every note the account ever received. Those include the change notes of its exits, which join both legs of every round trip. ZIP 2005's quantum recoverability protects only funds.",
"interior": {
"sender": {
"verdict": "atRisk",
"note": "Spends are found through the change notes they pay back to the same account."
},
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Orchard key agreement on the Pallas curve",
"url": "https://zips.z.cash/protocol/protocol.pdf#concreteorchardkeyagreement"
},
{
"title": "ZIP 2005: quantum recoverability of funds",
"url": "https://zips.z.cash/zip-2005"
},
{
"title": "Payouts are encrypted to an all-zero outgoing viewing key",
"url": "https://github.com/Near-One/btc-bridge/blob/4711c2f1d035a208464b9729bb24e45ed9ab7831/contracts/satoshi-bridge/src/zcash_utils/orchard_policy.rs#L13-L63"
}
],
"id": "futureAdversary",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "atRisk"
},
{
"field": "recipient",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
}
]
}
}
},
"anonymitySet": {
"type": "not-applicable",
"description": "The set is Zcash's shielded pool, outside the chains L2BEAT indexes. Amounts are public at the pool edge, so an exit hides among the pool entries that could match it in amount and time."
},
"attributes": [
{
"id": "bridged",
"label": "Bridged",
"description": "Funds leave Ethereum through a bridge and gain their privacy on another chain."
},
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "The NEAR Intents multisig upgrades the Verifier and the Rainbow Bridge multisig the Zcash bridge, both instantly. The Ethereum funds sit in an EOA the operator controls.",
"walkawayTest": {
"passed": false,
"reason": "The custodial bridge operator executes every Ethereum deposit and withdrawal offchain. For the Zcash light client on NEAR, anyone staking 1,000 NEAR can relay after seven days, unless the Rainbow Bridge multisig rejects them."
}
},
"referenceClient": {
"name": "Zodl",
"repository": "https://github.com/zodl-inc/zodl-ios",
"commit": "75b83d7601573e165e2dacdfaffb69750dadd05f"
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The Verifier, the bridge token, the Zcash bridge and Zodl are open source. The bridge back end, the 1Click API and the solver relay that every Ethereum leg needs are closed."
},
"riskSummary": "## Funds can be stolen if\n1. the custodial bridge operator's mint key or its Ethereum treasury key is compromised.\n2. the NEAR Intents multisig upgrades the Verifier maliciously.\n3. the Rainbow Bridge multisig upgrades the Zcash connector, its token or the light client maliciously.\n4. a threshold of the NEAR MPC nodes colludes to sign Zcash transactions from bridge addresses.\n
\n## Funds can be frozen if\n1. the NEAR Intents multisig or the single-key account locker freezes the user's account in the Verifier.\n2. the custodial bridge operator holds a deposit or withdrawal for a compliance review.\n3. the relayers stop and the Rainbow Bridge multisig rejects anyone who stakes to replace them.\n
\n## Privacy can be lost if\n1. the operator, which custodies both legs, makes the release of either depend on who the user is (see privileged insider).\n2. the lightwalletd server Zodl syncs from ties the payout and the exit to the account, since syncs send transparent addresses outside Tor (see network observer).\n3. elliptic-curve cryptography is broken, which recovers each account's viewing key from its payout addresses on NEAR (see future adversary).",
"tokens": [],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "The route touches three governed systems on NEAR, each can change instantly. The Ethereum side runs on EOAs.\n\n### NEAR Intents Verifier (`intents.near`)\n\n`intents.sputnik-dao.near`, a 3/5 multisig, holds the `DAO` role and is super admin, so it can grant every other role. Upgrades go through `ctl-intents.near`, a controller whose only admin is the same multisig, and deploy at once. Six accounts hold `PauseManager` and can halt all swaps and withdrawals, and only the multisig can resume them. One EOA holds `UnrestrictedAccountLocker` and can lock any user account. A locked account keeps receiving deposits, while its intents and withdrawals stop until the multisig unlocks it.\n\n### Custodial \"PoA\" bridge (`omft.near`, `eth.omft.near`)\n\nThe `poa-factory` contract `omft.near` deploys one token per bridged asset. It mints on the signal of `TokenDepositer`: `bridge-mng.near`, an EOA, and `int-mnt-dao.sputnik-dao.near`, a 3/3 multisig. NEAR takes every mint on trust. The NEAR Intents multisig is super admin.\n\n### Zcash connector (`zcash-connector.bridge.near`, `zec.omft.near`, `zcash-client.bridge.near`)\n\n`rainbowbridge.sputnik-dao.near`, a 3/5 multisig, governs the connector, the token's controller and the light client, and sets the bridge fees. `bridge-ops.near` can stage code and pause the connector, and `pm.bridge.near` can pause it. `omni-relayer.bridge.near` and `intents-relayer.near` prove deposits against the light client, whose headers `zcash-relayer.near` relays. Withdrawals are signed by the NEAR MPC network `v1.signer` (11/17, see the [MPC operators page](https://mpc-operators.nearone.org/)) on request of a relayer. These three hold roles that make them relayers. Anyone else becomes one after staking 1,000 NEAR and waiting seven days, and the multisig can reject any relayer. Anyone can refund a deposit the connector never credited, once the light client holds its block. The refund waits two days, or fourteen when the deposit message names no refund address. The multisig or `omni-relayer.bridge.near` can reject the refund until then."
},
"zkCatalogId": "zcash"
}
+6 -1
+6 -1
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides which deposit pays for which API request. Deposits and withdrawals are public, and the provider can read prompts."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether an API request can be tied to the deposit that pays for it."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Requests stay offchain, so nothing onchain ties a request to the deposit that pays for it.",
"exposureContinued": "A deposit publishes the funder, amount, note id and expiry. Closing the note publishes the payout address and the remaining balance, so each note's total spend is public.",
"interior": {
"sender": "exposed",
"recipient": {
"verdict": "exposed",
"note": "Payments go to the operator treasury."
},
"amount": {
"verdict": "atRisk",
"note": "Charges per request stay offchain. Closing the note publishes the total."
},
"asset": "exposed",
"linkage": {
"verdict": "private",
"note": "An escape dispute publishes the link for one request."
}
},
"sources": [
{
"contract": "ZkApiVault"
},
{
"title": "Deposit and close events",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/protocol/contracts/src/libraries/Events.sol#L6-L10"
},
{
"title": "Request circuit keeps note id, balance and state signature private",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/protocol/rust/crates/zkapi-proof/src/groth16.rs#L368-L485"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "good",
"exposureShort": "Authorizations never reach the chain, so correlating public data adds nothing to the note record.",
"interior": {
"sender": "exposed",
"recipient": {
"verdict": "exposed",
"note": "Payments go to the operator treasury."
},
"amount": {
"verdict": "atRisk",
"note": "Charges per request stay offchain. Closing the note publishes the total."
},
"asset": "exposed",
"linkage": {
"verdict": "private",
"note": "An escape dispute publishes the link for one request."
}
},
"sources": [
{
"title": "Authorization is an HTTP request to the operator",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/docs/api-spec.md"
}
],
"id": "chainAnalyst",
"value": "Link private",
"alsoExposed": []
},
"networkObserver": {
"sentiment": "good",
"exposureShort": "The app works in Tor Browser, the daemon has a Tor setting with a kill switch, and no third party sees both a deposit and a request.",
"exposureContinued": "The RPC serving the user's wallet sees the deposit, while requests go to the operator and the provider. The app sends inference through a relay at refraction.network by default, which sees its timing. The hosted app reports feature use to Fathom, a cookieless analytics service.",
"advice": "Use the app in Tor Browser, or the daemon with its Tor setting, and send the deposit through a public RPC over Tor.",
"interior": {
"sender": "exposed",
"recipient": {
"verdict": "exposed",
"note": "Payments go to the operator treasury."
},
"amount": {
"verdict": "atRisk",
"note": "Charges per request stay offchain. Closing the note publishes the total."
},
"asset": "exposed",
"linkage": {
"verdict": "atRisk",
"note": "Private only over Tor, which keeps the user's IP off both sides."
}
},
"sources": [
{
"title": "Daemon Tor route has a kill switch",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/zkapi-clientd/docs/CLI_ZKAPI.md#L81-L97"
},
{
"title": "App relay on by default, direct fallback",
"url": "https://github.com/OpenAnonymity/oa-chat/blob/60ed5be2957d984c70a7299474927becec47b61f/chat/services/networkProxy.js#L7-L10"
},
{
"title": "Hosted app loads Fathom Analytics (checked 2026-10-10)",
"url": "https://chat.openanonymity.ai"
}
],
"id": "networkObserver",
"value": "Link private",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "The operator sees each request's time and budget tier but not its note, and too few active notes cover a top-tier budget to hide among.",
"exposureContinued": "The candidates are the active notes whose balance covers the request's budget tier, which follows the chosen model's price. The daemon reveals the note id to the operator's indexer before each request. The provider can read prompts and responses and link requests under one key.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": {
"verdict": "exposed",
"note": "The operator bills each request and the provider meters it."
},
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Balance commitment re-blinded for every request",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/docs/note-bound-commitments.md"
},
{
"title": "OA Chat sets the budget tier from the model's price",
"url": "https://github.com/OpenAnonymity/oa-chat/blob/60ed5be2957d984c70a7299474927becec47b61f/chat/zkapi/services/zkapiModelBudget.mjs#L6-L14"
},
{
"title": "Daemon fetches the note path by note id",
"url": "https://github.com/ethereum/zkapi/blob/20aa542ae98e767c0507133fd34b12a56f5ccd3d/crates/zkapi-clientd/src/indexer.rs#L71-L80"
},
{
"title": "Provider sees inference content",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/zkapi-clientd/docs/PRIVACY.md"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": [
{
"field": "amount",
"exposure": "exposed"
}
]
},
"futureAdversary": {
"sentiment": "good",
"exposureShort": "Note leaves and nullifiers are Poseidon hashes and nothing encrypted is written onchain, so there is nothing to decrypt.",
"exposureContinued": "Whoever breaks elliptic-curve cryptography opens only the balance commitment that a published dispute carries.",
"interior": {
"sender": "exposed",
"recipient": {
"verdict": "exposed",
"note": "Payments go to the operator treasury."
},
"amount": {
"verdict": "atRisk",
"note": "Charges per request stay offchain. Closing the note publishes the total."
},
"asset": "exposed",
"linkage": {
"verdict": "private",
"note": "An escape dispute publishes the link for one request."
}
},
"sources": [
{
"title": "Note-bound commitments and assumptions",
"url": "https://github.com/ethereum/zkapi/blob/045b444ea1b52538d1b40273c7cb6ed09468a052/docs/note-bound-commitments.md"
}
],
"id": "futureAdversary",
"value": "Link private",
"alsoExposed": []
}
}
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "anonymousAccess",
"label": "Anonymous access",
"description": "Proves eligibility to use a service without revealing which account or deposit grants access."
},
"exitWindow": {
"value": "None",
"sentiment": "bad",
"orderHint": 0,
"description": "The owner can immediately pause cooperative closes and the start of escapes. An already pending escape can be finalized after 1 day, including during a pause. An active note becomes sweepable after its deposit expiry.",
"walkawayTest": {
"passed": false,
"reason": "Starting an escape needs an unpaused vault and the user's latest signed balance. The operator can cancel it with any request proof it holds for that balance, and only a new operator signature restores normal use."
}
},
"referenceClient": {
"name": "OA Chat",
"repository": "https://github.com/OpenAnonymity/oa-chat",
"commit": "60ed5be2957d984c70a7299474927becec47b61f"
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The browser app and the local daemon have public source and build instructions. The verifier enclave image rebuilds from source and matches its hardware attestation. The hosted frontend, the daemon releases and the key stations remain unreproduced."
},
"riskSummary": "## Funds can be stolen if\n\n1. the owner pauses withdrawals until notes expire and anyone sweeps them to its treasury.\n2. the single-party setup secrets or a circuit flaw allow forged withdrawal proofs.\n3. malicious wallet code reads the note secret.\n\n
\n\n## Funds can be lost or frozen if\n\n1. the note secret or the latest signed balance is lost.\n2. a note expires before withdrawal.\n3. the operator withholds a signed balance and cancels the escape with the request it received.\n\n
\n\n## Privacy can be lost if\n\n1. the operator ties a request to its deposit, since few active notes cover a top-tier budget (see privileged insider).\n2. a daemon user reveals the note id to the operator's indexer before each request (see privileged insider).\n3. prompts identify the user to OpenRouter or the model provider (see privileged insider).\n4. the operator keeps request transcripts and indexer logs, which later tie requests to deposits (see privileged insider).",
"riskSummary": "## Funds can be stolen if\n1. the owner pauses withdrawals until notes expire and anyone sweeps them to its treasury.\n2. the single-party [trusted setup](#trusted-setups) secrets or a circuit flaw allow forged withdrawal proofs.\n3. malicious wallet code reads the note secret.\n
\n## Funds can be lost if\n1. the note secret or the latest signed balance is lost.\n2. a note expires before withdrawal.\n
\n## Funds can be frozen if\n1. the operator withholds a signed balance and cancels the escape with the request it received.\n
\n## Privacy can be lost if\n1. the operator ties a request to its deposit, since few active notes cover a top-tier budget (see privileged insider).\n2. a daemon user reveals the note id to the operator's indexer before each request (see privileged insider).\n3. prompts identify the user to OpenRouter or the model provider (see privileged insider).\n4. the operator keeps request transcripts and indexer logs, which later tie requests to deposits (see privileged insider).",
"tokens": [
{
"token": {
"address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"iconUrl": "https://assets.coingecko.com/coins/images/279/large/ethereum.png?1595348880",
"symbol": "ETH",
"decimals": 18,
"priceId": "ethereum",
"sinceTimestamp": 1790783879
},
"buckets": [
{
"id": "zkapi-ETH",
"type": "pool",
"label": "ETH API balances",
"address": "eth:0x4386FDbdA35D995beB3BF8625118Ec5982ec81fe",
"sinceTimestamp": 1790783879,
"deposit": {
"event": "0x7c83dba8534bea9e30d6444f9ca6462dc906897f9938d220dbbe4358c1f7a063",
"extractor": "zkApiDeposit",
"params": {
"weiPerUnit": "1000000000"
}
},
"withdrawal": {
"event": "0x1f43fa4711ca18e1d26398f26bf598bd3a62992cdd0e84f055f2bb506e9d7031",
"extractor": "zkApiWithdrawal",
"params": {
"weiPerUnit": "1000000000"
}
},
"additionalWithdrawals": [
{
"event": "0x163f2e46c4004f0ed9682e2db8c84efac31310720266b17ea9904ba348c26504",
"extractor": "zkApiWithdrawal",
"params": {
"weiPerUnit": "1000000000"
}
}
]
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "The vault, verifier, signing keys and exit parameters are immutable. The owner EOA can set the treasury, pause deposits, cooperative closes and the start of escapes, and transfer or renounce ownership, all without delay. Pending escapes still finalize during a pause. An instant pause with a subsequent sweep after expiry would steal all funds whose escape was not started before the pause.\n\nThe operator's services, the hosted app and the daemon releases are controlled by Open Anonymity and can change without notice."
}
}
+7 -2
+7 -2
{
"adversaries": {
"promise": {
"protects": "linkage",
"text": "Hides senders, amounts and the link between deposits and withdrawals inside the ledger. Names, deposits and withdrawals are public."
},
"adversaries": [
{
"id": "publicObserver",
"label": "Public observer",
"description": "Everyone with a block explorer and some basic tools. Sees every public onchain event, but does no correlation beyond following links.",
"examples": "A curious counterparty, an employer, a journalist."
},
{
"id": "chainAnalyst",
"label": "Chain analyst",
"description": "Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters.",
"examples": "Chain analytics firms, ZachXBT, data brokers."
},
{
"id": "networkObserver",
"label": "Network observer",
"description": "Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Learns IP addresses, timing, fingerprints and ciphertext. Services the operator runs count as the insider.",
"examples": "Infura or Alchemy, a Tornado relayer, a wallet vendor selling telemetry, Google captcha or analytics in the dapp frontend."
},
{
"id": "privilegedInsider",
"label": "Privileged insider",
"description": "Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the client: upgrade admin, custodian, view key holder, enclave operator, association set provider, hosted prover, registry, frontend host.",
"examples": "A compliance backdoor key, a DAO with an upgrade key, a KMS committee, an ASP operator, a custodial bridge."
},
{
"id": "futureAdversary",
"label": "Future adversary",
"description": "Harvest now, decrypt later. Holds every byte ever published and runs the known quantum attacks: elliptic curves, pairings and RSA fall. Hashes, symmetric ciphers and post-quantum schemes stand until an attack on them is known.",
"examples": "An intelligence agency archiving chain data today, then anyone once a break is public."
}
],
"fields": [
{
"id": "sender",
"label": "Sender",
"subject": "Sender",
"promiseLabel": "Sender privacy",
"description": "The Ethereum address that funds entered from, or that initiated a transfer."
},
{
"id": "recipient",
"label": "Recipient",
"subject": "Recipient",
"promiseLabel": "Recipient privacy",
"description": "Who receives the funds: the address they exit to, the receiver of a transfer, or whoever controls a one-time receiving address."
},
{
"id": "amount",
"label": "Amount",
"subject": "Amounts",
"promiseLabel": "Amount privacy",
"description": "The value moved."
},
{
"id": "asset",
"label": "Asset",
"subject": "Asset",
"promiseLabel": "Asset privacy",
"description": "Which token is moved."
},
{
"id": "linkage",
"label": "Link",
"subject": "Link",
"promiseLabel": "Link privacy",
"description": "Whether the entry and exit of the same funds, or sender and recipient of the same transfer, can be tied together."
}
],
"cells": {
"publicObserver": {
"sentiment": "good",
"exposureShort": "Private payments publish encrypted notes.",
"exposureContinued": "Claiming a name ties it and its Aztec address to the wallet that funds the registration. The first payment to a new contact reveals the recipient through a handshake, and L2 logs mark every transaction of the shared token smart contract. The user's first sponsored transaction after registration is tied to their account, with the payment, deposit address or withdrawal it carries.",
"advice": "Claim the user's name from a wallet without a public link to them, then make the first transaction after registration a deposit from that wallet. Fund each deposit address once and let it be swept/relayed.",
"interior": {
"sender": {
"verdict": "atRisk",
"note": "Public for the user's first sponsored transaction after registration."
},
"recipient": {
"verdict": "exposed",
"note": "Revealed by the first payment to each new contact."
},
"amount": "private",
"asset": {
"verdict": "exposed",
"note": "Only DAI."
},
"linkage": {
"verdict": "atRisk",
"note": "Exposed when the user's first sponsored transaction after registration withdraws or pays a new contact."
}
},
"sources": [
{
"title": "Fixed log tags on every token transaction",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/vendor/oxide/noir-projects/oxide_lib/src/constants.nr#L77-L81"
},
{
"title": "First delivery to a new contact opens a handshake",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/sdk/src/feePaymentMethod/claimFpcGasModel.ts#L232-L237"
},
{
"title": "First sponsored transaction nullifies the L1 account",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/contracts/contracts/fee_paying/claim_fpc/src/main.nr#L205-L217"
},
{
"contract": "AccountMetadataRegistry",
"title": "Names map to Aztec addresses"
}
],
"id": "publicObserver",
"value": "Link private",
"alsoExposed": []
},
"chainAnalyst": {
"sentiment": "warning",
"exposureShort": "In practice the anonymity set is zk.money's users on Aztec, although the L2 contract is permissionless.",
"exposureContinued": "The first payment to a name from outside zk.money is publicly tied to that name.",
"exposureContinued": "The first payment to a name from outside zk.money is publicly tied to that name. A payee can tell which payments come from the same payer, since each pair shares one secret for tagging notes.",
"advice": "Give outside payers a deposit address the user's wallet created. Withdraw common amounts rather than everything at once. Wait before exiting and pick a different time of day than the deposit. Exit to a fresh address every time and spend from it with a different wallet than the one that deposited.",
"interior": {
"sender": {
"verdict": "atRisk",
"note": "Public for the user's first sponsored transaction after registration."
},
"recipient": {
"verdict": "exposed",
"note": "Revealed by the first payment to each new contact."
},
"amount": {
"verdict": "atRisk",
"note": "Inferable when a payment sits between a matching public deposit and withdrawal."
},
"asset": {
"verdict": "exposed",
"note": "Only DAI."
},
"linkage": {
"verdict": "atRisk",
"note": "Registration deposits are publicly tied to their name."
}
},
"sources": [
{
"contract": "RegistrationSIPA"
},
{
"title": "Resolver notifies the recipient of each deposit address",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/vendor/oxide/noir-projects/oxide_token_contract/src/main.nr#L236-L251"
},
{
"title": "The notification and the sweep request share one Aztec transaction",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/sdk/src/services/sipaIntents.ts#L171-L186"
},
{
"title": "Handshake announcements are tagged with the recipient address",
"url": "https://github.com/AztecProtocol/aztec-packages/blob/v5.2.0/noir-projects/noir-contracts/contracts/standard/handshake_registry_contract/src/main.nr#L82-L96"
}
],
"id": "chainAnalyst",
"value": "Link at risk",
"alsoExposed": [
{
"field": "amount",
"exposure": "atRisk"
}
]
},
"networkObserver": {
"sentiment": "warning",
"exposureShort": "Anyone on the user's network path sees their Aztec transactions and can match their deposit and withdrawal to the blocks they land in.",
"exposureContinued": "Desktop has no Tor or proxy setting.",
"advice": "Route zk.money Desktop through Tor with system-wide tools.",
"interior": {
"sender": {
"verdict": "atRisk",
"note": "XMTP shows who asks whom for payment."
},
"recipient": {
"verdict": "exposed",
"note": "Revealed by the first payment to each new contact."
},
"amount": "private",
"asset": {
"verdict": "exposed",
"note": "Only DAI."
},
"linkage": {
"verdict": "atRisk",
"note": "Private only over Tor, which Desktop lacks."
}
},
"sources": [
{
"title": "Desktop settings: endpoints only, no proxy",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/web-wallet-desktop/src/config.js#L36-L47"
},
{
"title": "XMTP identity is the account bootstrap address",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/web-wallet/src/platform/xmtp/WebXmtpClient.ts#L95-L109"
}
],
"id": "networkObserver",
"value": "Link at risk",
"alsoExposed": []
},
"privilegedInsider": {
"sentiment": "bad",
"exposureShort": "The wallets derive their own deposit addresses from an ECDH secret shared with the resolver operator, Aztec Labs today.",
"exposureContinued": "Matching the derived commitments against public portal deposits lets the operator link L1 deposits to L2 recipients. Payments, withdrawals and deposit claims are encrypted to an enclave admitted with an AWS Nitro attestation, which reads them inside.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"title": "Wallets derive deposit addresses against the resolver key",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/web-wallet/src/features/deposit/sipaGateway.ts#L857-L871"
},
{
"title": "Their nonces count down a predictable range",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/sdk/src/services/sipaSelfResolve.ts#L49-L58"
},
{
"title": "Wallets encrypt to the enclave key registered in the portal",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/vendor/oxide/yarn-project/oxide-client/src/fleet_signer.ts#L172-L202"
},
{
"contract": "ZkMoneyPortal",
"title": "Deposits publish the recipient commitment"
}
],
"id": "privilegedInsider",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
}
]
},
"futureAdversary": {
"sentiment": "bad",
"exposureShort": "Whoever breaks elliptic-curve cryptography can decrypt historical notes and payment events published to Ethereum.",
"exposureContinued": "Registered Aztec addresses identify the accounts. Deposit address secrets and enclave communication use the same class of cryptography.",
"interior": {
"sender": "exposed",
"recipient": "exposed",
"amount": "exposed",
"asset": "exposed",
"linkage": "exposed"
},
"sources": [
{
"contract": "AccountMetadataRegistry",
"title": "Registered Aztec addresses"
},
{
"title": "Deposit address secrets use secp256k1 key exchange",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/packages/sdk/src/services/sipaStealth.ts#L80-L100"
},
{
"title": "Enclave channel uses P-256 HPKE",
"url": "https://github.com/aztec-labs-eng/zkmoney-public/blob/f04743f5d57d1b89f9190cad0f6affd28b0793f2/vendor/oxide/yarn-project/oxide-lib/src/encryption.ts#L1-L5"
}
],
"id": "futureAdversary",
"value": "Link exposed",
"alsoExposed": [
{
"field": "sender",
"exposure": "exposed"
},
{
"field": "amount",
"exposure": "exposed"
}
]
}
}
},
"anonymitySet": {
"type": "partially-attributed"
},
"attributes": [
{
"id": "zk",
"label": "ZK",
"description": "Uses zero-knowledge proofs to prove private actions without revealing private data."
},
{
"id": "tee",
"label": "TEE",
"description": "Privacy assumptions of this project are secured by trusted hardware."
},
{
"id": "transfers",
"label": "Transfers",
"description": "Private transfers within the shielded pool."
},
{
"id": "anyAmount",
"label": "Any amount",
"description": "Deposits and withdrawals can have any size."
}
],
"category": {
"id": "shieldedLedger",
"label": "Shielded ledger",
"description": "A pool with transfers or DeFi inside. Hides who pays whom and which deposit became which withdrawal."
},
"exitWindow": {
"value": "Infinite",
"sentiment": "good",
"orderHint": 9007199254740991,
"description": "The escrow and the approved enclave image are immutable.",
"walkawayTest": {
"passed": false,
"reason": "Withdrawals and refunds need a live AWS Nitro enclave running the approved image. The approved sUSDS image is absent from the documented public downloads. The assessed DAI wallet requires modification to replace zk.money services."
}
},
"referenceClient": {
"name": "zk.money",
"repository": "https://github.com/aztec-labs-eng/zkmoney-public",
"commit": "f04743f5d57d1b89f9190cad0f6affd28b0793f2"
},
"relayerTracking": {
"type": "onchainEvents",
"sources": [
{
"address": "eth:0xdf410ad448A0f7165181FBdB32f8896f4a0d9449",
"sinceTimestamp": 1790298635,
"extractor": "zkMoneyWithdrawalRelayer",
"params": {
"tokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"executorAddress": "0xC2363b7155EE8391C5395B72C46a6d22BF49151c",
"operationExecutor": "0xe883686d9EC4E0430f2233A6BF12B2D226a39e19"
}
}
]
},
"reproducibility": {
"value": "Partially reproducible",
"sentiment": "warning",
"description": "The Ethereum contracts, desktop wallet, enclave and circuit sources are public. The refund and resolver verifiers match the published circuits. The complete enclave image build, resolver service and frozen-chain snapshot service are unpublished. The hosted wallet release is ahead of the to public source and thus unreproduced. Verification instructions cover the refund and resolver circuits and the DAI token pinned by its Ethereum portal."
},
"riskSummary": "## Funds can be stolen if\n\n1. Aztec's private execution or refund proof is unsound and the enclave layer also fails.\n2. malicious wallet code obtains a harmful signature, or substituted unsigned contract lists redirect future deposits and payments.\n3. the NameRegistry owner or owner of zk.money in ENS redirects future payments to names.\n4. a malicious sUSDS token upgrade confiscates escrowed shares (see upgrades and governance).\n\n
\n\n## Funds can be lost if\n\n1. a user loses their passkey.\n2. all registered signers stop serving and users cannot obtain or run the portal's approved enclave image (see walkaway test).\n3. resolver screening blocks an external payment and the recipient lacks the tooling to re-derive its deposit address.\n\n
\n\n## Privacy can be lost if\n\n1. a user pays a new contact, whose handshake reveals the recipient (see public observer).\n2. the resolver operator links L1 deposits to L2 recipients, or an enclave or AWS Nitro is compromised (see privileged insider).\n3. anyone on the user's network path times their Aztec transactions, since Desktop has no Tor or proxy setting (see network observer).\n4. the portal freezes, and refunds publish note or deposit amounts on Ethereum.\n5. elliptic-curve cryptography is broken, which decrypts data published to Ethereum (see future adversary).",
"riskSummary": "## Funds can be stolen if\n1. Aztec's private execution or refund proof is unsound and the enclave layer also fails.\n2. malicious wallet code obtains a harmful signature, or substituted unsigned contract lists redirect future deposits and payments.\n3. the NameRegistry owner or owner of zk.money in ENS redirects future payments to names.\n4. a malicious sUSDS token upgrade confiscates escrowed shares (see [upgrades and governance](#upgrades-and-governance)).\n
\n## Funds can be lost if\n1. a user loses their passkey.\n2. all registered signers stop serving and users cannot obtain or run the portal's approved enclave image.\n3. resolver screening blocks an external payment and the recipient lacks the tooling to re-derive its deposit address.\n
\n## Privacy can be lost if\n1. a user pays a new contact, whose handshake reveals the recipient (see public observer).\n2. a user's payments hide only among zk.money's users on Aztec (see chain analyst).\n3. the resolver operator links L1 deposits to L2 recipients, or an enclave or AWS Nitro is compromised (see privileged insider).\n4. anyone on the user's network path times their Aztec transactions, since Desktop has no Tor or proxy setting (see network observer).\n5. the portal freezes, and refunds publish note or deposit amounts on Ethereum.\n6. elliptic-curve cryptography is broken, which decrypts data published to Ethereum (see future adversary).",
"tokens": [
{
"token": {
"address": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"iconUrl": "https://assets.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
"symbol": "DAI",
"decimals": 18,
"priceId": "dai",
"sinceTimestamp": 1790298635
},
"buckets": [
{
"id": "zkmoney-DAI",
"type": "pool",
"label": "DAI",
"address": "eth:0xdf410ad448A0f7165181FBdB32f8896f4a0d9449",
"sinceTimestamp": 1790298635,
"anonymitySet": {
"minimumAmounts": [
"200000000000000000000"
]
},
"deposit": {
"event": "0x8154af7b1b360f500640de68c82af19c52c4ad4189d7a7c7a41506e19a1fdd6c",
"extractor": "zkMoneyDeposit",
"params": {
"tokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"fundingCut": "100000000000000000",
"factoryAddress": "0xc357E34D4C7520a83C9Ec0a242Ba52b4ecABa1Fc",
"depositImplementation": "0xF714D8Cf287F4A410b018514074A9371BC45461b",
"registrationImplementation": "0x0934F010d59b552949DBe44AcBE5AFf0e32C8C34",
"fundingTokens": [
"0x6B175474E89094C44Da98b954EedeAC495271d0F",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"0xdAC17F958D2ee523a2206206994597C13D831ec7"
],
"exchangeAddress": "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7",
"historyFromBlock": 26051085
}
},
"withdrawal": {
"event": "0x0ef2e2e9f18042ca214d1bee833209f28326ffa8f4a6b0dc92172caf71bc5433",
"extractor": "zkMoneyWithdrawal",
"params": {}
}
}
]
}
],
"trackedOn": [
"ethereum"
],
"upgradesAndGovernance": {
"content": "Aztec Network's rollup and zk.money's portals and payout contracts are immutable.\n\n### Enclave signers and freeze\n\nAnyone can register a signer with an AWS Nitro attestation up to 1 hour old. DAI has 2 registered signers, and sUSDS has 3. A change to Aztec's canonical rollup lets anyone freeze the portals permanently, enabling refunds at the last proven checkpoint.\n\n### Names and services\n\nTwo Aztec Labs EOAs control *.zk.money names. The deployer owns the NameRegistry and can replace its registration, metadata and resolver contracts, which lets it reassign names and redirect future payments. It also owns zk.money in ENS, which the DNS holder can reclaim. The domain owner can refuse claims, sign custom fees and add permanent fee beneficiaries, which users pick from in their registration intent. Aztec Labs also controls the hosted wallet, the desktop releases and the two unsigned contract lists both wallets currently use.\n\n### Savings asset\n\nSky governance can upgrade sUSDS, changing balances and transfer rules. Its authorized rate controller can change the savings rate."
},
"zkCatalogId": "barretenberg"
}