Skip to main content

Intent

Keep amounts and positions private on Ethereum L1 via a shielded pool using commitments and nullifiers. Each transfer verifies a zero-knowledge proof, with atomic delivery-versus-payment (DvP) coupling via ERC-7573.
Best for: Low trade frequency (< 100 trades/month) where L2 is not available or desirable.
Avoid when: Active secondary markets or frequent settlements require lower per-trade costs. Consider L2 encrypted audit instead.

Ingredients

Standards

  • ERC-3643: Compliant security token standard with identity and transfer rules
  • ERC-7573: Atomic DvP settlement standard
  • ZK proof system: Commitments and nullifiers (Groth16, Plonk, or similar)

Infrastructure

  • L1 contracts: Shielded pool contract managing commitments and nullifiers
  • Prover infrastructure: Off-chain proof generation service
  • Key management: Secure storage for proving and viewing keys

Off-chain Components

  • Key management system: Generate and store user proving keys
  • RFQ workflow: Request-for-quote matching engine
  • Proof generation service: Compute ZK proofs for transfers

Protocol

1

Deposit into Shielded Pool

User deposits tokens into the shielded pool contract. The contract issues private notes (commitments) representing the deposit amount and ownership.
function deposit(uint256 amount, bytes32 commitment) external {
  // Transfer tokens from user to pool
  token.transferFrom(msg.sender, address(this), amount);
  // Store commitment
  commitments[commitment] = true;
  emit Deposit(commitment);
}
2

Private Transfers with ZK Proofs

To transfer, user generates a ZK proof demonstrating:
  • Ownership of input notes (via nullifiers)
  • Output commitments sum correctly
  • No double-spending (nullifier not previously used)
The proof reveals no amounts or identities. Only nullifiers and new commitments are published on-chain.
3

Atomic DvP Settlement

Couple the private asset transfer to payment (e.g., EURC stablecoin) using ERC-7573. Both legs settle atomically or both revert.
function atomicDvP(
  bytes32 assetNullifier,
  bytes32 assetCommitment,
  bytes32 cashOutcomeKey,
  bytes calldata proof
) external {
  require(verifyProof(proof, assetNullifier, assetCommitment));
  require(!nullifiers[assetNullifier], "Double spend");
  
  // Mark nullifier as spent
  nullifiers[assetNullifier] = true;
  commitments[assetCommitment] = true;
  
  // Execute cash leg via ERC-7573
  cashContract.settleConditional(cashOutcomeKey);
}

Guarantees

Amounts and positions remain confidential on Ethereum L1. Public observers see only:
  • Nullifiers (one-time identifiers preventing double-spending)
  • Commitments (cryptographic hashes of new notes)
  • Proof verification success/failure
No transaction amounts, sender identities, or recipient identities are revealed.
ERC-7573 ensures delivery-versus-payment atomicity. The asset transfer and payment either both succeed or both fail. No partial settlement is possible.
ERC-3643 compliance checks integrate with the shielded pool. Identity verification and transfer restrictions apply before deposit and after withdrawal.

Trade-offs

Costly per-transfer proofs: Each transaction requires generating and verifying a ZK proof on L1. Gas costs are significantly higher than transparent transfers (typically 500k-1M gas per proof).
  • Mempool privacy: Without additional privacy routing, transactions are visible in the public mempool before inclusion. Consider using private RPCs or MEV protection services.
  • Operational complexity: Running prover infrastructure requires specialized hardware and expertise. Proof generation may take seconds to minutes depending on circuit complexity.
  • Withdrawal privacy: Withdrawals from the shielded pool may reveal amounts and recipients unless withdrawn to another shielded address.

Example Workflow

Scenario: Private Bond Settlement

1

Setup Phase

Bank A and Bank B each deposit tokenized bonds and cash into respective shielded pools. They receive private notes representing their balances.
2

Trade Execution

Bank A initiates sale of €5M bond to Bank B:
  • Bank A generates ZK proof consuming its bond note and creating output commitment for Bank B
  • Bank B generates ZK proof consuming its cash note and creating output commitment for Bank A
3

Atomic Settlement

Both proofs are submitted to the DvP contract. The contract verifies both proofs and settles atomically:
  • Bond nullifier marked as spent, Bank B’s bond commitment recorded
  • Cash nullifier marked as spent, Bank A’s cash commitment recorded
4

Regulatory Disclosure

BaFin requests details on trade N. Bank A provides a scoped viewing key or ZK proof demonstrating:
  • The trade occurred
  • The amount was within regulatory limits
  • Counterparty identity (via ERC-3643 attestation)
No other trades or balances are revealed.
With 50 trades/month, gas costs are manageable. At 500k gas per trade and 20 gwei gas price, monthly costs are approximately 0.5 ETH (~1,000at1,000 at 2,000/ETH).

Implementation Considerations

Choosing a ZK System

SystemProof SizeVerification CostGeneration TimeBest For
Groth16~200 bytes~250k gas1-5 secondsSimple transfers
Plonk~500 bytes~400k gas2-10 secondsFlexible circuits
STARKs~100 KB~1M gas10-30 secondsComplex logic

Prover Infrastructure

Use a third-party prover service (e.g., zkProof.io, Gevulot). Trade-off: trust in service availability and data handling.

Security Considerations

Trusted setup: Groth16 and some other ZK systems require a trusted setup ceremony. Ensure the ceremony is conducted securely with multiple independent participants.
  • Key custody: Proving keys must be kept secret. Compromise reveals transaction details.
  • Proof malleability: Ensure nullifiers are unique and cannot be replayed across different contexts.
  • Circuit audits: ZK circuits must be audited by cryptography experts before production use.

See Also

L2 Encrypted Off-chain Audit

Lower-cost alternative for higher transaction volumes

Regulatory Disclosure

Selective disclosure mechanisms for compliance

Atomic DvP via ERC-7573

Learn more about the DvP settlement standard

Railgun Privacy System

Production shielded pool implementation

External References

Build docs developers (and LLMs) love