Verification Logic
The facilitator performs these checks in order:- Type guard: Payload matches
Eip3009PayloadorPermit2Payload(includessignatureandsalt). - Scheme match:
requirements.scheme === "auth-capture"andpayload.accepted.scheme === "auth-capture". - Network match:
payload.accepted.network === requirements.networkand format iseip155:<chainId>. - Extra validation: All required
extrafields present. - Method routing:
extra.assetTransferMethod(default"eip3009") matches the payload shape. - Deadline ordering:
refundDeadline >= captureDeadline,captureDeadline > now + 6s, and the payload’svalidBefore(EIP-3009) ordeadline(Permit2)<= captureDeadline. - Time window:
validBefore/deadline > now + 6s(not expired) andvalidAfter <= now(active, EIP-3009 only). - Spender / collector match:
authorization.to === EIP3009_TOKEN_COLLECTOR_ADDRESS(EIP-3009) orpermit2Authorization.spender === PERMIT2_TOKEN_COLLECTOR_ADDRESS(Permit2). - Token match:
permit2Authorization.permitted.token === requirements.asset(Permit2 only, EIP-3009 binds via signing domain). - Signature verify: Recover signer from EIP-712 (
ReceiveWithAuthorizationorPermitTransferFrom); must match payer. - Amount: Authorization amount matches
requirements.amount. - Nonce match: Reconstruct
PaymentInfofrom extra + salt + payer + requirements; recompute the payer-agnostic hash; assert it matches the wire nonce. This transitively enforces equality on every field encoded inPaymentInfo(receiver, token, deadlines, fee bounds, feeRecipient). - Simulate: Call
AuthCaptureEscrow.authorize(...)or.charge(...)viaeth_callto verify success.
SAFETY_MARGIN_SECONDS constant is 6, which is why deadline comparisons use now + 6s.
EIP-6492 Support
For smart wallet clients, the signature may be EIP-6492 wrapped (containing deployment bytecode). The facilitator extracts the inner ECDSA signature for verification. The on-chainERC6492SignatureHandler in the token collector handles wallet deployment during settlement.
Settlement Logic
- Re-verify the payload (catch expired/invalid payloads before spending gas).
- Determine function:
extra.autoCapture === true ? "charge" : "authorize". - Resolve collector:
EIP3009_TOKEN_COLLECTOR_ADDRESSorPERMIT2_TOKEN_COLLECTOR_ADDRESS(perassetTransferMethod). - Encode
collectorData: raw ERC-3009 signature, or ABI-encoded Permit2 signature. - Call escrow:
AuthCaptureEscrow.<functionName>(paymentInfo, amount, tokenCollector, collectorData). - Wait for receipt: 60s timeout.
- Return result: tx hash, network, payer.
Error Codes
Verification Errors
Settlement Errors
Next Steps
Wire Format
PaymentRequirements and PaymentPayload shapes.
PaymentInfo Struct
On-chain struct, expiry ordering, and safety guarantees.
