How claim disputes work on chain

How the IXO Protocol's Claims module handles a dispute: who can file one, the stake, performance deposits, adjudication, and how the penalty is paid.

The Claims module of the IXO Protocol lets anyone challenge the party who submitted a claim, or the party who evaluated it. A dispute is its own record on chain, and both sides have money at risk: the disputer stakes a deposit, and the agents who submit and evaluate hold performance deposits that they lose if a dispute goes against them. An adjudicator approved by the collection decides the outcome.

This page describes the mechanism as the Claims module implements it in release v8.0.0 of ixo-blockchain. The module's own specification is in its spec folder.

The parts

PartWhat it is
DisputeA record against one claim and one role. Its status is OPEN, AWARDED or DISMISSED.
Target roleThe party being challenged: the SUBMITTER of the claim, or its EVALUATOR.
Dispute depositThe stake the disputer locks when filing. The collection sets the amount.
Performance depositA balance an agent keeps on a collection. The collection can require one before an agent may submit or evaluate. It is what a penalty is taken from.
AdjudicatorA DID on the collection's list of approved adjudicators. Each one sets its own reward percentage.
PenaltyWhat the losing agent pays when a dispute is awarded. The collection fixes it, or the adjudicator sets it within a cap.

Who can file a dispute

Anyone with a registered DID can file one. The signing account must be a key on that DID. No role on the collection is needed, and no grant.

What stops frivolous disputes is the stake. The disputer must lock the collection's dispute deposit when filing, and loses it if the dispute is dismissed.

What a dispute targets

A dispute is against one claim and exactly one role:

  • SUBMITTER. The agent that submitted the claim.
  • EVALUATOR. The agent that evaluated it. The claim must have an evaluation.

To challenge both, file two disputes.

A flagged evaluation cannot be disputed. Flagged means the evaluator declined to make a final call, and the way forward is for an evaluator to re-evaluate the claim to a final status. That evaluation can then be disputed.

What filing does

A dispute is filed with MsgDisputeClaim. It carries the claim's id, the target role, and a pointer to your evidence: a URI, its media type, its content hash, and whether it is encrypted. The content hash is the dispute's key, so it must be unique.

When the message is accepted:

  1. The dispute deposit moves from the disputer's account into the collection's escrow account. The amount is recorded on the dispute, so a later change to the collection's setting does not change what is at stake.
  2. The dispute is stored with status OPEN.
  3. The targeted agent is blocked on that collection. They cannot submit or evaluate claims there, and they cannot withdraw their performance deposit, until the dispute is decided.

Only one OPEN dispute can exist for a claim and a role. If a dispute is awarded, no further dispute can be filed against that claim and role. If it is dismissed, a new one can be filed, for example with new evidence.

Illustrative example, in the pattern of the IXO MultiClient SDK (@ixo/impactxclient-sdk):

const disputeMsg = {
  typeUrl: "/ixo.claims.v1beta1.MsgDisputeClaim",
  value: ixo.claims.v1beta1.MsgDisputeClaim.fromPartial({
    subjectId: "bafkreih...", // the id of the claim
    agentDid: "did:ixo:...", // your DID
    agentAddress: signerAddress, // must be a key on that DID
    disputeType: 1, // your own code for the kind of dispute
    targetRole: ixo.claims.v1beta1.DisputeTargetRole.DISPUTE_TARGET_ROLE_EVALUATOR,
    data: ixo.claims.v1beta1.DisputeData.fromPartial({
      uri: "ipfs://...", // where your evidence document is
      type: "application/json",
      proof: "bafkrei...", // its content hash, unique to this dispute
      encrypted: false,
    }),
  }),
};

await signingClient.signAndBroadcast(signerAddress, [disputeMsg], "auto");

Performance deposits

A collection can require the agents who work on it to keep a deposit there. It sets one amount for agents who submit claims and one for agents who evaluate them. An agent whose balance is below the required amount cannot submit or evaluate.

  • An agent adds to their own balance with MsgAddPerformanceDeposit. The money moves into the collection's escrow account. An agent can top up even while a dispute is open against them.
  • An agent takes money back with MsgWithdrawPerformanceDeposit. It is refused while any OPEN dispute targets the agent on that collection.
  • A collection can set a minimum deposit period. Each top-up locks the balance for that long, so an agent cannot deposit, act and withdraw in one go.

Adjudication

An adjudicator settles an OPEN dispute with MsgAdjudicateDispute. The adjudicator's DID must be on the collection's list, and the signing account must be a key on that DID. The chain does not assign a dispute to a particular adjudicator: any adjudicator on the list can decide it.

The adjudicator gives an outcome, AWARDED or DISMISSED, and can attach a document that sets out their reasoning, in the same form as the disputer's evidence.

For an award, the penalty comes from one of two places:

  • If the collection has a fixed penalty for each dispute, that amount is used.
  • If it has none, the adjudicator must give an amount. It cannot be more than the deposit the collection requires for the losing agent's role.

Who is paid

The adjudicator's share is their own reward percentage, as listed on the collection. The winner gets the rest.

OutcomeWho losesWhere the money comes fromWhere it goes
AWARDEDThe targeted agentThe penalty, taken from the agent's performance depositThe adjudicator's share to the adjudicator, the rest to the disputer. The disputer also gets their dispute deposit back in full
DISMISSEDThe disputerThe disputer's dispute depositThe adjudicator's share to the adjudicator, the rest to the targeted agent

Two limits apply:

  • A penalty cannot be more than the agent's deposit balance at that moment. If an earlier dispute has already reduced the balance, less is paid. The resolution records both the intended penalty and the amount actually paid.
  • The adjudicator's share is rounded down, and the winner receives the remainder.

If the adjudicator's DID belongs to an entity, their share is paid to that entity's adjudicator revenue account. Otherwise it is paid to the signing account.

An example. A collection sets a dispute deposit of 10, a fixed penalty of 50, and lists an adjudicator with a reward of 20 percent.

  • Awarded: 50 is taken from the agent's performance deposit. The adjudicator receives 10 and the disputer receives 40, plus their own 10 back.
  • Dismissed: the disputer's 10 is the pot. The adjudicator receives 2 and the targeted agent receives 8.

What a dispute does not do

  • It does not change the claim's evaluation. An approved claim stays approved. The dispute and its resolution are separate records.
  • It does not reverse a payment that was made when the claim was evaluated. The penalty comes from the losing agent's performance deposit.
  • It does not use the evaluation status disputed. New evaluations can no longer be given that status, and the chain refuses one that tries. Older claims that carry it keep it as history.

Configure disputes on a collection

The collection's admin sets the configuration with MsgUpdateCollectionDisputeConfig. Every field replaces the current value, so send the whole configuration each time.

SettingWhat it controls
serviceAgentDepositRequiredThe performance deposit an agent needs before they can submit a claim. Empty means none
evaluatorDepositRequiredThe same, for agents who evaluate
disputeDepositAmountThe stake a disputer locks when filing
adjudicatorsThe approved adjudicators, each with a DID and a reward percentage from 0 to 100
penaltyAmountPerDisputeA fixed penalty for an awarded dispute. Empty lets the adjudicator set it
minDepositPeriodHow long a performance deposit stays locked after each top-up

The chain enforces these rules:

  • If any deposit, penalty or dispute stake is set, the list of adjudicators cannot be empty.
  • A fixed penalty cannot be more than either required performance deposit.
  • The list of adjudicators cannot be cleared while a dispute is open.
  • A dispute that is already open keeps the deposit recorded when it was filed. The adjudicator list and the penalty rules are read when the dispute is decided.

Messages

MessageSigned byPurpose
/ixo.claims.v1beta1.MsgDisputeClaimThe disputerFile a dispute and lock the stake
/ixo.claims.v1beta1.MsgAdjudicateDisputeAn approved adjudicatorDecide an open dispute
/ixo.claims.v1beta1.MsgUpdateCollectionDisputeConfigThe collection's adminSet deposits, adjudicators and penalty
/ixo.claims.v1beta1.MsgAddPerformanceDepositThe agentAdd to their deposit on a collection
/ixo.claims.v1beta1.MsgWithdrawPerformanceDepositThe agentTake back some or all of their deposit

Version 3.1.0 of the IXO MultiClient SDK includes these messages.

Read disputes and deposits

These are the REST paths of the Claims module's queries.

QueryPath
One dispute, by its content hash/ixo/claims/dispute/{proof}
All disputes/ixo/claims/disputes
The current dispute for a claim and a role/ixo/claims/dispute-by-subject/{subjectId}/{targetRole}
Every dispute for a claim/ixo/claims/disputes-for-subject/{subjectId}
One agent's deposit on a collection/ixo/claims/collection/{collectionId}/deposit/{agentAddress}
All deposits on a collection/ixo/claims/collection/{collectionId}/deposits
A collection, with its dispute settings and counters/ixo/claims/collection/{id}

A collection counts its open, awarded and dismissed disputes. Filing emits ClaimDisputedEvent, and a decision emits DisputeResolvedEvent. Both carry the full dispute record.

Errors you may see

ErrorMeaning
dispute with proof already existsThe content hash of your evidence has been used for another dispute
cannot dispute evaluator role: claim has not been evaluatedYou targeted the evaluator of a claim with no evaluation
cannot dispute a FLAGGED evaluationThe evaluation is not final. It must be re-evaluated first
an OPEN dispute already exists for this (subject_id, target_role)Wait for the open dispute to be decided
this (subject_id, target_role) was previously AWARDEDNo further dispute is allowed against that claim and role
collection has no adjudicators configuredThe collection takes a dispute deposit and has nobody to decide disputes, so the chain will not lock your stake
agent has an active dispute on this collectionYou are the target of an open dispute and cannot submit or evaluate there until it is decided
agent performance-deposit balance is below required amountTop up your deposit before you submit or evaluate
performance-deposit cannot be withdrawn while agent has active disputesWait for the dispute to be decided
performance-deposit is still within the minimum deposit periodWait for the lock from your last top-up to end
adjudicator_did is not in the collection's adjudicators whitelistOnly a listed adjudicator can decide
penalty_amount exceeds the loser's deposit-required capLower the penalty to the required deposit for that role, or less