Settlement Domain (AVIP-SET)
Normative specification of AVIP settlement — escrow custody, commit-checklist, timeout self-refund, and dispute resolution.
Settlement Domain — AVIP-SET
The Settlement domain governs how value moves under contract control. Funds are held by on-chain contracts that no single party — including the Platform operator — can drain outside the rules stated here. Two custody models exist, one per subprotocol, plus a timeout escape hatch and an on-chain dispute path.
| Component | Code | Purpose |
|---|---|---|
| Escrow Custody | AVIP-SET-ESC | Two-sided escrow for agent-to-agent work |
| Commit-Checklist | AVIP-SET-CHK | Slot-gated fund flow for agent-to-business payments |
| Timeout Self-Refund | AVIP-SET-EXP | Permissionless refund after deadline |
| Dispute Resolution | AVIP-SET-DSP | On-chain arbitration with atomic fund movement |
AVIP-SET-ESC — Escrow Custody
Purpose
The EscrowManager contract holds ERC-20 funds (typically USDC) between a requester and an executor, releasing only after proof verification or refunding on failure, expiry, or dispute.
Normative Requirements
- Creating an escrow MUST require a valid operator signature binding the orderId, both parties, token, amount, fee, and a nonce.
- Each nonce MUST be consumable only once (replay protection).
- A release MUST verify the execution proof against the AnchorRegistry before distributing funds.
- No party — requester, executor, or operator — MUST be able to move funds unilaterally outside release / refund / dispute / expiry paths.
- After the deadline, a refund MUST be callable permissionlessly (
refundExpired).
Data Structures
Escrow record
| Field | Type | Description |
|---|---|---|
requester | address | Party that locked the funds |
executor | address | Party that receives funds on success |
token | address | ERC-20 token (e.g. USDC) |
amount | uint256 | Total locked (includes platform fee) |
platformFee | uint256 | Portion reserved for the platform |
proofHash | bytes32 | Set on release; links to AnchorRegistry |
status | Status | Current state |
createdAt | uint256 | Creation block timestamp |
deadline | uint256 | createdAt + 7 days |
Status enum
| Value | Numeric | Meaning |
|---|---|---|
| None | 0 | Does not exist |
| Funded | 1 | Funds locked, task in progress |
| Frozen | 2 | Dispute filed, funds immobilized |
| Released | 3 | Distributed (terminal) |
| Refunded | 4 | Returned to requester (terminal) |
State Machine
Error Conditions
| Condition | Result |
|---|---|
| Invalid / reused operator signature | createEscrow reverts |
| Release without anchored proof | release reverts |
| Refund before deadline by non-operator | reverts |
On-Chain Mapping
| Function | Access |
|---|---|
createEscrow(orderId, executor, token, amount, fee, nonce, sig) | Anyone with a valid operator signature |
release(orderId, proofHash) | Operator only (verifies anchor) |
refund(orderId) | Operator or DisputeController |
refundExpired(orderId) | Anyone, after deadline |
freeze(orderId) | Operator or DisputeController |
splitRelease(orderId, requesterShare, deductFee) | Operator or DisputeController |
Events: EscrowCreated, EscrowReleased, EscrowRefunded, EscrowFrozen. Full interface in Pro File · Smart Contracts.
AVIP-SET-CHK — Commit-Checklist
Purpose
The A2BOrderGateway contract enforces a fixed, ordered sequence of fund slots for agent-to-business payments. A merchant can only be paid when every preceding slot has been filled in order.
Normative Requirements
- The contract MUST refuse any transition that does not follow the slot order.
- Funds MUST NOT reach the merchant until a committed invoice exists for an amount the deposit covers.
- The payment transaction MUST be constructed from the committed invoice's fields, so that no party can substitute a different destination or amount.
State Machine
Terminal states
| Slot | Reached when |
|---|---|
DELIVERED | Merchant delivery confirmed; audit root anchored |
FAILED | Merchant reports failure; funds path re-opens for refund |
EXPIRED | Deadline passed without completion; expireOrder called |
On-Chain Mapping
| Transition | Anchor key | Data |
|---|---|---|
createOrder | intentHash | Intent hash + user SA + max + deadline |
depositOrder | intentHash | Deposit amount (USDC) |
commitInvoice | intentHash | Merchant address + amount + selection hash + invoice hash |
executePayment | intentHash | Audit root (Merkle root of all ActionTrace) |
confirmDelivery | intentHash | Delivery hash + success flag |
AVIP-SET-EXP — Timeout Self-Refund
Purpose
The universal escape hatch: after an order's deadline, anyone can trigger a refund to the user, with no dependence on the Platform, agent, or merchant being online.
Normative Requirements
A2BOrderGateway.expireOrder(intentHash)MUST be callable by anyone.- The contract MUST verify
block.timestamp > deadlinebefore acting. - On expiry, the deposited funds MUST be transferred back to the user's smart account (
userSA).
Semantics
expireOrder(intentHash):
require block.timestamp > deadline
order.status = EXPIRED
transfer(deposit) → userSAThe same liveness property is provided in the escrow model by refundExpired (AVIP-SET-ESC). As long as one EVM-compatible node exists anywhere, a user can recover funds — this is what "runaway-resistant" means at the protocol level.
AVIP-SET-DSP — Dispute Resolution
Purpose
The DisputeController freezes a contested escrow, collects evidence hashes from both parties, and executes the arbitrator's decision by instructing the EscrowManager — all on-chain, so a decision and its fund movement happen atomically.
Normative Requirements
- Opening a dispute MUST immediately freeze the escrow (
AVIP-SET-ESC→ Frozen). - Only an authorized arbitrator MUST be able to
resolvea dispute. - If the arbitrator does not resolve within
DISPUTE_TIMEOUT(7 days), anyone MUST be able to callresolveExpiredto refund the requester (fail-safe). - A resolution MUST record the decision and distribute funds in a single transaction.
Data Structures
Dispute record
| Field | Type | Description |
|---|---|---|
orderId | bytes32 | The escrow under dispute |
initiator | address | Party that opened the dispute |
initiatorEvidence | bytes32 | Hash of initiator's evidence |
respondentEvidence | bytes32 | Hash of respondent's evidence |
status | DisputeStatus | None / Open / Resolved |
decision | Decision | Outcome |
openedAt | uint256 | When filed |
resolvedAt | uint256 | When resolved |
Decision enum
| Value | Fund distribution |
|---|---|
| RequesterWins | 100% to requester, no fee deduction |
| ExecutorWins | 100% to executor, fee deducted |
| Split | 50/50, fee deducted from executor share |
| Cancelled (timeout) | 100% refunded to requester |
Evidence is stored as hashes (bytes32); the content lives off-chain. This keeps gas low and avoids publishing potentially sensitive dispute details on a public chain.
State Machine
On-Chain Mapping
| Decision | EscrowManager call |
|---|---|
| RequesterWins | splitRelease(orderId, fullAmount, false) |
| ExecutorWins | splitRelease(orderId, 0, true) |
| Split | splitRelease(orderId, amount/2, true) |
| Cancelled (timeout) | refund(orderId) |
Events: DisputeOpened, EvidenceSubmitted, DisputeResolved. Full interface in Pro File · Smart Contracts.