Skip to main content

Withdrawal

Privacy Pools supports two types of withdrawals:

  1. Direct Withdrawals: User directly interacts with pool contract
  2. Relayed Withdrawals: Withdrawal processed through a relayer for additional privacy

Both methods require zero-knowledge proofs to prove commitment ownership and maintain privacy.

Withdrawal Types Comparison

AspectDirect WithdrawalRelayed Withdrawal
Privacy LevelBasicEnhanced (different withdrawal address)
Gas PaymentUser pays directlyRelayer pays, takes fee
Fee StructureNo feesConfigurable relayer fee
ComplexitySimpler flowAdditional fee computation
Front-running ProtectionContext-basedContext-based

Protocol Flow - Direct Withdrawal

Protocol Flow - Relayed Withdrawal

Withdrawal Data Structure

struct Withdrawal {
address processooor; // Direct: recipient, Relayed: Entrypoint
uint256 scope; // Pool identifier
bytes data; // Direct: empty, Relayed: encoded `FeeData`
}

struct FeeData {
address recipient; // Final recipient
address feeRecipient; // Relayer address
uint256 relayFeeBPS; // Fee in basis points
}

Withdrawal Steps

Direct Withdrawal

  1. Proof Generation
    • User constructs withdrawal parameters
    • Generates ZK proof of commitment ownership
    • Computes new commitment for remaining value
  2. Contract Interaction
    • User submits proof to pool contract
    • Pool verifies proof and context
    • Updates state (nullifiers, commitments)
    • Transfers assets to recipient

Relayed Withdrawal

  1. User Steps
    • Construct withdrawal with Entrypoint as processooor
    • Generate ZK proof
    • Submit to relayer off-chain
  2. Relayer Steps
    • Verify proof locally
    • Submit transaction to Entrypoint
    • Pay gas fees
  3. Entrypoint Processing
    • Verify proof and context
    • Process withdrawal through pool
    • Handle fee distribution
    • Transfer assets to recipient

Context Generation

The context signal binds the proof to specific withdrawal parameters:

context = uint256(keccak256(abi.encode(
withdrawal,
pool.SCOPE()
))) % SNARK_SCALAR_FIELD;