Architecture
ZeroK breaks the on chain link between what you deposit and what you spend, using zero knowledge proofs and a shared shielded vault. One program on Solana mainnet serves both native SOL and SPL tokens such as USDC.
One program, two kinds of asset
Everything runs from a single deployed program:
HVcTokFF4rwvcU7sC7GjS317CSf7QDgfCvW7edijKS2vInside it, a pool is identified by the pair (mint, denomination). The denomination is a label that
names the pool, not a limit on what you can deposit.
| Pool | Address | Asset |
|---|---|---|
| SOL | 2AhYLs7wEyMFGpYS3jEyRty9uTdCbfDiV5NrfCBZda3E | native SOL |
| USDC | 4QyozMXeHcu2ifqTFJc4ygptFAEZP8zXsZXDN9kniRa6 | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
A pool knows which kind of asset it holds by looking at its own mint field. If the mint is unset, the pool is native SOL and value moves as lamports. If a mint is present, the pool is a token pool and value moves through a vault token account. The two paths cannot be confused for one another, because no account can be both an unset address and a valid mint at the same time.
This is why adding a stablecoin did not need a new program, a new deployment or a new ceremony. The USDC pool inherits the verifying keys that were already finalised on the program.
Notes, not balances
When you deposit, the program does not credit an account. It appends a commitment to a Merkle tree, and you keep the secret behind it. That commitment is a note: a claim on some value in the vault that only you can spend.
Your deposit is split into notes on a denomination ladder of round sizes. SOL uses a ladder from 0.01 upward, USDC from 0.1 upward. Depositing 28.8 USDC produces notes of 20, 5, 2, 1, 0.5, 0.2 and 0.1. You never choose the sizes, and you never pick a pool.
The tree is 24 levels deep, which is room for millions of deposits.
Spending
To pay someone, your device builds a Groth16 proof that you own a note in the tree, without revealing which one. The proof is verified on chain. Alongside it the program records a nullifier, a value derived from the note that reveals nothing about it but is unique to it. A second attempt to spend the same note fails, because the nullifier is already present.
If your note is larger than the payment, the difference comes back to you as a fresh note. If it is smaller, several notes are spent together.
The relayer
You do not submit the withdrawal yourself. A relayer does, and it pays the network fees, which is what makes a withdrawal gasless for the recipient. If the recipient is a wallet that has never held the token, the relayer also pays the rent to create their token account. A recipient holding zero SOL can receive USDC and still hold zero SOL afterwards.
The relayer covers those costs from a small per transaction protocol fee taken out of the amount before the recipient is paid, so the payment you preview is the payment they receive. The fee is a live field on the pool account rather than a compiled constant, which is why the client reads it from chain and shows it to you before you send.
Be clear about what the relayer does and does not know. It receives the recipient and the amount, because it has to in order to build the transaction. What it cannot do is change either one: both are bound into the proof as public inputs, so altering them invalidates it. It never holds your funds, it never learns which deposit funded the payment, and it has none of the secrets needed to spend a note.
Recovery
The secrets that let you spend are encrypted to a key derived from a signature by your own wallet, and stored on chain alongside the deposit. Reconnect the same wallet on any machine and your balance is rebuilt from the chain itself.
That key is derived from your wallet and decrypts only your own notes. There is no viewing key held by us or by anyone else, and no committee that can see inside the pool.
What this design does not do
The proof hides which note you spent among the notes in the pool. That means the strength of the privacy depends on how many notes are in there with yours. Cryptography guarantees the property, but the size of the crowd sets how much it is worth, and this pool is young. Every deposit makes the next one stronger.