Smart Contracts Reference#
All contracts implement ERC-7683 (Open Intents Framework). 0 contract families deployed per chain: InputSettler (origin), OutputSettler (destination), ComplianceRegistry (both).
Deployment. Core (InputSettlerEscrow, InputSettlerCompact, OutputSettlerSimple, HyperlaneOracle) deployed on Optimism + Base (mainnet + Sepolia). Compliance contracts code-complete with 368+ Foundry tests - deployment pending. Testnet-first
Contract Families#
Origin
Input Settlers
Lock taker funds · None → Deposited → Claimed | Refunded
Destination
Output Settlers
Record fills · 4 order types via MandateOutput.context
Per-Chain
ComplianceRegistry
KYC gate on open() · fill() · claim()
Contract Reference#
Input Settlers (Origin Chain)#
Lock the taker's funds and manage the 4-state escrow lifecycle: None → Deposited → Claimed | Refunded.
Escrow State Machine
InputSettlerEscrow Audited#
The standard input-first settler. Taker deposits funds via open(), solver claims via finalise() after oracle attestation.
1// State machine: None → Deposited → Claimed | Refunded2function open(StandardOrder calldata order, bytes calldata signature) external;3function openFor(StandardOrder calldata order, bytes calldata signature, address sponsor) external;4function finalise(StandardOrder calldata order, bytes calldata payload, uint256 filledAmount) external;Lock types supported:
0x00- Permit2 (gasless approval via Uniswap Permit2)0x01- EIP-3009 (gasless transfer viatransferWithAuthorization, USDC/EURC only)
openFor() enables sponsor-based settlement: a third party (e.g., a relayer) can submit the deposit transaction on behalf of the taker, enabling gasless UX.
InputSettlerCompact Audited#
Uses The Compact (ResourceLock) for output-first settlement. The solver fills on the destination chain before the taker's funds are locked - highest capital efficiency.
- Lock type
0xff- ResourceLock (The Compact) - Solver claims via
batchClaim()after oracle attestation - Allocator co-signs to prevent double-spend
- Arbiter verifies fill conditions
ComplianceSettlerEscrow Production#
Extends InputSettlerEscrow with a compliance gate at deposit time. Overrides _validateOpenCompliance() to check depositor compliance via ComplianceRegistry. Does not modify _resolveLock() - the core escrow state machine is unchanged.
1// Reverts if depositor is not compliant2function _validateOpenCompliance(address depositor) internal view override;Settlement Invariants#
- INV-1: Proof-gated release - Escrow funds only release on a valid oracle proof
- INV-2: Timeout refund - Taker can always reclaim funds after
expirestimestamp - INV-3: No double-claim - A claim can only succeed once per order
- INV-4: No double-refund - A refund can only succeed once per order
- INV-5: Refund ignores compliance -
refund()never checks compliance - users can always exit even if their KYC attestation expires after deposit - INV-6: First-to-fill -
fill()is idempotent; subsequent fill attempts for the same output return early without reverting - INV-7: One-time proof - Oracle proof is consumed on use; it cannot be replayed
INV-5 is architecturally critical. The compliance gate is at deposit time (open()), NOT at refund time. This ensures users can always recover their funds regardless of subsequent KYC status changes. Compliance enforcement is an entry gate, not an exit barrier.
Gas Impact of Compliance Gate#
The ComplianceSettlerEscrow adds ~0 gas per open() call - approximately 1.6% overhead on a typical 0 gas order. This is the cost of the on-chain isCompliant() check against the ComplianceRegistry.
The ComplianceOutputSettler overrides _beforeNewFill() to check recipient compliance on the destination chain. Already-filled outputs bypass the compliance check (idempotent).
Solver Selection & Multi-Output Orders#
When an order contains multiple outputs, the solver filling the first output becomes the order owner:
- Once the first output is filled, other solvers cannot fill remaining outputs
- Dutch auctions only apply to the first output
- All outputs may be filled atomically but in any order
For multi-output orders, the first output should always be the most valuable to mitigate DoS risk - a solver filling only the first output and abandoning the rest would block the entire order.
Order Purchasing (Underwriting)#
Solvers can purchase orders from other solvers to speed up capital rotation. This also enables a better user experience when the user acts as their own solver, receiving assets faster.
| Role | Action | Benefit |
|---|---|---|
| Original solver | Fills on destination chain | Earns spread |
| Underwriter | Purchases the claim on origin chain at a discount | Frees solver capital immediately |
| User | Unaffected - receives output as normal | Potentially faster settlement |
New settlers can inherit InputSettlerPurchase to support order purchasing. The underwriter pays the original solver at a discount and waits for oracle proof themselves - a same-chain transaction with no additional cross-chain dependency.