Privacy Wallet · Technical Docs

Security model

Threat protection

Defenses against double spends, tree inconsistencies, invalid proofs, insolvency, and relayer abuse.

Double-spend prevention

  • Unique nullifiers. Each note maps to a single nullifier derived from a secret key and spend nonce.
  • On-chain flags. For every observed nullifier, aNullifierFlag PDA is created and stored permanently.
  • Strict rejection. Reuse results in a revert.

Merkle tree integrity

  • Root history. Only roots present in the history buffer are accepted, preventing arbitrary tree replacement.
  • Atomic operations. Commitments and root updates occur in one transaction.
  • Deterministic hashing. VoidHash ensures a unique root for any set of leaves.

Proof verification

  • Groth16 enforcement. All join–split transitions must carry a valid proof or fail with InvalidProof.
  • Input validation. Public inputs are checked for length, encoding, and consistency.
  • All-or-nothing. Any invalid component triggers a full revert.

Pool solvency

  • Tracked totals. The program maintains counters for total deposited and withdrawn.
  • Solvency invariant. Before any withdrawal, the program enforces pool_lamports ≥ deposited - withdrawn.

Relayer authorization

  • Authorized key. Only the configured relayer key may execute prepared withdrawals.
  • Economic incentives. The fee model compensates relayers for risk and gas.