Overview
The shielded pool is ZUL's reason to exist: a UTXO-style, multi-asset pool (ZUL and bridged SOL) enshrined as a builtin program in the node. Value inside the pool is held as private notes; moving it reveals nothing about sender, receiver, amount, or even which asset moved.
The model in one paragraph
A note is a commitment to (asset, amount, owner) stored in an append-only Merkle tree. Spending a note reveals only its nullifier — a one-way tag that prevents double-spends without pointing back at the note. A Groth16 proof ties everything together: you own the notes you spend, value is conserved, and the nullifiers are correct. The proof is generated in your browser and verified natively by the node.
Three operations
| OP | PUBLIC | PRIVATE |
|---|---|---|
| Shield | Depositor, amount, asset | The note's owner secret |
| Transfer | Nullifiers, new commitments, proof | Sender, receiver, amounts, asset |
| Unshield | Recipient, amount, asset | Which note was spent; change |
Step-by-step flows are in Shield, transfer, unshield.
Why enshrined, not a contract
- Native verification — Groth16 over BN254 verifies in native Rust on the node, free of BPF compute budgets.
- Protocol-level vaults — pool value is held in protocol-controlled vaults for ZUL (native lamports) and SPL assets, moved only by verified pool instructions.
- One pool, all users — privacy loves company; a single enshrined pool concentrates the anonymity set instead of fragmenting it across contracts.
Public counters only: total commitments, total nullifiers, the current tree root, and per-transaction note deltas. Amount columns on /explorer/shielded are rendered as sealed — the data does not exist publicly.
Honest scope: privacy holds against external observers of public data, with known v1 caveats around fee payers and edge amounts — read Privacy limits before relying on it.