Settling outcomes
A deployer settles its outcomes with settleOutcome or settleQuestion2, copying names exactly from outcomeMeta; settled outcomes are pruned but stay readable.
Settlement moves everyone’s money at once. Yes balances become settleFraction of the quote token, No balances 1 - settleFraction, and the market is gone. The protocol checks form (outcome, names, a legal fraction), not correctness, which your stake backs.
Say you settle a standalone outcome at "0.66": 1,000 Yes pay 660 of the quote token, and 1,000 No pay 340.
Who may settle
Section titled “Who may settle”- The deployer, directly or through an approved API wallet.
- A sub-deployer with the
settleOutcomeorsettleQuestiongrant (the latter coverssettleQuestion2), for its deployer’s outcomes only. - The protocol, for its own recurring markets (descriptions starting
class:), from mark prices;settledOutcome.detailsrecords the fixing, for exampleprice:76876.9.
One outcome: settleOutcome
Section titled “One outcome: settleOutcome”{ "type": "outcomeDeploy", "venue": "ab", "operation": { "settleOutcome": { "outcome": 7, "settleFraction": "1", "details": "", "nameAndDescription": ["template:abc", "expiry:20260801-0600|target:100|underlying:ABC"], "sideNames": ["template:Over", "template:Under"] } }}| Field | Rule |
|---|---|
outcome |
the numeric outcome id |
settleFraction |
decimal string from 0 to 1, paid to the first side; the second side gets 1 - settleFraction |
details |
must be the empty string |
nameAndDescription |
must match the outcome exactly: copy both strings from outcomeMeta |
sideNames |
must match exactly: template:<Side> for standalone outcomes, Yes and No inside a question |
A standalone outcome may settle to any fraction; a question outcome only to "0" or "1". Question outcomes can settle one at a time: any to 0, in any order, but to 1 only when it is the last active one, which settles the fallback to 0 and the question.
A whole question: settleQuestion2
Section titled “A whole question: settleQuestion2”{ "type": "outcomeDeploy", "venue": "ab", "operation": { "settleQuestion2": { "question": 3, "outcomeSettlements": [ { "outcome": 11, "settleFraction": "1", "details": "", "nameAndDescription": ["template:abc-outcome", "choice:A"], "sideNames": ["Yes", "No"] }, { "outcome": 12, "settleFraction": "0", "details": "", "nameAndDescription": ["template:abc-outcome", "choice:B"], "sideNames": ["Yes", "No"] } ], "nameAndDescription": ["template:abc", "expiry:20260801-1830"] } }}outcomeSettlements must cover exactly the remaining active outcomes, one at "1" and the rest "0"; the fallback settles to 0 automatically. It replaces the discontinued settleQuestion.
The template sets the timing
Section titled “The template sets the timing”The protocol has no settlement window; the template’s fields bind you:
- Price templates publish only
time.binaryPriceandscalarPricesettle on the TWAP over thesecondsbeforetime, not a single mark, so the fixing exists only once that window closes. - Sports templates publish a
resolutionDeadline;scheduledStartis kickoff. - Protocol recurring binaries interpolate linearly between the mark updates either side of the settlement time. Deployer templates settle as their text says.
Before resolution, anyone quoting, the deployer included, should arm a dead man’s switch (scheduleCancel) against informed traders.
Pruned, but still readable
Section titled “Pruned, but still readable”Settled outcomes leave outcomeMeta, typically within about a minute, so anything listed there is unsettled. The record survives in settledOutcome:
{ "type": "settledOutcome", "outcome": 95 }It returns the spec (name, description, side names, quoteToken), settleFraction and details, pruned or not (checked on 69 ids). For a question outcome it adds the parent’s description, the only later source of a price bucket’s bounds.
From the HyperEVM, precompile 0x814 answers outcomeStatus(uint32 outcome) with (uint8 status, uint64 settledValue, uint32 question) (precompiles):
status |
Meaning |
|---|---|
| 0 | never existed |
| 1 | active |
| 2 | settled; settledValue available, 1e8 = 1.0 |
| 3 | settled and pruned; settledValue no longer available |
question is the maximum uint32 for a standalone outcome.
Recurring markets and the rollover
Section titled “Recurring markets and the rollover”A recurring series lists a new market each cycle, often striking off the previous fixing. Build and sign cycle N+1 while N settles; submit it once N’s settlement has landed.
With no outcome id returned, a timeout, 5xx or 429 leaves N+1’s existence unknown. A retry that recomputes the strike from “the latest cycle” then reads N+1 itself: a second, wrongly struck market holding a daily and an active slot until settled. Any deployer deriving parameters from live state is exposed.
The defence:
- Persist the intent and the signed request before submitting.
- On an uncertain result, look in
outcomeMetaby exact name and description. - If absent, resend the stored request unchanged: a nonce works once. If refused as a stale nonce, check
outcomeMetaagain, then re-sign the stored intent. - Never recompute in a retry; key cycles by scheduled time, not the newest outcome.
The numbers
Section titled “The numbers”| Parameter | Value |
|---|---|
settleFraction |
decimal string, 0 to 1; question outcomes exactly 0 or 1 |
details |
empty string |
| Protocol settlement window | none |
Pruning from outcomeMeta |
about 1 minute after settlement |
settledValue scale |
1e8 = 1.0 |
| Precompile | 0x814, outcomeStatus(uint32) |
| Active outcomes freed | 1 per settled outcome |
Getting the action right
Section titled “Getting the action right”- Copy names, never rebuild them:
nameAndDescriptionandsideNamesmust matchoutcomeMetabyte for byte, and a rebuild can change sort order or format. - Validate the side. Defaulting to side 0 on unparseable input settles markets backwards; treat it as an error.
- Fractions are strings without trailing zeros (
"0.25","1"); zeros change the signed bytes. - Settlement fills: one per holder, direction
Settlement, losing side at notional 0, never a builder code. Keep them out of trading volume.
No amend, no expiry
Section titled “No amend, no expiry”- Settlement is final: the docs describe no amend.
- An unsettled outcome never expires. It holds an active slot and blocks deactivation; the announced design made over a week unsettled slashable, unobserved on mainnet.
For what holders receive, see settlement; for the semantics you settle against, outcome templates and keywords.