Documentation Index
Fetch the complete documentation index at: https://mintlify.com/zkp2p/zkp2p-contracts/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Escrow contract is the liquidity hub of the zkp2p protocol. It holds depositor funds, manages deposit configurations, and coordinates with the Orchestrator to lock/unlock liquidity as intents progress through their lifecycle.Each deposit can support multiple payment methods (Venmo, PayPal, Wise, etc.), each with its own verification requirements and supported currencies.
Key Responsibilities
- Deposit Management: Create and manage deposits with flexible intent ranges
- Liquidity Locking: Lock funds when intents are signaled, release when fulfilled or cancelled
- Payment Method Configuration: Support multiple payment services with independent verification data
- Intent Expiry: Track and reclaim liquidity from expired intents
- Dust Collection: Automatically close small deposits and sweep remainder to protocol
Core Data Structures
Deposit Struct
Every deposit created on the Escrow is represented by this struct (fromcontracts/interfaces/IEscrow.sol:24):
Delegate: An optional address that can manage deposit parameters (conversion rates, intent ranges, payment methods) on behalf of the depositor.
Intent Struct
Each intent locked against a deposit is tracked with this struct (fromcontracts/interfaces/IEscrow.sol:12):
Payment Method Data
Deposits can support multiple payment methods. Each has its own configuration (fromcontracts/interfaces/IEscrow.sol:44):
Deposit Lifecycle
Creating a Deposit
Depositors create liquidity pools by callingcreateDeposit() with comprehensive configuration (from contracts/Escrow.sol:139):
token: ERC20 token addressamount: Initial deposit amountintentAmountRange: Min/max amounts per intentpaymentMethods: Array of supported payment method hashespaymentMethodData: Verification data for each payment methodcurrencies: Supported currencies and min conversion rates for each methoddelegate: Optional management delegateintentGuardian: Optional address that can extend intent expiryretainOnEmpty: Whether to keep deposit config when balance reaches zero
Example: Multi-Currency Deposit
A depositor might configure:- Venmo: USD only, min rate 1.0
- Wise: USD, EUR, GBP with different conversion rates
- PayPal: USD, EUR
payeeDetails (the depositor’s account ID for that service).
Liquidity Management
Adding Funds
Anyone can add funds to an existing deposit (fromcontracts/Escrow.sol:187):
remainingDeposits, making them immediately available for new intents.
Removing Funds
Only the depositor can remove funds (fromcontracts/Escrow.sol:213):
Intent Amount Range
TheintentAmountRange (min/max) controls the size of intents accepted:
setIntentRange() (from contracts/Escrow.sol:352).
Intent Lifecycle on Escrow
Locking Funds
When an intent is signaled on the Orchestrator, it callslockFunds() (from contracts/Escrow.sol:557):
- Validates deposit state (
acceptingIntents == true) - Checks amount is within
intentAmountRange - Prunes expired intents if needed to free liquidity
- Moves amount from
remainingDepositstooutstandingIntentAmount - Stores the intent with expiry time (
block.timestamp + intentExpirationPeriod) - Emits
FundsLockedevent
Unlocking Funds (Cancel)
When an intent is cancelled, the Orchestrator callsunlockFunds() (from contracts/Escrow.sol:620):
remainingDeposits.
Unlocking & Transferring Funds (Fulfill)
When an intent is fulfilled, the Orchestrator callsunlockAndTransferFunds() (from contracts/Escrow.sol:651):
Partial Fulfillment: The
_transferAmount can be less than the original intent amount. The difference is returned to remainingDeposits.Intent Expiration
Intents have a configurable expiration period (default 5 days max perMAX_TOTAL_INTENT_EXPIRATION_PERIOD at line 42).
Automatic Expiry Pruning
Expired intents are automatically pruned when:lockFunds()needs more liquidityremoveFunds()is calledwithdrawDeposit()is called- Anyone calls
pruneExpiredIntents()(fromcontracts/Escrow.sol:533)
Extending Expiry
TheintentGuardian (if set) can extend intent expiry via extendIntentExpiry() (from contracts/Escrow.sol:702):
Delegate System
Depositors can assign a delegate to manage deposit parameters without transferring ownership. Delegate can:- Update conversion rates (
setCurrencyMinRate) - Update intent ranges (
setIntentRange) - Add/remove payment methods and currencies
- Toggle accepting intents state
- Set retention behavior
- Withdraw funds (only depositor)
- Change the delegate itself (only depositor)
Dust Collection
When a deposit’sremainingDeposits falls below dustThreshold (max 1 USDC, see line 41) and has no outstanding intents:
- Deposit is automatically closed
- Remaining balance is swept to
dustRecipient - All payment method and currency data is deleted
Set
retainOnEmpty = true to prevent auto-closure and keep the deposit configuration for future reuse.Payment Method & Currency Management
Adding Payment Methods
Depositors can add new payment methods after creation (fromcontracts/Escrow.sol:381):
Toggling Payment Methods
Payment methods can be deactivated without deletion (fromcontracts/Escrow.sol:404):
Managing Currencies
Each payment method can support multiple currencies with independent min conversion rates:addCurrencies(): Add new currencies to a payment method (line 430)setCurrencyMinRate(): Update min conversion rate (line 324)deactivateCurrency(): Set conversion rate to 0 (line 458)
State Variables
| Variable | Description | Location |
|---|---|---|
orchestrator | Orchestrator contract reference | Line 47 |
paymentVerifierRegistry | Payment verifier registry | Line 48 |
chainId | Immutable chain identifier | Line 49 |
depositCounter | Incrementing deposit ID counter | Line 78 |
dustRecipient | Receives dust from closed deposits | Line 80 |
dustThreshold | Threshold below which deposits are dust | Line 81 |
maxIntentsPerDeposit | Max concurrent intents (prevents DOS) | Line 82 |
intentExpirationPeriod | How long intents remain valid | Line 83 |
Access Control
Owner (Governance)
- Set orchestrator address
- Update payment verifier registry
- Configure dust parameters
- Set max intents per deposit
- Set intent expiration period
- Pause/unpause deposit operations
Depositor
- Create deposits
- Withdraw deposits
- Remove funds
- Set delegate
- Remove delegate
Depositor OR Delegate
- Update conversion rates
- Update intent ranges
- Add/remove payment methods
- Add/remove currencies
- Toggle accepting intents state
- Set retention behavior
Orchestrator Only
- Lock funds
- Unlock funds
- Unlock and transfer funds
Intent Guardian Only
- Extend intent expiry
Key Events
Security Features
Reentrancy Protection
All state-changing functions use
nonReentrant modifier from OpenZeppelinPausability
Owner can pause deposit creation/modification while leaving withdrawals active
Intent Limits
maxIntentsPerDeposit prevents gas DOS attacks on withdrawalExpiry Enforcement
Intents automatically expire after
intentExpirationPeriodRelated Contracts
- Orchestrator - Signals intents and coordinates fulfillment
- Payment Verification - Verifies off-chain payment proofs
- Registry System - Payment verifier and currency validation