Contract Spec
Overview
The zERC20 contract system consists of:
zERC20: Privacy-enabled ERC-20 token
Verifier: Proof verification and teleport execution
Hub: Cross-chain root aggregation
LiquidityManager: Liquidity entry/exit policy
Adaptor: Cross-chain exit via Stargate
Fee Manager (off-chain): Dynamic liquidity target adjustment
zERC20
Location: contracts/src/zERC20.sol
An upgradeable ERC-20 that tracks all transfers in a hash chain for ZKP verification.
Key Features
Emits
IndexedTransfer(index, from, to, value)for every transferMaintains truncated SHA-256 hash chain:
hashChain = SHA256(hashChain || from || to || value)[0:248]Exposes
teleportfor Verifier-initiated mints
Functions
Events
Constraints
All transfer values must be ≤ 2^248 - 1 (fits in BN254 scalar field)
Reverts with
ValueTooLargeif exceeded
Verifier
Location: contracts/src/Verifier.sol
LayerZero OApp that verifies ZK proofs and manages teleports.
Key Features
Records hash chain checkpoints for proof anchoring
Verifies Nova proofs for transfer root transitions
Verifies Nova/Groth16 proofs for withdrawals
Relays roots to Hub via LayerZero
Functions
State
GeneralRecipient
Binds withdrawals to a specific destination:
Emergency Handling
If a proof inconsistency is detected (mismatched roots for same index), the contract pauses automatically. Owner must rotate verifiers and call deactivateEmergency to resume.
Hub
Location: contracts/src/Hub.sol
Central aggregator for cross-chain transfer roots.
Key Features
Receives roots from all chain Verifiers via LayerZero
Aggregates into Poseidon tree (max 64 leaves)
Broadcasts global root to all Verifiers
Functions
Events
LiquidityManager
Location: contracts/src/liquidity/LiquidityManager.sol
Manages liquidity entry/exit with incentive curves.
Key Features
Wraps underlying tokens into zERC20
Unwraps zERC20 back to underlying
Applies incentive fees based on liquidity target
Functions
Incentive Curve
Linear incentive density: density(x) = k * (1 - x / T) for x < T
Below target: wraps earn rewards, unwraps pay fees
Above target: no rewards or fees
Fees accumulate in
feeSurplusfor future incentives
Fee Manager
Location: fee-manager/ (off-chain service)
Periodic maintenance worker that dynamically adjusts targetLiquidity on all LiquidityManager contracts across chains.
Purpose
The Fee Manager ensures balanced liquidity distribution across all chains by automatically updating fee parameters:
This eliminates manual parameter tuning and automatically adjusts incentives as liquidity flows between chains.
How It Works
Fetch Balances: Query underlying token balance (
balance - feeSurplus) from each LiquidityManagerCalculate Target: Compute
targetLiquidity = total / chain_countUpdate Parameters: Call
setFeeParams({ targetLiquidity, k })on each LiquidityManagerRepeat: Sleep for configured interval (default: 1 hour)
FeeParams Structure
targetLiquidity: The liquidity level at which wrap rewards and unwrap fees approach zerok: Controls incentive curve steepness (higher = stronger incentives when liquidity deviates from target)
Configuration
FEE_MANAGER_PRIVATE_KEY
—
Private key with FEE_MANAGER_ROLE on each LiquidityManager
FEE_MANAGER_INTERVAL_SECS
3600
Interval between updates (seconds)
FEE_MANAGER_K_BPS
1000
Incentive coefficient k in basis points (1000 = 10%)
Native Token Support
The Fee Manager automatically detects whether a LiquidityManager uses native ETH or ERC20:
Native ETH: Detected via ERC-7528 sentinel address
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeEERC20: Balance fetched via
balanceOf()on underlying token
Permissions
The Fee Manager requires FEE_MANAGER_ROLE on each LiquidityManager:
Key Flows
1. Transfer Root Proving
2. Local Teleport
3. Global Teleport (Cross-chain)
Security Notes
Value range: All values checked against 248-bit limit
Double-spend prevention:
totalTeleportedtracks cumulative mints per recipientLayerZero security: Only accepts messages from known endpoints
Upgrade safety: UUPS pattern with owner-only upgrade
Last updated