# Umbra Cash Markdown version of https://ethbeat.org/privacy/projects/umbra ## Summary - Total Value Locked: N/A - Assets tracked: 5 - Buckets tracked: 5 - Deposits 7D: 11 (-15.3% compared to the previous seven days) - Deposits 30D: 81 - Deposits Total: 25.50 K - Tracked on: Ethereum - Attributes: Any amount, Stealth addresses - Reference app: Umbra app ### Risks - Privacy: Recipient privacy. Public observer: Recipient private (sentiment: good); Chain analyst: Recipient private (sentiment: good); Network observer: Recipient at risk (sentiment: warning); Privileged insider: Recipient at risk (sentiment: warning); Future adversary: Recipient exposed (sentiment: bad). - Trusted setup: No setup (sentiment: neutral). No setup: This project does not have a ZK system and thus no setup-related trust assumptions. - Exit window: Infinite (sentiment: good). The contracts are immutable. The toll applies only to new payments, so recipients can always withdraw what they received. This protocol passes the walkaway test: users can still fully use it if every centralized participant disappears. - Reproducibility: Reproducible (sentiment: good). 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. ### About A stealth-address payment protocol for an existing wallet: the user registers once, and anyone can pay them at a fresh address. ### Links - Website: https://app.umbra.cash - Docs: https://app.umbra.cash/faq - Repository: https://github.com/ScopeLift/umbra-protocol - Social: https://x.com/UmbraCash, https://discord.com/invite/uw4y5J2p7C - Other: https://diligence.security/audits/2021/03/umbra-smart-contracts/ - Contracts explorer (Disco): https://disco.l2beat.com/ui/p/umbra ## Protocol description Umbra Cash is a stealth-address protocol that lets anyone pay the user at a fresh address, so the payment does not identify them as its recipient. The user registers once, and payers find their keys in a public registry. Payer, amount and token stay public, and so does where the funds go next. Users trust ScopeLift, which hosts the app, runs its indexer and relays token withdrawals. The contracts are immutable, and their owner can only set a fee on new payments. Leaving needs no one: ETH lands at the stealth address itself, and any account can relay a token withdrawal. ### Flow 1. **Register.** The app derives a spending and a viewing key from a wallet signature and publishes the public keys in the StealthKeyRegistry. 2. **Pay.** The payer's app derives a fresh stealth address from those keys and pays through the Umbra contract. ETH goes straight to the address, tokens wait in the contract. An event publishes the address with a secret only the viewing key decrypts. 3. **Scan.** The recipient's app fetches every payment since registration and decrypts each locally. 4. **Withdraw.** ETH leaves in a plain transfer that pays its own gas. Tokens leave through a relayer, which pays the gas for a fee against the recipient's signature. ### App The app is built from public source, while its indexer and relayer API are closed. It finds payments through the indexer, relays token withdrawals through the API and checks every address it handles with its mainnet RPC, Alchemy. The app warns before withdrawals to registered, named or otherwise known addresses. A local build can leave the indexer out and read the chain from the user's own node. It still asks Cloudflare for the ENS name of the user's wallet, and building it needs a WalletConnect project id and L2 subgraph URLs. The [privacy policy](https://app.umbra.cash/privacy) keeps IP logs for up to 90 days. ### Compliance Screening runs in the app only. It refuses wallets, recipients and withdrawal addresses on its blocklist or Chainalysis's sanctions oracle, and hides payments from or to listed addresses. ### Fees Each payment through the Umbra contract pays the owner's ETH toll, 0 ETH today. Token withdrawals through the relayer pay its fee in the withdrawn token, and ETH withdrawals pay only gas. ## Privacy **What the protocol promises:** Hides which registered recipient a stealth payment is for. The payer knows; sender, asset, amount and where the funds go next are public. **Apps** - **[Umbra app](https://app.umbra.cash)** (Reference): The ratings assume this app, since 2026-09-16 · Source [947c4f3](https://github.com/ScopeLift/umbra-protocol/tree/947c4f3b9b89f6cf5d69b2d43d3cffec673da655) [How we pick the reference](https://ethbeat.org/publications/privacy-methodology#reference-app) Ethereum is public by default. Each protocol is rated on its main privacy promise, like hiding who paid, who received, how much, or which deposit became which withdrawal. Against each adversary, the colour says whether it holds for a careful user with the app's own settings: green yes, yellow only with significant extra work, red no. Fields marked at risk stay private only under the condition in their note. ### Public observer Recipient private (sentiment: good) **Who:** 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. Each payment goes to a fresh stealth address, and only the recipient's viewing key shows whose it is. 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** - [Announcement and TokenWithdrawal publish the fund path](https://ethbeat.org/privacy/projects/umbra#Umbra) - [StealthKeyChanged publishes recipients and key changes](https://ethbeat.org/privacy/projects/umbra#StealthKeyRegistry) - [Matching decrypts the secret with the viewing key and checks the stealth address](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/classes/Umbra.ts#L707-L721) ### Chain analyst Recipient private (sentiment: good) **Who:** Scrapes all public data and correlates it: timing, amounts, gas and wallet fingerprints, address clusters. Examples: Chain analytics firms, ZachXBT, data brokers. Any of the 11,983 registered recipients could be behind a stealth address. 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** - [Each registration is public with its block](https://ethbeat.org/privacy/projects/umbra#StealthKeyRegistry) - [Kovács and Seres: reuse heuristics and their reach on mainnet (sections 6 and 7)](https://arxiv.org/html/2308.01703v2#S6) - [The app warns about registered, named and sender destinations, and lets the user proceed](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/utils/address.ts#L146-L241) ### Network observer Recipient at risk (sentiment: warning) **Who:** Sits between the user and the services and sees traffic only: ISPs, VPNs, Tor exits, public RPCs and relayers. Ties requests to a user by content, session or timing: what they name, a shared IP or login, and when they arrive. 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. The hosted app checks the payee's address with its Alchemy RPC seconds before each payment, so timing ties the payee to the payment. The same RPC gets the payee's wallet on connect, the sender of every matched payment on each scan, and the withdrawal address. The wallet's own RPC receives the wallet address together with the matched stealth addresses. On connect, the wallet library also sends the 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** - [Sending checks the recipient against a sanctions list through the app's mainnet RPC](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/classes/Umbra.ts#L219-L227) - [Connecting checks the wallet address through the same RPC](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/store/wallet.ts#L273) - [Withdrawing checks the destination through the same RPC](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/components/AccountReceiveTable.vue#L736) - [Matched stealth addresses go to the wallet RPC in one balance call](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/components/AccountReceiveTable.vue#L606-L625) ### Privileged insider Recipient at risk (sentiment: warning) **Who:** Holds an operator role, custodies funds, receives keys or plaintext by design, or delivers the app: 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. The hosted app gives the operator the user's wallet address on every scan and withdrawal address in the same session. 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 app instead of the hosted frontend. Leave its indexer URL empty, so it reads payments from the user's node. **Sources** - [Each scan first asks the indexer for the connected wallet's registration](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/utils/utils.ts#L336-L349) - [The registry read stores no block, so the lookup repeats on every scan](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/store/wallet.ts#L605-L615) - [Every withdrawal sends the destination to the operator's API](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/utils/address.ts#L201-L214) - [Token withdrawals send the stealth address to the relayer](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/frontend/src/components/AccountReceiveTable.vue#L767-L768) ### Future adversary Recipient exposed (sentiment: bad) **Who:** 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. Whoever breaks elliptic-curve cryptography matches every past payment to its registered recipient from chain data alone. 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** - [Announcement archives the one-time key and ciphertext](https://ethbeat.org/privacy/projects/umbra#Umbra) - [Historical public viewing and spending keys](https://ethbeat.org/privacy/projects/umbra#StealthKeyRegistry) - [A shared secret from elliptic-curve keys encrypts the secret](https://github.com/ScopeLift/umbra-protocol/blob/947c4f3b9b89f6cf5d69b2d43d3cffec673da655/umbra-js/src/classes/KeyPair.ts#L121-L157) ## Anonymity sets ### 30 day historic anonymity set How many unique registrants you could have blended in with if you received a stealth address transfer on a particular day after registering keys during the previous 30 days. This metric is a proxy for the historic anonymity set and shows how it developed over time. The metric looks backwards: it counts key registrations that already happened, and a registered address has not necessarily received any transfers. Your real anonymity also depends on registrations made after yours, which cannot be known in advance. ### Estimated anonymity set by waiting time An estimate of how many unique registrants you blend in with, depending on how long you wait between registering keys and receiving a stealth address transfer. It is based on historic data of past registrations: each point counts registrants from the preceding period, so waiting for up to 30 days effectively means blending in with everyone who registered during the last 30 days. The interactive charts are shown on [the HTML page](https://ethbeat.org/privacy/projects/umbra#privacy-anonymity-set). ## Flows The interactive flows chart is shown on [the HTML page](https://ethbeat.org/privacy/projects/umbra#privacy-flows). ## Assets Breakdown | Asset | Deposits 7D | Deposits 30D | Deposits Total | | --- | --- | --- | --- | | DAI | 1 ($9.99 K) | 2 ($21.99 K) | 175 ($826.10 K) | | ETH | 10 ($158.43 K) | 21 ($158.60 K) | 23.75 K ($118.84 M) | | USDC | 0 ($0.00) | 10 ($152.26 K) | 717 ($4.75 M) | | USDT | 0 ($0.00) | 48 ($820.79 K) | 695 ($7.31 M) | | WBTC | 0 ($0.00) | 0 ($0.00) | 162 ($11.22 M) | | Total | 11 ($168.43 K) | 81 ($1.15 M) | 25.50 K ($142.97 M) | ## Risk summary ### Funds can be lost if 1. 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. ### Use can be stopped if 1. the Umbra owner raises the toll on payments through the contract, which has no cap. ### Privacy can be lost if 1. the operator links the user's wallet to their stealth addresses, since the hosted app sends it both in one session (see privileged insider). 2. 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). 3. elliptic-curve cryptography is broken, which matches every past payment to its registered recipient (see future adversary). ## Upgrades & Governance 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. ## Updates Each date links the update on the HTML page, which also shows its contract diffs. ### [2026-10-09 07:23 UTC](https://ethbeat.org/privacy/projects/umbra?update=f01747ad) (1 change) Added UmbraBatchSend, which the app uses for batch payments. Moved Umbra and StealthKeyRegistry from config overrides into templates, with no value changes. ### [2026-08-17 09:44 UTC](https://ethbeat.org/privacy/projects/umbra?update=73958e78) (high severity, 3 changes) 7702 delegation. ### [2026-07-31 11:57 UTC](https://ethbeat.org/privacy/projects/umbra?update=7c965433) (2 changes) Initial discovery of Umbra contracts ## Permissions Explore these contracts and permissions in Disco, ETHBEAT's contract explorer: https://disco.l2beat.com/ui/p/umbra ### Ethereum #### Actors ##### EOA 1 Addresses: [0x5777Aa6F437399Af6cef2Fce0BE8D4B4eD7C7232](https://etherscan.io/address/0x5777Aa6F437399Af6cef2Fce0BE8D4B4eD7C7232) - Can interact with Umbra - set an arbitrary ETH toll that must be paid on every transfer routed through the Umbra contract ##### EOA 2 Addresses: [0xB7EE870E2c49B2DEEe70003519cF056247Aac3D4](https://etherscan.io/address/0xB7EE870E2c49B2DEEe70003519cF056247Aac3D4) - Can interact with UmbraBatchSend - approve new tokens so that batch sends can route them to the Umbra contract ## Smart contracts ![A diagram of the smart contract architecture](https://ethbeat.org/static/images/architecture/umbra.5263be65.png) Explore these contracts and permissions in Disco, ETHBEAT's contract explorer: https://disco.l2beat.com/ui/p/umbra ### Ethereum #### StealthKeyRegistry Addresses: [0x31fe56609C65Cd0C510E7125f051D440424D38f3](https://etherscan.io/address/0x31fe56609C65Cd0C510E7125f051D440424D38f3#code) Public registry that maps an Ethereum address to its two secp256k1 stealth public keys: a spending key used to derive a fresh stealth address, and a viewing key used to encrypt the transfer metadata for the recipient. #### UmbraBatchSend Addresses: [0xDbD0f5EBAdA6632Dde7d47713ea200a7C2ff91EB](https://etherscan.io/address/0xDbD0f5EBAdA6632Dde7d47713ea200a7C2ff91EB#code) Helper the app uses to send several stealth payments in one transaction. It pulls the tokens from the sender and calls the Umbra contract once per payment, so each payment emits its own Announcement. It holds no funds between transactions. - Roles: - **owner**: EOA 2 #### Umbra Addresses: [0xFb2dc580Eed955B528407b4d36FfaFe3da685401](https://etherscan.io/address/0xFb2dc580Eed955B528407b4d36FfaFe3da685401#code) Main entry point of the Umbra protocol, routing all ETH and ERC-20 stealth payments. On send, it emits an Announcement event that the recipient scans to detect the payment. ETH is forwarded directly to a fresh stealth address, ERC-20s are escrowed in this smart contract. - Roles: - **owner**: EOA 1