Overview
The Orchestrator is the intent coordination hub of the zkp2p protocol. It manages the complete lifecycle of intents from signal to fulfillment, coordinates with the Escrow for liquidity management, and integrates with payment verifiers to validate off-chain payments.The Orchestrator acts as the “order book” for P2P fiat-to-crypto trades, matching buyers (who signal intents) with sellers (who provide liquidity via deposits).
Key Responsibilities
- Intent Signaling: Capture buyer commitment to pay off-chain for on-chain assets
- Intent Verification: Validate gating service signatures and deposit parameters
- Fulfillment Coordination: Verify payment proofs and release funds to buyers
- Fee Management: Collect protocol fees and referrer fees
- Hook Execution: Execute post-intent actions (bridging, swapping, etc.)
Core Data Structures
Intent Struct
Every intent signaled on the Orchestrator is represented by this comprehensive struct (fromcontracts/interfaces/IOrchestrator.sol:12):
Intent Immutability: Once signaled, intent parameters are frozen on-chain. This gives strong guarantees to both buyer (locked exchange rate) and seller (payment details).
SignalIntentParams
When signaling an intent, users provide these parameters (fromcontracts/interfaces/IOrchestrator.sol:29):
Intent Lifecycle
Signaling Intents
Buyers signal intent to purchase on-chain assets by paying off-chain (fromcontracts/Orchestrator.sol:102):
Signal Validation
The_validateSignalIntent() function performs extensive checks (from contracts/Orchestrator.sol:390):
- Multiple Intent Check: Verify user can have multiple active intents (whitelisted relayer or
allowMultipleIntents == true) - Address Validation: Ensure
toaddress is not zero - Fee Validation:
- Referrer fee must be ≤ 50% (
MAX_REFERRER_FEE) - If no referrer, fee must be 0
- Referrer fee must be ≤ 50% (
- Post-Intent Hook Validation: If set, must be whitelisted in
postIntentHookRegistry - Escrow Validation: Must be whitelisted or registry accepts all escrows
- Payment Method Validation: Must exist in
paymentVerifierRegistryand be active on the deposit - Currency Validation: Must be supported by the payment method with non-zero min conversion rate
- Conversion Rate Validation: Must meet or exceed deposit’s min conversion rate
- Gating Service Signature: If deposit has a gating service, validate EIP-712 signature
Intent Hash Calculation
Intent hashes are deterministically generated (fromcontracts/Orchestrator.sol:444):
What Happens on Signal
- Validate all parameters via
_validateSignalIntent() - Generate unique
intentHashvia_calculateIntentHash() - Fetch deposit and payment method data from Escrow
- Store snapshot of deposit’s min intent amount (
intentMinAtSignal) - Create and store the full Intent struct
- Add intent hash to
accountIntents[msg.sender] - Increment
intentCounter - Emit
IntentSignaledevent - Call
IEscrow(escrow).lockFunds(depositId, intentHash, amount)
Cancelling Intents
Intent owners can cancel their own intents before fulfillment (fromcontracts/Orchestrator.sol:161):
- Verify intent exists (
timestamp != 0) - Verify caller is intent owner
- Prune intent (delete from storage, remove from
accountIntents) - Call
IEscrow(escrow).unlockFunds(depositId, intentHash)to release liquidity - Emit
IntentPrunedevent
Fulfilling Intents
Anyone can submit a fulfillment with valid payment proof (fromcontracts/Orchestrator.sol:184):
FulfillIntentParams
Fulfillment Flow
Payment Verification
The Orchestrator calls the payment verifier registered for the intent’s payment method (fromcontracts/Orchestrator.sol:194):
Min-At-Signal Enforcement
To prevent sub-minimum partial fulfillments, the Orchestrator enforces the deposit’s min intent amount at the time of signal (fromcontracts/Orchestrator.sol:205):
This prevents a depositor from raising their min intent amount after an intent is signaled, then getting a partial fulfillment below the original minimum.
Fee Management
Protocol Fee
The protocol charges a fee on the release amount (fromcontracts/Orchestrator.sol:485):
- Max protocol fee: 10% (
MAX_PROTOCOL_FEE = 1e17at line 41) - Fee is in
preciseUnits(1e16 = 1%)
Referrer Fee
Referrers can earn a fee for bringing users to the protocol (fromcontracts/Orchestrator.sol:490):
- Max referrer fee: 50% (
MAX_REFERRER_FEE = 5e17at line 40) - Paid from the release amount
Net Amount Calculation
netAmount is what the buyer receives (or is passed to the post-intent hook).
Post-Intent Hooks
Post-intent hooks enable custom actions after fulfillment, such as:- Bridging tokens to another chain (Across, Stargate)
- Swapping tokens (Uniswap, 1inch)
- Depositing to yield protocols
- Multi-step DeFi operations
Hook Execution
If an intent has apostIntentHook set (from contracts/Orchestrator.sol:534):
Manual Release by Depositor
Depositors can manually release funds to the buyer in case of disputes or off-chain arrangements (fromcontracts/Orchestrator.sol:232):
- Verify caller is the depositor for the intent’s deposit
- Prune intent from storage
- Call
unlockAndTransferFunds()with full intent amount (no partial) - Calculate and transfer fees
- Transfer net amount to
intent.to - Emit
IntentFulfilled(intentHash, to, netAmount, isManualRelease: true)
Manual releases still charge protocol and referrer fees.
Intent Pruning
Expired intents are pruned by the Escrow contract, which calls back to the Orchestrator (fromcontracts/Orchestrator.sol:257):
Gating Service Signatures
Deposits can require buyers to obtain a signature from a gating service (KYC provider, allowlist manager, etc.) before signaling intents.Signature Validation
The signature covers (fromcontracts/Orchestrator.sol:578):
State Variables
| Variable | Description | Location |
|---|---|---|
chainId | Immutable chain identifier | Line 45 |
intents | Mapping of intentHash to Intent struct | Line 47 |
accountIntents | Mapping of account to array of intent hashes | Line 48 |
intentMinAtSignal | Snapshot of min intent amount at signal time | Line 52 |
escrowRegistry | Registry of whitelisted escrows | Line 55 |
paymentVerifierRegistry | Registry of payment verifiers | Line 56 |
postIntentHookRegistry | Registry of whitelisted hooks | Line 57 |
relayerRegistry | Registry of whitelisted relayers | Line 58 |
protocolFee | Protocol fee in preciseUnits (1e16 = 1%) | Line 61 |
protocolFeeRecipient | Recipient of protocol fees | Line 62 |
allowMultipleIntents | Whether all users can have multiple intents | Line 64 |
intentCounter | Incrementing nonce for intent hash generation | Line 66 |
Access Control
Owner (Governance)
- Set escrow registry
- Set protocol fee (max 10%)
- Set protocol fee recipient
- Set allow multiple intents
- Set post-intent hook registry
- Set relayer registry
- Pause/unpause orchestrator
Users
- Signal intents (with valid gating signature if required)
- Cancel own intents
- Fulfill any intent (with valid payment proof)
Depositors
- Manually release funds to buyers
Escrows
- Prune expired intents
Key Events
Security Features
Reentrancy Protection
fulfillIntent and releaseFundsToPayer use nonReentrant guardIntent Immutability
Once signaled, intent parameters cannot be changed
Min-At-Signal
Prevents depositors from raising minimums after intent signal
Hook Safety
Post-intent hooks must consume exact allowance or revert
Related Contracts
- Escrow - Manages deposits and locks liquidity
- Payment Verification - Verifies off-chain payment proofs
- Intent Lifecycle - Complete intent flow diagram
- Registry System - Whitelisting and authorization