[How Privacy Boost Works #2]: Forced Withdrawal: Your Assets Stay Yours
![[How Privacy Boost Works #2]: Forced Withdrawal: Your Assets Stay Yours](/_next/image?url=%2Fblog-forced-withdrawal.png&w=3840&q=75&dpl=dpl_5LByUYouC2h7ySNrHFqSEHJfBaJu)
There is one question users rarely stop to ask about a blockchain protocol.
On the day every server running this protocol goes offline, who gives me my money back?
Privacy Boost's answer is: you do. The mechanism that makes that answer possible is the subject of this post: forced withdrawal, an escape hatch that lets users withdraw their assets using nothing but their own keys and the data left on the blockchain, even if the entire offchain infrastructure disappears. In this post we look at why this feature is necessary, how it is designed, and what sets it apart from other designs.
A system without an escape hatch is a custodial service
Think about Ethereum L2s. On a typical rollup, everyday transactions are processed by a centralized operator called the sequencer. This allows transactions to be processed quickly and cheaply. But what happens if the sequencer censors a particular user, or stops running altogether?
To address this scenario, some rollups provide a mechanism called forced inclusion. A user can submit a transaction directly to Ethereum L1 without going through the sequencer, and the protocol guarantees that the transaction is reflected on L2 within a fixed window. Withdrawals are likewise handled by verifying proofs on L1, so even if the sequencer vanishes forever, users can still withdraw their assets to L1. Thanks to this escape hatch, the sequencer remains a service provider rather than a custodian, and control over assets remains with the user.
The same principle should apply to every protocol that depends on an offchain operator.
If there is no path to recovering your assets without the operator, the system is a custodial service under a different name.
So how does Privacy Boost uphold this principle?
Privacy Boost and forced withdrawal
Privacy Boost is a privacy protocol built by Sunnyside Labs that enables private onchain activity across ERC-20 transfers and DeFi. It protects user identities, balances, and transaction history while allowing interactions with public protocols. The architecture has two main components.
- Onchain smart contracts: a shielded pool that holds user assets and a registry of user signing keys
- An offchain TEE server: a server that generates proofs on the user's behalf and looks up balances and transaction histories. Because it runs inside isolated hardware known as a TEE (Trusted Execution Environment), even the operator (Sunnyside Labs) cannot see user data.
Inside the shielded pool, assets are held in units called notes. Each note contains a token type, an amount, and an owner. These contents are hidden behind a cryptographic commitment, so outside observers cannot determine them from the public data. Spending a note writes a value called a nullifier to the chain, which acts like a stamp saying "this note has already been spent." Any attempt to spend the same note twice runs into that stamp and is rejected.
The core trust structure is in the following invariant: what the TEE server is responsible for stops at privacy and convenience. The safety of the assets is guaranteed by cryptography and smart contracts. That is why assets remain safe even if the server is hacked or shut down, and why users can always leave through forced withdrawal.
This architecture does, however, hand the escape hatch a problem to solve. In Privacy Boost, balances and transaction history are represented onchain only through encrypted notes, and under normal conditions the TEE server decrypts this data, reconstructs the user's balance, and generates the proofs required for withdrawal. So if the server becomes permanently unavailable, users must be able to do two things without assistance: figure out how much they hold, and produce the proof that the money is theirs. Forced withdrawal is the mechanism that puts both of those capabilities back in the user's hands.
How it differs from a normal withdrawal
Ordinary transfers and withdrawals are handled by the TEE server, which batches requests from many users into a single proof. Forced withdrawal removes the server from that path entirely.

In practice, forced withdrawals differ in three ways.
- The user generates the proof themselves. They generate a ZK proof locally, without relying on the server. It proves "these notes are mine, and I authorized this withdrawal" without revealing any secrets.
- No one's permission is required. Requesting, executing, and cancelling all happen without any operator authorization check. Anyone can submit a request as long as they have a valid proof, and any account can submit the execution transaction.
- The result is always a withdrawal to a public address. A single request can gather up to eight notes of the same token and send their combined amount to a specified address. The proof verifies that the withdrawal amount equals the total value of the notes. If you hold more notes than that, or several different tokens, the withdrawal must be split across multiple requests.
A two-step design: request, wait, execute
A forced withdrawal in Privacy Boost does not finish in a single transaction. You first submit a request together with a proof, which starts a waiting period (roughly 3 days), and only after that can you execute or cancel.

Why is the process split into two steps? Because if a forced withdrawal executed immediately, it would open a window for a DoS attack against normal service.
Because forced withdrawals do not require anyone's permission, an attacker could spend the same notes just before a batch processed by the TEE server is posted onchain, invalidating the entire batch. By repeating this process, the attacker could block transactions from all other users. The waiting period makes forced-withdrawal requests visible before they can be executed, allowing the normal processing path to exclude or otherwise route around the affected notes.
The two-step process creates a period during which the request is pending. During that period, double spending is prevented by checking the notes' nullifiers again at execution time. The proof is verified at request time, but the nullifier is not applied until execution. If the same notes are spent through the normal path during the waiting period, execution is rejected; conversely, if the escape executes first, the normal path is rejected afterward. Either way, each note is spent exactly once.
Can it be stolen or hijacked?
A withdrawal request carries the user's signature, and that signature is bound to the entire content of the withdrawal: the chain ID, the contract address, the notes to be spent, and the recipient address and amount. That makes it impossible to reuse a valid authorization on a different chain or redirect it to a different recipient.
What a forced withdrawal actually looks like
Let's walk through the forced-withdrawal process from the user's perspective. The user needs three things.
-
The user's key bundle.
You need the viewing key used to find and decrypt notes, the auth key that approves the withdrawal, the key used to derive the nullifier, plus your account ID and the address that will receive the funds. The first 3 keys are generated when you create a Privacy Boost account, and are provided to the user for safekeeping.
-
A blockchain connection.
Because the request is submitted onchain, you need an RPC endpoint for the chain you are withdrawing on.
-
The public parameters used to build the proof.
Producing a ZK proof requires the proving key associated with the circuit, which is available from the privacy-boost-ceremony repo.
Once you are set up, a forced withdrawal proceeds as follows.
Step 1: Find your assets in the onchain record. With no help from the server, you scan the events the contract has emitted from the very beginning. You attempt to decrypt the ciphertext attached to each transaction with your viewing key, pick out the ones that belong to you, and reconstruct your local view of the onchain state. You then check that the reconstructed ledger matches the onchain state exactly, and filter out notes that have already been spent.
Step 2: Verify your signing key. You also reconstruct the signing-key registry from onchain events and confirm that your key is registered on chain.
Step 3: Build the proof. You generate a ZK proof on your own machine. The proof guarantees 3 things:
- that these notes really do belong to your registered key,
- that this withdrawal was authorized with that key,
- and that the withdrawal amount is exactly equal to the sum of the notes.
Throughout this process, your secret keys never leave your computer.
Step 4: Submit the request. You send a request transaction to the contract carrying the proof and the withdrawal details. Once the contract verifies the proof and records the request, the waiting period begins.
Step 5: Wait. You wait about 3 days. The request is already recorded onchain, so from here all that has to happen is time passing.
Step 6: Execute. You send the execution transaction, and the contract re-checks that the notes have not been spent in the meantime, records the nullifier, and sends the amount minus fees to the address you specified. With that, the assets leave the shielded pool and land in your wallet.
The only things that appeared anywhere in this process are the user's keys, the blockchain, and the user's computer. Sunnyside Labs' servers are involved at no point.
Comparison with other privacy protocols: who gives you your money back on the worst day?
Is this kind of escape path a standard feature of privacy protocols? Ask the same question of another privacy design, and the difference becomes clear.
Another prominent design in onchain privacy protocols is Zama, which uses fully homomorphic encryption (FHE) to store balances in encrypted form and perform computations without decrypting them.
To recover the underlying tokens from a Zama confidential token, you first burn the encrypted token, then wait for the decryption nodes known as the KMS to decrypt the amount and sign off on it, which on Ethereum mainnet requires signatures from 7 out of 13 nodes. As of July 2026, there is no way to complete the withdrawal without obtaining those signatures. In the extreme case where the decryption quorum stops for good, the underlying tokens remain locked even though the confidential tokens have already been burned. That is because the design burns the confidential tokens before the decryption quorum authorizes release of the underlying assets. The withdrawal path therefore remains dependent on infrastructure that can halt or block completion.
Privacy Boost, by contrast, lets users initiate recovery at any time using nothing but a ZK proof and contract interaction, independent of any server, and this property is a core design requirement.
Viewed through the question posed at the beginning of this post, the distinction reduces to a single number. Count how many independent parties must cooperate for a withdrawal to complete; in the Zama design described above, the number is 7 of 13 KMS nodes. In Privacy Boost, it is zero.
Conclusion: the scope of self-custody
Privacy Boost users can recover their assets even if the entire offchain infrastructure becomes permanently unavailable, under the following conditions:
- they still hold their keys,
- they can send a transaction to the chain, and
- they can wait out the roughly 3-day waiting period.
Proofs are generated on the user's own computer, and no one's permission is required. The TEE server provides privacy and performance, but the control of the assets is enforced by the user's keys and the smart contracts.
As with forced inclusion on L2s, an escape hatch is one of those things that should never need to be used under normal circumstances. Yet its existence fundamentally changes the system's guarantees. As long as the escape hatch is verifiably open, control over assets stays with the user no matter what happens to the operator. That is why we designed forced withdrawal as a core component of Privacy Boost's self-custody model.
For those who want to dig deeper: the ZK proof circuits for forced withdrawal can be found in the privacy-boost-protocol repo.
See Privacy Boost in action
Explore the privacy infrastructure behind confidential onchain finance.
Read next

Friends Is Live on Startale App: Private Payments Powered by Privacy Boost
Friends is a Mini App on Startale App that lets you send money onchain without putting your payment history on display. It's powered by Privacy Boost, bringing shielded transfers to every user on Soneium.

How Privacy Boost Works #01: ZK proofs keep the money safe. TEEs make it fast.
Most onchain privacy projects pick a side: trustless-but-slow ZK, or fast-but-fragile trusted hardware. Privacy Boost splits the guarantees by how badly their failure hurts, so a hardware break can never reach your funds.