settlement

SettlementService converts verifier attestations into on-chain payouts. This page starts after consensus already has a majority decision and focuses on submission, receipts, and final bookkeeping.


Decision Logic

After each attestation is submitted, SettlementService.advance() evaluates the current tally and either opens settlement or returns the job to escalation:

const majority = Math.floor(totalAssigned / 2) + 1;

if (approvals ≥ majority) → decision = "approve"

if (rejections ≥ majority) → decision = "reject"

if (all voted, no majority) → decision = "uncertain" → status = "escalated"

Settlement Object

When a decision is reached, the service builds a Settlement object with the final verdict and payout totals:

json
{
  "network": "stellar:mainnet",
  "contractAddress": "C...",
  "decision": "approve",
  "threshold": 2,
  "approvals": 2,
  "rejections": 1,
  "providerPayout": "1.00",   // 0.00 on reject
  "verifierPayout": "2.25",   // verifierFee + computeFee (shared only by winning votes)
  "requesterRefund": "0.00",  // providerFee on reject
  "platformFee": "0.07",
  "state": "confirmed",       // pending → submitted → confirmed | failed
  "transactionHash": "0x...",
  "settledAt": "2026-04-07T12:00:00Z"
}

Settlement State Machine

pendingsubmittedconfirmedorfailed

Verifier Penalties

The baseline protocol penalty is lost payout: verifiers whose decision does not match the final verdict receive none of the verifier pool. If a 0G penalty client is configured, the server can also attempt registry slashing after a confirmed settlement.

Reconciliation

Settlements in the submitted state are reconciled through SettlementClient.waitForReceipt(). A confirmed receipt moves the job to approved or rejected; a failed receipt marks the job as settlement-failed.