Smart Contracts
ShieldFlow's smart contracts implement the Privacy Pool protocol with UUPS upgradeability, AccessControl, and Groth16 ZK proof verification.
Deployed Addresses
0xCFFf9d27e6A23C94447cEA72DDf6B0C3807F5fE50xd600BFEdF8E6cEF5c144997BF29137853618D9f30x89234FE6d2722fAD5Fde884C618C05EE5568B84e0x14df42045c3c128f0dbc7c0ae8a6eee19d678acd0x213fe14bc0a6c6e1ff909219e2f0dd83c4012b8fContract Architecture
Entrypoint (UUPS Upgradeable)
Main entry point for deposits and relayed withdrawals. Acts as the gateway to all pool interactions, routing calls to the appropriate pool contracts. Manages protocol-level configuration including fee rates and pool registration.
OWNER_ROLE, ASP_POSTMANdeposit(), relay(), updateRoot(), registerPool()PrivacyPool (Abstract)
Base contract implementing core deposit and withdrawal logic. Maintains the state Merkle tree (LeanIMT), tracks spent nullifiers to prevent double-spending, and stores a 64-entry circular root history buffer for proof verification against recent tree states.
PrivacyPoolSimple
Concrete implementation for native ETH deposits and withdrawals. Extends PrivacyPool with ETH-specific transfer logic using low-level calls for gas efficiency.
PrivacyPoolComplex
Concrete implementation for ERC-20 token deposits and withdrawals. Extends PrivacyPool with SafeERC20 for secure token transfers, supporting any standard ERC-20 token.
Verifier Contracts
Auto-generated Groth16 proof verification contracts for the withdrawal and commitment circuits. These verify zero-knowledge proofs on-chain to validate withdrawal eligibility without revealing deposit details.
Key Functions
The primary contract interfaces for deposits, withdrawals, and emergency exits:
// Deposit ETH
function deposit(uint256 _precommitment) external payable;
// Deposit ERC20
function deposit(IERC20 _asset, uint256 _value, uint256 _precommitment) external;
// Relay withdrawal (called by relayer)
function relay(
IPrivacyPool.Withdrawal memory _withdrawal,
ProofLib.WithdrawProof memory _proof,
uint256 _poolScope
) external;
// Emergency exit (called by original depositor)
function ragequit(ProofLib.CommitmentProof memory _proof) external;Security Features
UUPS Upgrade Pattern
Controlled upgradeability with authorization checks. Only the contract owner can authorize upgrades, and the implementation logic lives in the proxy itself to prevent unauthorized upgrades.
AccessControl Roles
Fine-grained permission system using OpenZeppelin AccessControl. OWNER_ROLE manages protocol configuration, ASP_POSTMAN updates association set roots.
ReentrancyGuard
Prevents reentrant calls to state-modifying functions. Applied to all deposit, withdrawal, and ragequit operations.
Checks-Effects-Interactions
All state changes (effects) are performed before external calls (interactions). Nullifiers are marked as spent before transferring funds.
SafeERC20
Uses OpenZeppelin SafeERC20 for all ERC-20 token interactions, protecting against non-standard token implementations that don't return boolean values.
Nullifier Tracking
Every withdrawal produces a unique nullifier that is stored on-chain. Attempting to reuse a nullifier reverts the transaction, preventing double-spending.
Root History Buffer (64 entries)
The contract maintains a circular buffer of the last 64 Merkle roots. Withdrawal proofs can reference any recent root, allowing transactions to succeed even when new deposits update the tree between proof generation and on-chain submission.
Solidity Version
