Disputes
A dispute is how a model owner brings evidence of leaked weights or attestation fraud against an operator. The arbitration panel, a named multisig, rules on it under the Operator Agreement. A ruling for the claimant can freeze the operator, revoke all of its attestations and slash its bond to the claimant.
Who can open a dispute
You can open a dispute against an operator when all of these hold:
- You own a model with a lane on one of that operator's nodes.
- That lane has paid protocol fees to the treasury of at least the dispute deposit, and that much of it has not been used by an earlier dispute.
- You pay the dispute deposit.
The second rule is the admission credit. A lane earns credit only when protocol fees actually leave it for the treasury at distribution; fees held as a claim count once the treasury claims them. Revenue to the owner or the operator never counts. Opening a dispute uses up credit equal to the deposit, so a later dispute on the same lane needs new fees.
At the launch fee of 500 bps, the protocol fee is 5% of what a lane distributes, so a lane earns credit equal to the deposit after it has distributed 20 times the deposit:
The lane record shows this directly: eligibleProtocolFeesPaid, admissionCreditConsumed and admissionCreditAvailable.
The deposit
The deposit is a fixed USDC amount, published as disputeDeposit in GET <api-url>/v1/parameters. Opening a dispute moves it from your USDC account into the dispute's own vault.
| Ruling | Your deposit |
|---|---|
| For the claimant | Returned to you, with the slash |
| Dismissed | Forfeited to the beneficiary named in the protocol's dispute configuration |
The deposit policy and its beneficiary are in settlementPolicies.disputeDeposit and disputeConfiguration in the parameters.
Open disputes at once
disputeConfiguration.maxOpenPerClaimantOperator limits how many disputes one claimant can have open against one operator, and maxOpenPerOperator (8 by default) limits open disputes against one operator in total.
Open a dispute in the app
- Open Disputes from the top bar and connect the wallet that owns the model.
- In Open a dispute, choose the lane under Against the operator of lane. Each entry names the lane, its node and the node's operator.
- In Evidence, describe what leaked, where and when, with links to your archive. Only the SHA-256 of this text goes on-chain; keep the evidence itself for the arbitration panel.
- Select Open dispute and sign. The transaction moves your deposit and records the dispute.
The table on the left lists every dispute with Dispute, Operator, Claimant, Deposit, Status and Ruling.
Open a dispute from code
Send the open_dispute intent to POST <api-url>/v1/transactions/preview:
| Field | Value |
|---|---|
authority | Your wallet, the model's owner |
operatorId | The operator's account |
modelId | Your model |
evidenceHash | SHA-256 of your evidence, 64 lowercase hex characters |
disputeNonce | The operator's nextDisputeSequence, from GET /v1/operators/<operator> |
laneId | Optional. The lane that carries the admission credit. Without it, the API picks one of your lanes on that operator that has enough credit |
const operator = await api.detail('operators', operatorId)
if (!operator.ok) throw new Error(operator.error.message)
const preview = await api.previewTransaction({
action: 'open_dispute',
authority: owner,
operatorId,
modelId,
laneId,
evidenceHash,
disputeNonce: operator.data.nextDisputeSequence ?? '0',
})
While a dispute is open
- The dispute's status is
open. - The operator cannot request unbonding or withdraw its bond. The bond stays available for a slash.
- The operator's
openDisputeCounton the Operators page counts it.
Rulings
The arbitration panel rules with rule_dispute. Each ruling records its time, the arbitration authority, a hash of the written ruling and its reason.
| Outcome | Status | Effects |
|---|---|---|
| For the claimant | ruled_for_claimant | Your deposit becomes claimable. The panel can also slash any amount up to the operator's full bond to you, freeze the operator, and revoke all of its attestations |
| Dismissed | dismissed | No slash, freeze or revocation. Your deposit is forfeited to the configured beneficiary |
What each effect does:
| Effect | Result |
|---|---|
| Slash | The amount is taken out of the operator's bond at the moment of the ruling and reserved for you |
| Freeze | The operator is frozen. Its nodes stop qualifying for any model, and it cannot add to, unbond or withdraw its bond |
| Revoke attestations | Every current attestation of the operator becomes invalid at once. Its nodes must attest again before they qualify |
The Disputes table shows the ruling as its reason and the slash amount.
The arbitration panel can also act on an operator directly, without a dispute: freeze it and revoke its attestations, and slash its bond to a model owner whose lane on that operator has paid fees. These records carry relationshipScope: "operator".
Claim the slash and your deposit
After a ruling for you, the reserved slash is settled from the operator's bond vault into the dispute's vault. Then:
- Send the
claim_disputeintent with thedisputeId(and optionally adestinationAta). - Sign. Your deposit and the settled slash arrive in your canonical USDC account.
const preview = await api.previewTransaction({ action: 'claim_dispute', authority: owner, disputeId })
The dispute record shows the amounts: ruling.slashAmount, ruling.claimableAmount, ruling.pendingSlashAmount (reserved, not yet settled) and ruling.depositDisposition (returned or forfeited).
After a dismissal, the forfeiture beneficiary claims the deposit with claim_forfeited_deposit.
Dispute records
GET <api-url>/v1/disputes lists every dispute; filter with status, operatorId, modelId or claimant.
| Field | Meaning |
|---|---|
id | The Dispute account |
operatorId, modelId, laneId, nodeId | Who and what the dispute concerns |
claimant | The owner who opened it |
evidenceHash | SHA-256 of the evidence |
deposit | The deposit in base units |
admissionCreditUsed | The lane credit this dispute used |
openedAt | When it was opened |
status | open, ruled_for_claimant or dismissed |
ruling | ruledAt, authority, rulingHash, slashAmount, claimableAmount, depositDisposition and reason, once ruled |