ZUL://DOCSPRIVACY LAYER 2 — SETTLED ON SOLANA
INDEX
SHIELDED POOL — /docs/shielded/privacy-limits

Privacy limits

A privacy system is defined by its failure modes. This page is the honest map of what an external observer of public data — the L2 ledger, the explorer, the L1 DA batches — can and cannot learn in v1.

The threat model

  • The sequencer is a trusted party in v1 — privacy against the operator (network metadata, submission timing) is explicitly out of scope at this stage.
  • The adversary reads everything public: every block, every pool transaction, every DA batch. The question is whether they can link a user's entry (shield) to their exit(unshield), or reconstruct the internal transfer graph.

What holds today

  • The internal graph is dark. Transfers expose nullifiers, commitments, and a proof — no amounts, no parties, no input↔output pairing.
  • Nullifiers don't backtrack. nf = Poseidon(commitment, leaf_index, s)is one-way without the owner's secret.
  • Note ciphertexts are opaque — X25519 + XChaCha20-Poly1305; recipients find their notes by trial decryption, observers find nothing.
  • Zero-knowledge survives even a bad trusted setup — setup compromise threatens soundness (theft), not privacy.

What still leaks (v1)

VECTORLEAK
Amount correlationShield and unshield amounts are public and arbitrary — a shield of 13.37 followed by an unshield of ≈13.37 is a match an observer will make.
Public fee payerEvery pool transaction is paid for by a visible signer in v1. Reusing a fee payer threads your pool activity together.
TimingEnter at 12:00, exit at 12:05, low pool traffic in between — the window itself is identifying.
Anonymity-set sizeEarly pools are small; you hide among the users who actually exist, per asset.

Practical guidance

  • Avoid distinctive amounts at the edges; round numbers blend.
  • Let time pass between entry and exit.
  • Use a fresh fee payer per pool transaction (until the relayer removes this footgun entirely).
  • Split internally before exiting — exit amounts that equal no entry amount defeat value matching.

Planned fixes

In priority order: fixed denominations at the public edges(entries/exits leak only "which bucket", internal transfers stay arbitrary) and the fee relayer (in-circuit fee output already exists for it). The two ship together — either alone still leaves a linkable path. Both are protocol-compatible upgrades to the data model documented in Notes & commitments.

RULE OF THUMB

Today's pool hides what happened inside extremely well, and who entered/exited only as well as you let it. Behave at the edges accordingly.