Arbitration: dedicated-stake commit-reveal quorum
When your agent pays for a call it never receives and raises a dispute, someone has to read
the evidence and rule, and that someone must be neither the operator's friends nor a committee
you are asked to trust. Disputes on the AIOUM network are adjudicated by
CommitRevealArbitrator
(tests): an open set of staked arbitrators who
vote by commit-reveal, with the DAO as a backstop. It is a drop-in arbitrator for the
DisputeManager, installed via setArbitrator with the same IDisputeResolver surface as
the guardian multisig it can replace. The juror's procedure is
Serve as a juror.
The decision
Three models were considered. Decentralization decided it: a ruling on your dispute should not depend on a party you cannot replace.
| Model | Verdict | |
|---|---|---|
| (a) | Single DAO/multisig arbitrator | The bootstrap arbitrator. Simplest, fully centralized judgment. |
| (b) | Small appointed committee | Rejected: a governance-appointed list is (a) with more signers — permissioned, not decentralized. |
| (c) | Open staked arbitrator set | Chosen. The requirement was decentralization; (c) is the only option that delivers it. |
The first version of (c),
ValidationQuorumArbitrator, had three
incentive gaps, all flagged in review, and each shaped its replacement. The wrong electorate:
any service node with enough self-stake could vote, but operators have no reason to
adjudicate competitors' disputes and a conflict of interest when they do, so the predictable
result was apathy. Herding rather than judging: votes were public with a live tally and the
reward paid the winning side, so the rational strategy was to vote with the visible majority,
a Keynesian beauty contest, and nothing punished a careless vote. Apathy acquitted the guilty:
if quorum never arrived, resolveStale closed the dispute as no-fault, the client refunded and
the operator unslashed, so validator laziness was a get-out-of-jail card for fraud.
How CommitRevealArbitrator works
1. A dedicated arbitrator role (fixes the electorate)
Arbitrators stake ZAI into the arbitrator contract itself, a separate pool from
service-operator stake. Anyone with minArbitratorStake may join: adjudication is an opt-in,
paid job with its own collateral, not a side duty bolted onto serving. Operators may also
arbitrate, with distinct capital at risk under distinct rules, and the parties to a dispute are
recused from its votes.
2. Commit-reveal voting (fixes herding)
Each dispute runs two phases, with deadlines snapshotted at first commit so a mid-case governance retune cannot shift a live case:
raise ──── commit window ────┬──── reveal window ────┬── finalize / escalate
(raisedAt+commitPeriod) (+revealPeriod)
In the commit phase a juror submits keccak256(disputeId, voter, vote, salt). The vote is
invisible, there is no tally to herd on, and the commitment binds the voter address so it
cannot be copied. Vote weight is snapshotted at commit time and the arbitrator's stake is
locked until the reveal deadline, which closes the predecessor's live-weight/unbond
loophole and its "same capital backs different disputes" limitation. In the reveal phase the
juror discloses (vote, salt) and the weight lands on the tally. The vote is one bit, so
clients must use a fresh random 32-byte salt; a guessable salt is brute-forceable.
Finalization is permissionless: after the reveal deadline, if revealed weight is at least
quorum with a strict majority, the decision is forwarded to DisputeManager.resolve exactly
once.
3. Accountability with a safe minority (fixes carelessness)
Commit-and-ghost is slashed. Anyone may call slashNoReveal after the deadline, and a
committer who never revealed loses noRevealPenaltyBps (default 20%) of their committed
weight to the treasury; the penalty reaches their unbonding queue, so unstaking at the
deadline is no escape. You cannot occupy the tally and bail. Winning-side revealers split a
reward pot (rewardPerResolution, weight-pro-rata), funded by the DAO from treasury slash
proceeds; when the pot token is ZAI the accounting excludes staked/unbonding collateral
(totalHeldForStake), so a reward can never spend someone's stake. Losing-side revealers are
not slashed: an honest minority must always be safe, because punishing dissent recreates the
herding commit-reveal just removed. Reward participation on the consensus side, punish
non-participation after commitment, never punish an honest losing vote.
4. DAO escalation backstop (fixes apathy-acquits)
If the reveal deadline passes without quorum, or with a tie, the dispute does not default
to acquittal. The DAO, as contract owner, rules directly via
escalate(disputeId, nodeAtFault), allowed only when the quorum path failed and still inside
the DisputeManager's liveness window. resolveStale remains the final valve if even the
DAO goes silent, and honest revealers still collect rewards on an escalated ruling. Liveness
ordering is enforced on both sides: the arbitrator exposes
minVotingPeriod() = commitPeriod + revealPeriod, and both DisputeManager.setDisputeTimeout
and setPeriods require the windows to fit strictly inside the timeout.
Incentive analysis (why this holds up)
Bribery and collusion are expensive: a briber must pay for hidden votes it cannot verify
until reveal, quorum weight is real locked capital, and parties are recused. The residual
risk, a stake-majority coalition ruling its way, is mitigated by a quorum sized against any
single actor, by the DAO refusing to fund rewards for a corrupted set, and ultimately by
governance swapping the module through setArbitrator, which is why it was built swappable.
Recusal is address-level, so a party could arbitrate its own case through a second funded
address, at the cost of a full minArbitratorStake plus the risk that one vote does not flip
a strict-majority quorum; the mitigation is a meaningful minimum stake and a quorum much larger
than any single stake. Lazy consensus, always voting node-not-at-fault to farm rewards, pays
only if disputes are overwhelmingly frivolous; the challenger bond filters frivolous disputes
and the DAO can escalate-override a no-quorum farm. Evidence-based objective disputes narrow
this further (dispute-verifiability.md).
Parameters
| Param | Local development network | Production guidance |
|---|---|---|
minArbitratorStake | 5,000e18 | ZAI worth ≈ $2–5k — lower than a service node; juror capital, not operator capital |
quorum | 25,000e18 | ≥ 3–5× the largest expected single arbitrator stake |
commitPeriod / revealPeriod | 1 day / 1 day | must sum strictly under disputeTimeout (3 days) |
noRevealPenaltyBps | 2000 (20%) | keep ≥ expected reward so ghosting is never EV-positive |
rewardPerResolution | unset | fund from treasury's 80% slash share; target juror APY, not lottery |
unbondingPeriod | 7 days | must exceed revealPeriod + slack so penalties reach leavers |
Deploy with USE_COMMIT_REVEAL_ARBITRATOR=true in Deploy.s.sol;
it takes precedence over USE_QUORUM_ARBITRATOR, and the guardian multisig is the arbitrator
otherwise. A network that starts on the guardian multisig moves to CommitRevealArbitrator
once enough independent arbitrators have staked, with one setArbitrator governance call and
no migration.
Runbook
The procedure for jurors (stake, commit with safe salt handling, reveal, finalize, rewards, penalties, exit) is Serve as a juror. A juror can only rule well on what the evidence proves.
Next: Dispute verifiability — how anchored transcripts turn most disputes from stories into checks.