Deposit Flow

Deposits are public on-chain transactions that create cryptographic commitments in the Privacy Pool. Each deposit locks funds into the pool and produces a unique commitment that can only be spent by the depositor using their recovery phrase.

Sequence Overview

Step-by-Step Walkthrough

1

Connect Wallet

User connects their wallet via RainbowKit/Wagmi. The SDK detects the connected chain and configures the appropriate pool contracts.

2

Select Asset & Amount

Choose ETH or a supported ERC-20 token and enter the deposit amount. The protocol enforces a minimum deposit to prevent dust attacks and ensure meaningful privacy set contributions.

3

Generate Precommitment

The SDK derives a secret precommitment hash from the user's wallet signature. This binds the deposit to the user's identity without revealing it on-chain.

4

Submit Transaction

Calls Entrypoint.deposit(asset, value, precommitment). For ERC-20 tokens, an approval transaction is required first. The Entrypoint contract acts as the single entry point for all pool interactions.

5

Fee Deduction

The protocol deducts a small vetting fee (baseFeeBPS) from the deposit amount. The remainder is forwarded to the Privacy Pool contract.

6

Commitment Creation

The pool generates a unique label from the pool scope and an incrementing nonce, then computes: commitment = PoseidonT4(value, label, precommitmentHash). This commitment is inserted as a leaf into the state Merkle tree.

7

Save Recovery Phrase

The SDK generates a 12-word BIP-39 mnemonic derived from the deposit secrets. This mnemonic is the ONLY way to recover and withdraw the deposited funds later.

Protect Your Recovery Phrase

Never share your recovery phrase. Anyone with these 12 words can withdraw your funds. Store it offline in a secure location. The protocol has no backdoor or admin recovery mechanism.

Commitment Construction

Each deposit produces a cryptographic commitment that is stored as a leaf in the state Merkle tree. The commitment is computed using the Poseidon hash function with four inputs:

commitment = PoseidonT4(value, label, precommitmentHash)

value

The deposited amount after fee deduction. Denominated in the asset's smallest unit (e.g., wei for ETH).

label

A unique identifier derived from the pool scope and a monotonically increasing nonce: label = H(scope, nonce). The scope identifies the specific Privacy Pool instance, and the nonce prevents label collisions across deposits.

precommitmentHash

A hash derived from the user's secret seed. This binds the commitment to the depositor without exposing their identity on-chain. Only the holder of the original secret (encoded in the 12-word mnemonic) can later produce a valid zero-knowledge proof to spend this commitment.

Why Poseidon?

PoseidonT4 is a ZK-friendly hash function designed for efficient computation inside arithmetic circuits. It enables the withdrawal circuit to verify commitment membership without prohibitive proving costs.

SDK Integration

The ShieldFlow SDK abstracts the precommitment generation, transaction construction, and mnemonic derivation into a single call:

deposit.ts
import { ShieldFlow } from '@shieldflow/sdk';

const sf = new ShieldFlow({ chainId: 1, rpcUrl: process.env.RPC_URL });

const deposit = await sf.deposit({
  asset: 'ETH',
  amount: '1.0',
});

// CRITICAL: Save this mnemonic securely
console.log('Recovery phrase:', deposit.mnemonic);
console.log('Commitment:', deposit.commitment);

ERC-20 Deposits

For ERC-20 tokens, the SDK automatically handles the approval transaction before depositing. You can also pass a pre-approved allowance to skip the approval step.