Summary
Implement the rule that decides a v2 dispute's outcome from the revealed tallies: strict-majority lock, or the optimistic timeout default if neither side reaches one.
What to build
Let F = weight revealed agreeing with the asserted outcome, A = weight revealed against it, W = the total eligible weight frozen at registration cutoff (see #66).
Strict majority check, evaluated after every reveal (see #67) and whenever a phase-advancing call happens:
- A side has an absolute majority when it exceeds half of
W: use side_weight > W - side_weight (checked arithmetic, not side_weight > W / 2, to avoid rounding/overflow issues with integer division).
- As soon as either side crosses this threshold, the outcome is safe to lock (
terminal_cause = StrictMajorityFor or StrictMajorityAgainst), and final_outcome is set. Once locked, terminal_cause and final_outcome never change.
- Reveals may continue after the outcome locks, up to the reveal deadline, so winning-side positions can still prove entitlement for settlement. Settlement itself does not open until the reveal deadline, or immediately if
revealed_weight == W (everyone who could reveal has revealed, so the result can no longer change).
Optimistic timeout default, if neither side crosses the threshold by the reveal deadline:
terminal_cause = OptimisticTimeout, and final_outcome is set to the originally asserted outcome. This applies identically whether the revealed tallies are close, wildly lopsided (e.g. 49% revealed against, 1% revealed for, 50% never revealed, the assertion still stands because 49% never exceeded half of the full W), or an exact tie with 100% reveal.
- This is a deliberate design choice, not a bug: Tholos always resolves to a real boolean rather than an
Inconclusive state, matching v1's existing behavior where an uncontested assertion finalizes as asserted. The burden of proof is on the challenging side to assemble an actual majority of all eligible capital, not just a majority of whoever bothered to show up.
This issue implements the outcome decision only. Settlement (who gets paid what) is a separate issue since the payout rule differs by terminal_cause.
Depends on
#66, #67.
Summary
Implement the rule that decides a v2 dispute's outcome from the revealed tallies: strict-majority lock, or the optimistic timeout default if neither side reaches one.
What to build
Let
F= weight revealed agreeing with the asserted outcome,A= weight revealed against it,W= the total eligible weight frozen at registration cutoff (see #66).Strict majority check, evaluated after every reveal (see #67) and whenever a phase-advancing call happens:
W: useside_weight > W - side_weight(checked arithmetic, notside_weight > W / 2, to avoid rounding/overflow issues with integer division).terminal_cause = StrictMajorityFororStrictMajorityAgainst), andfinal_outcomeis set. Once locked,terminal_causeandfinal_outcomenever change.revealed_weight == W(everyone who could reveal has revealed, so the result can no longer change).Optimistic timeout default, if neither side crosses the threshold by the reveal deadline:
terminal_cause = OptimisticTimeout, andfinal_outcomeis set to the originally asserted outcome. This applies identically whether the revealed tallies are close, wildly lopsided (e.g. 49% revealed against, 1% revealed for, 50% never revealed, the assertion still stands because 49% never exceeded half of the fullW), or an exact tie with 100% reveal.Inconclusivestate, matching v1's existing behavior where an uncontested assertion finalizes as asserted. The burden of proof is on the challenging side to assemble an actual majority of all eligible capital, not just a majority of whoever bothered to show up.This issue implements the outcome decision only. Settlement (who gets paid what) is a separate issue since the payout rule differs by
terminal_cause.Depends on
#66, #67.