Skip to content

Resolution & Disputes

Resolution is the step that turns outcome tokens into money. It is a multi-stage, bonded process rather than a single authority call.

Open ──▶ Closed ──▶ PendingResolution ──┬──▶ Resolved ──▶ redeem
│ │
(dispute) └── (no dispute, window elapses)
▼
Disputed ──▶ Resolved or Cancelled ──▶ refund
InstructionWhoEffect
close_marketOperatorStops trading at end_time
resolve_marketResolution authorityProposes an outcome; starts the dispute window
dispute_resolutionAnyonePosts a bond into the vault, contesting the proposal
finalize_resolutionAnyoneAfter the window elapses, makes the outcome final
cancel_marketConfig resolverVoids the market; collateral is refundable

The dispute parameters — bond size and window length — live in the program’s Config PDA.

resolve_market does not pay anyone. It proposes. The gap between proposal and finalization is the only opportunity to catch a wrong resolution, and the bond is what makes disputing costly enough to be meaningful. Nothing redeems until finalize_resolution lands.

Once Resolved:

markets::redeem winning outcome tokens → USDC, 1:1 from the market vault

The losing side is worthless. Redemption is a transaction you send — it isn’t automatic, and the program sets no deadline. withdraw_residual lets an admin sweep a market only after it is fully settled.

A cancelled market never had a winner. markets::refund returns collateral against either token type, because both are claims on the same undivided pot.

Cancellation has a second life in parlays: a leg whose market cancels doesn’t kill the slip. It goes Voided and is divided out of the multiplier, shrinking the payout to what the remaining legs justify. → Settlement & Claiming

Market statusNew ordersSettlement of existing matches
Openyesyes
Closednoyes, if before end_time
PendingResolutionnono
Disputednono
Resolvednono
Cancellednono

execute_trade requires the market to be Open or Closed and before end_time. The Closed allowance exists so a match made moments before close can still land; it is not a window for new trading.

Terminal window
# Dispute info for a market
curl -s https://prod-api.gomarket.io/api/markets/{market_id}/dispute/
# A user's open disputes
curl -s https://prod-api.gomarket.io/api/markets/user/disputes/ \
-H "Authorization: Bearer $JWT"
# What's redeemable
curl -s https://prod-api.gomarket.io/api/markets/user/claimable/ \
-H "Authorization: Bearer $JWT"

A parlay leg settles once its underlying market is terminal, via the permissionless settle_leg:

Market stateLeg becomes
Resolved, your side wonWon
Resolved, your side lostLost — the whole slip dies immediately
CancelledVoided — divided out of the multiplier
Anything elseTransaction reverts (MarketNotResolved, 6013)

Because a parlay reads the market’s resolved outcome rather than a price, the dispute window protects parlays exactly as it protects redemptions: a leg cannot settle against a proposal, only against a finalized result.