Skip to content

Extend voucher settlement functionality#20

Open
yongqjn wants to merge 8 commits into
erc-8183:mainfrom
okx:add-settle
Open

Extend voucher settlement functionality#20
yongqjn wants to merge 8 commits into
erc-8183:mainfrom
okx:add-settle

Conversation

@yongqjn
Copy link
Copy Markdown

@yongqjn yongqjn commented May 8, 2026

Summary

  • add settle(jobId, cumulativeAmount, voucherSig, optParams) for client-authorized partial settlement
  • track per-job settledAmount as the cumulative gross amount released from escrow
  • verify EIP-712 Voucher(jobId, cumulativeAmount, optParams) signatures against the job client
  • release only the new settlement delta and keep the job active after settlement
  • update complete, reject, and claimRefund to operate on budget - settledAmount
  • add architecture docs and tests for monotonic settlement, stale voucher rejection, invalid signatures, final completion, rejection, and refund accounting

Design Reference

This follows the Partial Settlement: Vouchers design described in HackMD:
https://hackmd.io/@nicholas-okx/rkiZgYtRZx

The design goal is to standardize the release and accounting primitive for long-running or milestone-based jobs. The provider submits a client-signed cumulative voucher, and ACP releases only the newly authorized delta without completing the job.

Settlement Semantics

  • only the provider can call settle
  • job must be Funded or Submitted and not expired
  • voucher must be signed by the client
  • cumulativeAmount must strictly increase over settledAmount
  • cumulativeAmount cannot exceed budget
  • successful settlement updates settledAmount = cumulativeAmount
  • the job remains active after settlement

Fee Policy Chosen

The HackMD lists multiple fee handling options. This PR intentionally implements the option where both platform and evaluator fees are charged pro rata against each settlement delta.

Concretely:

  • each settle computes fees from delta = cumulativeAmount - settledAmount
  • platform and evaluator fees are paid immediately on that delta
  • provider receives the net settlement delta
  • final complete charges fees only on the remaining escrow amount

This means fees are not reserved upfront and are not deferred entirely until final completion.

Testing

  • npm test
  • 14 passing

albbm and others added 8 commits May 8, 2026 15:04
… storage

Unified submitClaim entry point for both fast (immediate) and slow (pending
approval) settlement paths. Provider-only caller; deliverable.length selects
path; both paths verify a client-signed EIP-712 ClaimVoucher.

  - deliverable.length == 0 → fast path: unconditional voucher, immediate
    delta release, supersedes any pending slow claim.
  - deliverable.length  > 0 → slow path: deliverable is the condition the
    evaluator/client must vet. Stored as a single-slot binding hash
    keccak256(abi.encode(cumulativeAmount, keccak256(deliverable))).

approveClaim and rejectClaim accept the preimage components and recompute
the hash, so approvers cannot release funds for a claim other than the
one the provider committed to. Both are restricted to client OR evaluator;
provider self-approve and self-reject revert Unauthorized.

Storage:
  - mapping(uint256 => bytes32) public pendingClaimHash (single slot per job)
  - bytes32(0) means no pending claim
  - Adds CLAIM_VOUCHER_TYPEHASH and _verifyClaimVoucher (binds deliverable
    into the EIP-712 digest so the client's signature attests to the work,
    not just the amount).

Events: ClaimSubmitted (carries full deliverable bytes for indexers),
ClaimApproved (carries deliverableHash), ClaimRejected.

Tests cover both paths, auth model (provider-only submit, client/evaluator-
only approve/reject), preimage-mismatch revert, monotonic enforcement,
ClaimAlreadyPending, fast-path supersedes slow-path, invalid-signature revert.

Note: combined diff is 484 LOC. Kept as a single commit because contracts
and tests are tightly coupled — splitting would leave one commit with
unvalidated code or orphan tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restrict the claim workflow to Funded jobs so submitClaim, approveClaim, and rejectClaim are not processed after a job enters Submitted.

Refactor claim deliverables to bytes32 to match submit(), including ClaimVoucher signing, pending claim hashing, claim events, hook payloads, tests, and docs.
Evolve settle into submitClaim

See merge request web3-wallet/community/base-contracts!1
# Conflicts:
#	test/ERC8183.test.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants