Robinhood assets and tree rollover
Native ETH backing, depositor checks and spending across successive Robinhood note trees.
The Robinhood pool uses one private asset identifier for ETH and WETH, holds its backing as native ETH, and retains earlier note trees after opening a successor. These changes require a fresh deployment with matching clients and services; they do not migrate an existing deployment's WETH backing.
ETH and WETH share one private balance
The configured WETH address identifies the asset in notes, proofs and accounting. A wallet still holds ETH and WETH separately, but either can fund a note of that asset. A native deposit leaves its ETH in the pool contract. A WETH deposit transfers WETH from the depositor, measures the receipt and unwraps that receipt into ETH. The contract checks that the unwrapping delivered the same amount of ETH.
A withdrawal can request ETH or WETH. An ETH withdrawal pays native ETH directly. A WETH withdrawal wraps only its payout amount before transferring WETH to the recipient. Escape escrows reserve part of the same native balance, preventing ordinary payouts from using the reserved backing. If the recipient of a released escape escrow refuses ETH, the contract wraps that payout and transfers WETH so the already-spent note can still leave.
A native deposit names its payer
The inflow lane consuming attached ETH must name the transaction sender as its counterparty. The depositor's consent signature remains a separate requirement. If Alice signs a deposit lane but Mallory submits the transaction with her own ETH, the pool rejects it because the sender and the signed counterparty differ. A relayer therefore cannot supply native ETH for a lane naming another depositor, even when that depositor has signed consent.
WETH and other ERC-20 inflows are transferred from the lane's named counterparty. Their funding source is determined by the token transfer, rather than by attached ETH.
Note trees open in order
Tree set zero is active initially. Each set has a note commitment tree, a fee commitment tree and a fee queue. Only the active set accepts new output notes and newly staged fees. Anyone may open its immediate successor once the active set is full; the contract refuses skipped indexes and refuses an early opening.
Fullness accounts for leaf capacity, root-sequence capacity and space reserved for queued fee notes. A set becomes full when it cannot accept another ordinary transaction's three output notes and three fee notes. Rollover therefore does not depend on anyone filling a final one- or two-leaf remainder. Queue admission reserves enough room for the fees to be inserted later, including after a successor opens.
Earlier trees and their root histories remain available for spending. A value transaction spends notes from one source tree and appends its outputs to the active tree. The signed transaction context binds both indexes. Notes from different source trees cannot be combined in one proof; moving older notes into the active tree makes them available for a later combined spend. Escape withdrawals select their source tree without appending replacement notes.
Leaf commitments and nullifiers use a global insertion position: the tree index multiplied by 2^32, plus the position within that tree. Merkle paths still use the position within the selected tree. Reusing a note owner's derivation key and blinding at the same local position in two trees therefore produces different nullifiers. Indexed append events retain local positions, which clients combine with the emitted tree index.
Shared state and retained fees
Asset backing, identity registration and all three turnstiles remain shared across tree sets. Opening another note tree does not create another copy of a private balance or another place where a spent nullifier can be admitted. The pool reserves nullifier capacity for exits across all retained note trees. Opening successors does not make that shared capacity unlimited.
Fee notes belong to the tree set that received the transaction's outputs. Its queue remains drainable after rollover, and fee collection selects the retained fee tree containing the notes. The fee-nullifier turnstile remains shared, so collecting through another tree index cannot make an already-spent fee note spendable again.
Serving retained trees
Append mirrors and Merkle API replicas serve a configured tree set through
UMBRA_INDEXER_POOL_INDEX. Operators retain replicas for earlier sets and configure replicas
for successors. A fee-path request must reach the replica serving its requested set; another
replica refuses the request. Identity and nullifier services continue to use the shared set zero.
The fee collector reconstructs its configured fee tree from contract events and uses the shared
fee-nullifier mirror when preparing collection proofs.
Last updated
The note tree
The append-only Merkle tree that holds every note's leaf, how it fits four billion leaves into 19,249 bytes, how leaves are numbered across pool indexes, and what happens when a tree fills.
Every tree
All eight Merkle trees the protocol keeps, what each one holds, its shape, how long its old roots stay usable, and which instruction writes it.