How Lacuna works
Lacuna 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.
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.