System Architecture
ShieldFlow is built as a modular system with five core components: smart contracts, zero-knowledge circuits, a TypeScript SDK, an ASP (Association Set Provider) service, and a relayer service. Each component is independently deployable and communicates through well-defined interfaces.
System Diagram
Core Components
Smart Contracts
Solidity 0.8.28, Foundry
Entrypoint, PrivacyPool, and ZK Verifier contracts form the on-chain core. The Entrypoint acts as a single gateway for deposits and withdrawals, routing calls to the correct pool. All contracts use UUPS upgradeable proxies with OpenZeppelin AccessControl for role-based permissions.
ZK Circuits
Circom, Groth16
Two core circuits: the withdrawal proof circuit (proves commitment membership and secret knowledge) and the commitment proof circuit (proves correct commitment construction). Proofs are generated client-side using snarkjs with pre-compiled WASM and zkey files.
TypeScript SDK
TypeScript, snarkjs, viem
Client library that handles deposits, withdrawals, and proof generation. Manages secret derivation, Merkle tree reconstruction, and transaction assembly. Supports Node.js, browser environments, and ESM imports.
ASP Service
Node.js, Express
Monitors deposit events from PrivacyPool contracts, runs compliance checks via Nominis deep wallet screening, maintains the ASP Merkle tree of approved deposits, and posts updated ASP roots on-chain via the Entrypoint.
Relayer Service
Express.js
Accepts withdrawal proof submissions from users, quotes relay fees based on current gas prices, and submits withdrawal transactions on behalf of users. This allows recipients to receive funds without needing ETH for gas.
Security Model
The smart contract layer employs multiple defense-in-depth strategies to protect user funds and protocol integrity:
ReentrancyGuard
All state-mutating external functions use OpenZeppelin ReentrancyGuard to prevent reentrancy attacks.
Checks-Effects-Interactions
Contract logic follows the CEI pattern: validate inputs, update state, then perform external calls.
SafeERC20
All ERC-20 interactions use OpenZeppelin SafeERC20 wrappers to handle non-standard token implementations.
UUPS Upgradeable
Contracts are upgradeable via the UUPS proxy pattern with access-controlled upgrade authorization.
Nullifier Tracking
Every withdrawal records a nullifier hash on-chain. Attempting to reuse a nullifier reverts the transaction, preventing double-spend attacks.
Open Source
