Protocol
Operations

Escape hatch

The exit that needs no attester, what it requires instead, and what it discloses about the note you take out.

Umbra's clients, not the protocol

The platform wallet this page refers to is the wallet committed in slot 4 of your identity, which an escape discloses. That Umbra's clients derive it, and your keys, from your account signature is their standard, not a protocol rule.

The escape hatch takes one note out of the pool to a public Solana address with nothing but a zero-knowledge proof. It needs no guardian node, screener, fee enclave, data endorser, zone signature or relayer, so it keeps working when any of them is down or refuses. The price is privacy: the exit publishes the note's contents, including the identity that owned it. The note is spent at once, but the payout waits in an escrow for 48 hours before anyone can release it to the destination.

When to use it

A normal withdrawal needs the combined attester signature of all six attesters and an Active guardian cluster. The escape hatch is for when that is not possible:

  • a guardian node, the screener, the fee enclave or the data endorser is offline, frozen or refusing to sign;
  • the guardian cluster is not Active, for example Degraded because a member is down, or Frozen by governance;
  • a zone authority will not sign a transfer out of its zone;
  • no relayer will carry your transaction.

It is available whenever the pool program runs.

What it needs

  • An escape-hatch proof, made on your device. It stands in for both the attester signatures and the freshness proof: it shows that the note is in the note tree, that its nullifier is not yet spent, and, for an identity-owned note, that you know the keys behind its owner.
  • A path and a nullifier witness from any copy of the chain. Every note commitment and nullifier is in public instruction data, so the indexer or any other mirror can supply them.
  • A submitter who signs and pays the Solana fee. The proof names the submitter, so it is chosen before proving.
  • The owning address's signature, for a program-owned note, since such a note has no identity keys to prove with.
  • An escape-hatch fee accrual for the pool index and token, when the fee is not zero. Anyone may create one.
  • Rent for the escrow, paid by the submitter and returned on release, except that a Token-2022 escrow token account stays open with its rent.

What it does without

Nothing screens the destination. The token's allowlist entry is not checked, so a revoked token can still leave, and the owner need not be in the identity tree: knowing the keys behind the owner commitment is enough.

How an escape runs

An escape has three parts. Your device gathers a path and a witness and makes the proof. The submitter sends escape_hatch, and the shielded pool checks it, spends the note and moves the payout into an escrow, all in one instruction. From 48 hours later, anyone can release the escrow to the destination.

Preparing needs nothing from Umbra's services, only a copy of the chain.

sequenceDiagram
participant U as Your device
participant M as Chain mirror
U->>M: path for the note
M-->>U: path at a recent root
U->>M: gap for its nullifier
M-->>U: witness at a recent root
U->>U: escape-hatch proof

1. Your device fetches a path and a gap witness

Your device asks a chain mirror for a path to the note from a recent note tree root, and a witness that the note's nullifier falls in a gap of the nullifier tree at a recent nullifier root. The mirror need not be trusted: a wrong answer gives a proof that will not verify.

2. Your device proves the escape

The proof covers one note, one token and one destination. It discloses the note's fields and binds the destination, the withdrawal rate and every account the instruction uses, the submitter's included.

3. You, or anyone you ask, signs and submits

The submitter signs and pays, and so does the owning address for a program-owned note. Because the proof binds the destination account itself, the submitter cannot make the escape pay any other account.

The shielded pool then settles the escape in one instruction.

sequenceDiagram
participant S as Submitter
participant P as Shielded pool
participant T as Pool token account
participant E as Escrow
S->>P: escape_hatch
P->>P: check token, roots, policy
P->>P: check destination, verify proof
P->>P: stage nullifier
P->>E: create escrow
T->>E: amount less fee
P->>P: add fee to accrual

4. The shielded pool checks the token, the roots and the proof's age

The token must be an SPL Token or Token-2022 mint other than Token-2022's native mint, whatever its extensions. The note tree root must be among the 512 most recent, the nullifier root must still be active in the staging buffer, and the proof's execution slot must fall inside the process policy's proof-age window, which governance sets between 300 and 216,000 slots.

5. The shielded pool computes the fee and checks the destination

The fee is the default withdrawal rate, at most 500 basis points, on the note's whole amount, rounded up, with no per-token rate, discount or same-owner exemption. The destination must be the account the proof was made for and writable in the transaction: a wallet for SOL, or an initialized token account of the note's token. An associated token account is the safest choice, since if it is ever closed only the same owner and token can recreate it at that address.

6. The shielded pool verifies the proof

A program-owned note needs its owning address's signature, the same rule a value transaction applies. The program builds the proof's public input from its own reads of the roots, the token, the destination and the rate, and verifies it under the escape-hatch key compiled into the program, so a proof made for any other value fails.

7. The shielded pool spends the note, holds the payout and keeps the fee

The nullifier is staged in the same staging buffer value transactions use, so the note is spent from here on and cannot also leave by a withdrawal. Escapes never wait for room in the nullifier tree, because a pool index stops taking value transactions while that tree still has a place for every note in it (see the note tree). The payout, the amount less the fee, moves into an escrow account of the shielded pool that records the recipient and the release slot. The fee goes to a public escape-hatch fee accrual and later to the treasury (see fee collection).

8. Anyone releases the escrow after 48 hours

The escrow can be released 864,000 slots after the escape: 48 hours at the 200 milliseconds per slot the protocol counts with, and longer in practice, since Solana slots usually take more. Until then nothing can stop, cancel or redirect the payout, governance included, short of an upgrade of the pool program. From the release slot on, anyone can call release_escape_escrow, with no signature and no proof.

sequenceDiagram
participant A as Anyone
participant P as Shielded pool
participant E as Escrow
participant X as Destination
A->>P: release_escape_escrow
P->>P: check release slot, recorded accounts
E->>X: payout
P->>E: close, rent to submitter

The release pays only the recipient the escrow recorded, then closes the escrow and returns its rent to the submitter, so it cannot be released twice.

What it discloses

The escape publishes the note it spends: its kind (identity-owned or program-owned), zone, full amount rather than only the payout, validity window and memo hash, and the slot and position at which it entered the tree, which identify the transaction that created it. For an identity-owned note it also publishes your identity commitment and the platform wallet committed in your identity, which registration links to your main wallet in public. For a program-owned note it publishes the owning address's commitment. The token, destination, fee and submitter are public too. What stays private is the note's version, who paid the note in, and its blinding factors.

Escape hatch
Everything a chain observer can read
Program
Shielded pool, escape_hatch
Submitter and fee payer
Whoever signs it
Owner
The identity commitment or owning address
Platform wallet
The one committed in that identity
Note amount and token
Both, in full
Destination
Any writable address
Fee
Derived from the amount and the public rate
Note position and slot
Which leaf, so which transaction created it
Zone and validity window
As recorded in the note
Who funded the note
Private
Blinding factors
Private
The escape hatch trades the attesters for disclosure. The note it spends is readable in full.

What can go wrong

  • The note is already spent or pending. Its nullifier is in the nullifier tree or the staging buffer, so the escape is refused.
  • A root or the proof aged out. The escape must be proved again against current roots.
  • The fee accrual is missing. With a fee above zero, the escape fails until someone creates the accrual.
  • The destination does not match. A proof made for one account fails for any other, even one with the same owner.
  • The destination is read-only. An escape to a built-in account such as the System Program is refused, and the note stays unspent.
  • The owner did not sign. A program-owned note cannot leave without its owning address's signature.
  • The release is not due. Before the release slot the release is refused, and the payout stays in escrow.
  • The recipient's token account is closed. The release fails until an account exists at that address again.

Privacy notes

  • It discloses the note's owner. Anyone can see that your identity took this amount of this token out, and where it went.
  • It points back to the note's origin. The note's position identifies the transaction that created it, though that transaction's other contents stay private.
  • It exits one note at a time. A balance spread over several notes needs several escapes, each disclosing its own note.
  • The submitter is public. Whoever signs is on chain as the fee payer.

Last updated

On this page