BASIS
Documentation

Settlement

Settlement turns accrued worker rewards into on-chain payments on Base. It is keeper-driven and idempotent: a batch is identified by a deterministic hash and settles exactly once, so a reward is never paid twice — and a failed transaction leaves rewards recoverable.

Reward ledger

When a completed job accrues a worker reward, a reward ledger entry is created. The entry accumulates and moves through these states as it is batched and settled.

pendingA reward has accrued from a completed job and is waiting to be batched.
batchingThe reward has been assigned to a batch that is being prepared for submission.
settledThe batch confirmed on Base and the reward is settled.
failedThe settlement attempt failed. The reward rolls back to pending — never erased.

Batches

Pending rewards are grouped into a settlement batch. Each batch has a deterministic batchHash derived from its contents, which is what makes settlement idempotent.

pendingThe batch is assembled with a deterministic batchHash and is ready to submit.
submittedThe settlement transaction has been broadcast to Base.
confirmedThe transaction confirmed. Member rewards move to settled and a BaseScan link is available.
failedThe on-chain transaction failed. Member rewards roll back to pending; the batch can be retried.

BaseScan links appear once a transaction hash exists — a batch's explorer URL is https://basescan.org/tx/<txHash> and is null until the transaction is broadcast.

Idempotency & recovery

A given batchHash settles once. Re-running settlement over an already-settled batch is a no-op — the keeper recognizes the hash and does not re-submit, so rewards are never paid twice.

If an on-chain transaction fails, the batch is marked failed and its member rewards roll back to pending. Nothing is erased; the rewards remain recoverable and can be re-batched and retried on the next keeper run.

Distributor status

Reward distributor

PendingDry-run

Reward settlement is pending until the reward distributor is configured. rewardSettlementEnabled() currently returns false. Until it is configured, the keeper runs in dry-run mode: it assembles batches and computes hashes but signs and submits nothing.

The keeper

Settlement is driven by a keeper run, not by the web app. The web app never signs and never holds a key on its hot path — settlement happens out of band.

bash
# Assemble pending rewards into batches and settle on Base.
# Runs in DRY-RUN until BASIS_REWARD_DISTRIBUTOR_ADDRESS is configured —
# it computes batch hashes but signs and submits nothing.
pnpm settle:rewards

The keeper is the only component that signs settlement transactions, and only when the reward distributor is configured. The application and its request path never sign.

Reading batches

List settlement batches and their status. Confirmed batches carry an explorerUrl to the BaseScan transaction; unsettled batches report null.

bash
curl -s https://basis.watch/api/settlement/batches

# { "batches": [ { "batchHash": "...", "status": "pending",
#                  "explorerUrl": null, ... } ], "count": 0 }