xtruth

Dispute & escalation

Disputes are the safety mechanism that keeps optimistic claims honest. Anyone with a wallet, the same bond, and a working DVM connection can challenge any live assertion.

Anatomy of a dispute

asserter posts claim + bond
        │
        │  liveness window
        ▼
   ┌────────────┐
   │  no one    │ → settle → claim resolves true,
   │  disputes? │           asserter gets bond back
   └─────┬──────┘
         │ yes (someone calls disputeAssertion)
         ▼
   bond escrowed from disputer
         │
         ▼
   request enqueued in DVM round
         │  24h commit + reveal phases
         ▼
   majority of staked voters answer
         │
         ▼
   settle → winner takes loser's bond,
            wrong voters get slashed

How to dispute (manually)

The web console at app.xtruth.xyz/oracle has a one-click Dispute button on every live assertion. Behind the scenes it does:

  1. approve(OOV3, bondAmount) — same currency as the asserter's bond.
  2. OOv3.disputeAssertion(assertionId, disputer) — escrows your bond and pushes a price request to the DVM.
  3. Wait for the DVM round to resolve (commit-reveal, 24h).
  4. Anyone calls OOv3.settleAssertion(assertionId) to finalize and pay.

How to dispute (programmatically)

If you run an automated guard service (e.g. an LLM bot that reads each new assertion, checks the claim against ground truth, and disputes if the claim looks wrong), you point it at the same disputeAssertion ABI. A reference LLM dispute bot is a good starting point — it watches new assertions, runs the claim through an LLM with retrieval, and disputes when the LLM's answer disagrees with the asserter's.

Escalation managers

By default a dispute goes straight to the DVM. With a custom escalation manager you can:

Your escalation manager implements EscalationManagerInterface and is passed as an argument to assertTruth(). See the EscalationManager source in the xtruth-app contract bundle.

Cost calculation for disputes

If you win, your net is: +bondAmount - voting fee - gas. If you lose, your net is: -bondAmount - voting fee - gas.

That asymmetry is exactly the point — only people confident in their position dispute.

Watching for new disputes

Subgraph query for currently disputed assertions:

{
  assertions(
    where: { disputer_not: null, settlementTimestamp: null }
    orderBy: disputeTimestamp
    orderDirection: desc
  ) {
    assertionId
    claim
    asserter
    disputer
    bond
    disputeTimestamp
  }
}

See Subgraph API for the full schema.