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

All components are open source under the Apache-2.0 license. You can audit the code, run your own ASP, or deploy a custom relayer. See the GitHub repository for source code and contribution guidelines.