Family A: Oracle resolution
Family A markets resolve automatically atresolutionTime by reading an XLS-47 price oracle entry on the XRPL. No human input is required for a clean resolution.
What happens at resolution time
1
Read oracle
The settlement engine queries the XLS-47 oracle at
oracleAccount / oracleDocumentId for the baseAsset/quoteAsset pair.2
Check freshness
The oracle value’s The 120-second post-close grace period absorbs publish cadence, a value published just after
lastUpdateTime must satisfy:resolutionTime is still accepted. Freshness is measured against resolutionTime, not the wall clock at the time the engine runs, so settling late cannot use a price that did not exist at close.3
Evaluate condition
The engine compares the oracle’s reported price against
strike using comparison:>= strike, outcome 0 (Yes) wins ifprice >= strike<= strike, outcome 0 (Yes) wins ifprice <= strike
4
Publish resolution record
The operator writes a signed
ResolutionRecord memo to the pool account with status: "final", the winningOutcome index, the raw oracleValue, and the oracleLastUpdateMs timestamp. This record is the authoritative on-chain proof of resolution.5
Distribute payouts
The committee multisig sends a Payment from the pool account to each winning bettor, tagged with a
payout memo. Settlement is idempotent: the engine reads already-paid accounts from the ledger before each run and skips them.Freshness void
If the oracle value’s age relative toresolutionTime falls outside the freshness window (accounting for the 120-second grace period), the market voids immediately. All stakes are refunded. See Void policy below.
Family B: Manual (optimistic) resolution
Family B markets use an optimistic resolution model adapted from UMA’s Optimistic Oracle, rebuilt on native XRPL primitives with no smart contract and no token vote. The operator proposes an outcome and posts a bond, a dispute window opens, and the multisig committee finalizes. counsel says plainly where the trust lives: this is custodial-transparent, a disclosed council, not a trustless oracle. The full design is in optimistic-oracle.md.What happens at resolution time
1
Operator proposes and bonds
After
resolutionTime, the proposer posts a signed on-chain ResolutionRecord with status: "proposed" to the pool account, including winningOutcome, an evidence source URL, and an evidence hash. The proposer posts the symmetric bond whose size is pre-committed in the market definition (bondXrp), so the bond is fixed and non-negotiable.2
Dispute window opens
The window lasts
disputeWindowHours (default 48). Any account can open a dispute by posting a matching bond to the pool, anchoring its own evidence (a source URL and a content hash) on-chain, so the dispute references the same canonical record as the proposal. An undisputed proposal is correct by default.3
No challenge: committee signs
If the window closes with no dispute, the multisig committee cosigns the proposed outcome. Settlement proceeds identically to Family A: a final
ResolutionRecord is written on-chain, then payouts are distributed, and the proposer reclaims their bond.4
Challenged: committee finalizes and resolves bonds
If one or more bonds are posted, the committee reviews the evidence independently and signs the final outcome, which may or may not agree with the proposal. The final
status: "final" record supersedes the proposal. The committee then resolves the bonds (see below).A
proposed record is visible in the pool account’s transaction history but does not trigger payout distribution. Only a status: "final" record initiates settlement. A void (the “too early” or ambiguous outcome) is a first-class result that refunds every stake with no fee, the analogue of UMA’s 50-50 answer, so an unanswerable market never mis-resolves.Bonds and the final fee
Bonds are symmetric and pre-committed: the proposer postsbondXrp and a disputer must match it exactly, so neither side can take a cheaper position. A wrong side forfeits its bond to the right side, which is what turns a wrong proposal into free money for the first honest disputer and is the entire economic security of the model.
counsel also implements UMA’s final fee. A configurable slice of the slashed bond, finalFeeBps (basis points), is skimmed to the council treasury before the winner is paid; the winner’s own bond is always returned in full. The fee funds the arbiter and makes a frivolous bond cost real money even when you win. The bond math is integer-only and rounds down, so the fee plus the awards can never exceed the slashed bond, and the whole path is test-driven.
Void policy
The following conditions result in a full refund with no fee deducted:
When any condition is met, the settlement engine distributes refunds instead of payouts. Each bettor receives their exact original stake back via a native XRP Payment. Market-maker seeds are excluded from refunds (they are house-neutral) and remain as pool residue.
What happens on void
A void is not an error state, it is a defined contract outcome. On void:- The
ResolutionRecordis written on-chain withvoid: trueandwinningOutcome: null. - Every non-seed stake is refunded at face value (drops in = drops out).
- No fee is deducted from any refund.
- The pool account’s remaining balance (seeds + dust) stays under operator control.
Trust model
Pool accounts are secured so that no single party, including the operator, can unilaterally move funds:Master key disabled
After the pool account is created, the master key is disabled on-chain. There is no signing key that can authorize a unilateral Payment.
n-of-m SignerList
A multisig
SignerList is set on the pool account. A threshold of committee members must cosign any outgoing transaction before the XRPL will process it.