How Saturn works
Saturn is a shared HYPE pool on Elysium. You deposit from one wallet and later withdraw to another. On chain, the withdrawal carries a zero-knowledge proof that it spends some approved deposit in the pool, without saying which one.
The contracts and circuits are Privacy Pools by 0xbow (Apache-2.0), with two changes: the entrypoint is not upgradeable, and its fee settings are capped in code.
What happens on chain
- Deposit. The pool stores a commitment, a Poseidon hash of the amount, a label it assigns, and a hash of two secrets only you know. Deposits are public: everyone sees the wallet and the amount.
- Withdraw. You prove three things at once: you know the secrets of a commitment in the pool, its label is in the approved set, and the amount fits. The pool marks that commitment spent, pays out, and adds a new commitment for whatever is left.
- Nothing links the two. The proof reveals a nullifier, a value derived from your secret that can be used once, so the same note can't be spent twice. It does not reveal the commitment, the label or the depositor.
Notes and the recovery phrase
The app makes a 12 word phrase in your browser and derives every secret from it: the first deposit's secrets come from note number 0, the next from 1, and each partial withdrawal gets the next child secret. Scanning public events with the phrase rebuilds every note on any device.
The phrase stays in this browser's storage and is never sent anywhere. If you lose it, nobody can withdraw or return your notes. If someone else gets it, they can withdraw them.
The approved set
A withdrawal must prove its deposit's label is in the approved set, a Merkle tree whose root the pool reads from the entrypoint. The keeper posts a new root every time the set changes.
- A deposit is approved one hour after it lands, unless the depositing wallet is on the blocklist.
- The full list of approved labels is public at
/api/state, and the root's record carries the sha256 of that list. - Only the latest root is accepted. If it changes while you build a proof, the app builds a new one.
The relayer
A fresh wallet has no HYPE for gas, and paying for it from your old wallet would link them. So the app sends the proof to the relayer, which submits it and is paid 0.5% of the amount withdrawn.
The relayer sees the receiving address and the amount, and can't change either: both are bound into the proof. It simulates the withdrawal before sending, so a bad proof costs nothing.
Ragequit
If a deposit is never approved, or you change your mind, the wallet that made it can take the whole note back at any time with a ragequit proof. This is public and links the note to that wallet. It works even if the approved set stops being updated.
Fees and limits
- 0.3% of each deposit, kept by the entrypoint. The contract caps it at 1%.
- 0.5% of each withdrawal, to the relayer. The contract caps relay fees at 1% for this pool, and at 5% in code.
- Minimum deposit 0.05 HYPE. Withdraw any part of a note, any number of times.
What the owner can do
- Register a pool for another asset, change fees within the caps, stop new deposits into a pool, and collect the deposit fees.
- Change who posts the approved set.
- There is no function that moves deposits, and no upgrade path. Stopping a pool stops deposits only: withdrawals and ragequits keep working.
How private it is
Your withdrawal could have come from any approved deposit with enough left in it. With few deposits, or a deposit of an unusual size followed by a withdrawal of nearly the same size, a watcher can guess. Wait for more deposits, use round amounts, withdraw in parts, and send to wallets that have never touched yours.
The website and the relayer see your IP address, like any site. The proof is built locally and no secret leaves your browser.
Tools in the app
Privacy meter. For the amount you are about to withdraw, the app counts the approved deposits at least that large (any of them could have paid it), the deposits made after yours, and the time since your deposit. It rates the result Weak, Fair or Strong and says what would raise it. Everything comes from public events; nothing is sent anywhere.
Split across wallets. One withdrawal form can send a note to up to four addresses in equal parts. Each part is its own proof and its own relayed transaction; after each one the note's remainder becomes a new commitment, and the next part waits until the index has it.
Spread over hours. Parts can be scheduled at random moments over one or six hours. The schedule (amounts, addresses, times) is kept in this browser only, and it runs from the open tab: close it and the remaining parts wait until you come back. No secret is stored with it; proofs are built from your phrase when each part is due.
New wallet in one click. The app can make a fresh address in your browser and show its private key once. It is stored nowhere, so the app asks you to copy or download the key before anything is sent to it.
Risks
- Not audited. The circuits and pool are 0xbow's; the entrypoint changes are ours.
- The approved set is run by us. We can delay or refuse approval; you can always ragequit.
- Elysium is a new chain. RPCs and relays can be slow or down.
- Losing the recovery phrase loses the notes.