Appeals¶
Permissionless escalation to a larger panel. Anyone may appeal a resolved round within the appeal window.
The appeal window is per-Subaccord (
dispute.terms.appeal_window, frozen at filing; default 3 days, floor 1 hour — ADR-0022). Setmax_appeals == 0to disable appeals entirely.
appeal()¶
appeal(ctx, new_evidence_hash) — the new_evidence_hash: [u8; 32] argument is the
evidence-on-appeal channel (ADR-0023). It is
stored at dispute.evidence_hashes[current_round + 1] (the round this appeal opens). Pass
[0u8; 32] to appeal on the existing evidence only — the sentinel means "no new evidence this
round," and round-N jurors reuse the accumulated evidence_hashes[0..=N].
| Gate | Error |
|---|---|
!pause_state.paused |
ProgramPaused |
state == RoundResolved |
InvalidState |
current_round < max_appeals |
MaxAppealsReached |
now < reveal_end + terms.appeal_window |
AppealWindowClosed |
subaccord.staker_count ≥ new_panel |
InsufficientJurors |
Panel ladder¶
Closed form panel_k = (J+1)·2^k − 1, capped at MAX_JURORS (31).
current_round (after++) |
panel (J=3) |
|---|---|
| 1 | 7 |
| 2 | 15 |
| 3 | 31 |
Cost¶
fee_new = panel_new × fee_per_juror
bond = fee_new // bond == new-round fee
total = fee_new + bond // appellant ATA → vault
Bond settlement¶
- Recorded in
AppealBondPDA["bond", dispute, round_idx]whereround_idx= the new (larger) round. prior_result: u64= winning value of the round being appealed — option index (Plurality) or median (Median); u64 since ADR-0025.finalize_disputechecks each bond:prior_result == final_ruling⇒ no flip ⇒ bond folded into the final-round coherent pool and zeroed.prior_result != final_ruling⇒ flip ⇒ bond left forclaim_appeal_refund.claim_appeal_refundreturns flipped bonds to their appellant (idempotent).
Round reset¶
appeal increments current_round, stores new_evidence_hash into
evidence_hashes[current_round] (the new round's slot), and resets state → Created,
so the VRF → draw → vote cycle reruns for the larger panel. The same committed_vrf and
frozen_root are reused — appeals draw a larger panel from the same fixed pool (no new VRF,
no re-grind; ADR-0012).
accord::appeal(ctx.contexts, new_evidence_hash)?; // [u8; 32]; [0u8; 32] = no new evidence
// later, after Final:
accord::claim_appeal_refund(ctx.contexts, round_idx)?; // round_idx = appealed round
import { appeal, claimAppealRefund } from "@useaccord/sdk";
// newEvidenceHash: Uint8Array(32); all-zeros = appeal on existing evidence (ADR-0023)
await appeal(accord.adapter, accord.PROGRAM_ID, { dispute, newEvidenceHash });
// after finalize_dispute:
await claimAppealRefund(accord.adapter, accord.PROGRAM_ID, {
dispute,
roundIdx,
});
Why permissionless + bond economics: ADR-0004. Cross-round settlement against the final ruling: Kleros §4.6.