Settlement

All settlement happens on-chain via USDC on Base. Per-request, immediate, non-custodial.

How It Works

1. Response completes → server extracts token usage

2. Cost calculated at seller's listed price (sellerAmount)

3. Fee calculated: buyerAmount = sellerAmount × feeMultiplier / 10000 + flatFee

4. settle() called on Settlement contract (via UUPS proxy):

- Pulls sellerAmount from buyer's wallet → sends to seller (or payout address)

- Pulls fee from buyer's wallet → sends to feeRecipient

- All in one Base transaction (~$0.001 gas)

Fee Structure

Two components, both configurable on-chain by addresses with ADMIN_ROLE:

  • feeMultiplier — basis points (10000 = 0% fee, 10300 = 3% fee)
  • flatFee — fixed USDC amount per settlement (covers gas costs)

Current settings: feeMultiplier=10000 (0%), flatFee=0

Minimum feeMultiplier: 10000 (1.0x). Sub-1x subsidy mode is not supported.

Anyone can verify on-chain via calculateFee(sellerAmount) (free view call).

Buyer Setup

Buyers call usdc.approve(proxyAddress, amount) once. Funds stay in their wallet — nothing is locked. They can revoke approval at any time.

The proxy address is permanent — contract upgrades don't require re-approval.

Example

Input:  1,847 tokens    Output: 3,201 tokens

Seller: $12/M input, $48/M output

Fee: 0% + $0.001038 flat

Input cost: $0.02216

Output cost: $0.15365

sellerAmount: $0.17581

buyerAmount: $0.17581 × 10000/10000 + $0.001038 = $0.176848

Sent to seller: $0.17581

Sent to fee recipient: $0.001038

Gas: ~$0.001

Payout Address

Sellers can set an optional payout_address to direct settlement to a different wallet. Use cases:

  • Route to a Bankr wallet for automatic LLM credit top-up
  • Send to a treasury or multisig
  • Separate selling identity from payment destination

Failed Settlements

If a settlement fails after inference has already run, the usage row is marked failed and queued in pending_settlements. A cron job retries with exponential backoff for up to 5 attempts.

If all retries fail, the row is marked permanently_failed and removed from the retry queue. There is no automatic insurance pool or automatic seller reimbursement today. The seller is not paid on-chain until a settlement succeeds or the operator manually reconciles it. For API-key settlement, this means the seller can eat the upstream provider cost if the buyer's balance/allowance disappears and retries never settle. For x402/MPP/operator-mediated settlement, the buyer may already have paid the operator; seller payment still depends on the operator settlement succeeding or being manually remediated.

Contract

SettlementV2 deployed behind a UUPS proxy on Base. Source at contracts/SettlementV2.sol.

Architecture:
  • UUPS proxy (permanent address, buyers approve once)
  • Role-based access control via OPERATOR_ROLE, ADMIN_ROLE, UPGRADER_ROLE, and DEFAULT_ADMIN_ROLE
  • Implementation upgradeable by UPGRADER_ROLE without buyer re-approval
  • No contract-level timelock today
Key functions:
  • settle(buyer, seller, sellerAmount) — execute settlement
  • calculateFee(sellerAmount) → (buyerAmount, fee) — free view call
  • feeMultiplier() → current multiplier in basis points
  • flatFee() → current flat fee in USDC units
  • feeRecipient() → where fees go
Admin / trust model:
  • ADMIN_ROLE: setFeeMultiplier(uint256), setFlatFee(uint256), setFeeRecipient(address)
  • DEFAULT_ADMIN_ROLE: grant/revoke roles
  • UPGRADER_ROLE: upgradeToAndCall(address, bytes)

Current limitation: there is no on-chain timelock or multisig requirement enforced by the contract. A role holder can change fee parameters or upgrade in a single transaction. The current feeMultiplier is 10000, and buyers can limit exposure by approving only the amount they are willing to spend.

Operator flow (x402/MPP):

For x402/MPP, the buyer pays/authorizes payment to the SI operator path first, then SI pays the selected seller via operator-mediated settlement. This avoids route-locking issues where a 402 challenge might name one seller but failover chooses another. Seller payout is still visible as a Base USDC transfer when settlement succeeds.