Nullifier Epochs
How ZORB Cash keeps storage costs low
Nullifier Epochs
TL;DR: ZORB Cash prunes old nullifier data instead of storing it forever. This makes the protocol ~100x cheaper to operate long-term.
The Problem
Every privacy protocol needs to prevent double-spending. When you spend a note, it creates a "nullifier"—a unique identifier that gets recorded so the same note can't be spent twice.
Most protocols store nullifiers forever. This works, but storage costs grow without bound. On Solana, this means paying rent for an ever-growing list of spent notes.
Our Solution: Epochs
ZORB Cash uses a two-layer system:
- Recent nullifiers — Stored as individual on-chain accounts (PDAs)
- Historical nullifiers — Compressed into a Merkle tree
Every ~5 minutes, an epoch advances. Nullifiers from old epochs get inserted into the Merkle tree, and their individual accounts can be closed.
Epoch 0 Epoch 1 Epoch 2 ... Epoch 30 Current
────────────────────────────────────────────────────────────
│ Provable Range (30 epochs) │
└──────────────────────────────────────────────┘
Epochs older than 30 can be pruned:
• Close EpochRootAccount → reclaim ~64 bytes rent
• Close NullifierAccount → reclaim ~56 bytes rentWhy This Works
The key insight: once a nullifier is in the Merkle tree, we don't need its individual account anymore. The tree proves the nullifier exists.
We keep a 30-epoch window (~2.5 hours) to give transactions time to finalize. After that, the data can be safely pruned.
Economic Incentive
Anyone can call the cleanup instructions and keep the reclaimed rent. This creates a natural incentive for keepers to maintain the protocol.
No coordination needed—if cleanup is profitable, someone will do it.
The Numbers
| Metric | Value |
|---|---|
| Epoch duration | ~5 minutes (configurable) |
| Retention window | 30 epochs (~2.5 hours) |
| EpochRootAccount size | 64 bytes |
| NullifierAccount size | 56 bytes |
| Tree capacity | 67 million nullifiers |
See Also
- Key Hierarchy — Spending vs. viewing keys
- Shielded Yield — Earning on private balances
- Circuit Design — How nullifiers are proven in ZK