Skip to main content
The full OO lifecycle for a non-price market.

Prerequisites

  • An OO MarketLink registered (via pnpm market:register --kind oo or scripts during deploy). The id lands in .env as SPORTS_OO_MARKET_LINK_ID.
  • A DUSDC bond ≥ OO_MIN_BOND (50 by default).

1. Propose

pnpm oo:propose \
  --market-link <SPORTS_OO_MARKET_LINK_ID> \
  --outcome 1 \
  --bond 50 \
  --execute
  • --outcome 1 = YES, --outcome 2 = NO.
  • --bond is in whole DUSDC.
PTB:
split_coin(wallet_dusdc, bond)
  → oo_resolution::propose<DUSDC>(config, market_link, outcome, bond, clock, ctx)
  → transferObjects(proposal, sender)
Returns the new Proposal id. State → OPEN. Challenge deadline: now + OO_CHALLENGE_WINDOW_MS (30 min default). Verify:
sui client object <PROPOSAL_ID>
# → state: 0 (OPEN), proposer: <addr>, proposed_outcome: 1, proposer_bond: 50_000_000

2. (Optional) Dispute

Anyone watching can dispute. Match the proposer’s bond:
pnpm tsx scripts/oo-dispute.ts \
  --proposal <PROPOSAL_ID> \
  --bond 50 \
  --execute
State → DISPUTED. Vote deadline: now + OO_VOTE_WINDOW_MS (12h default).

3. Finalize

Auto (no dispute)

After the challenge window:
pnpm oo:finalize --proposal <PROPOSAL_ID> --mode auto --execute
scripts/oo-finalize.ts pre-flight reads the proposal and prints time-remaining instead of letting the Move call abort early. State → FINALIZED_AUTO. Proposer’s bond is returned in the same PTB. final_outcome = proposed_outcome.

Vote (post-dispute)

After the vote window:
pnpm oo:finalize --proposal <PROPOSAL_ID> --mode vote --execute
State → FINALIZED_VOTE. Winning side takes both bonds. final_outcome set from yes_weight vs no_weight.

Frontend integration

EventMarketDetail renders the OOPanel when the registry entry has ooMarketLinkId:
  • Propose form (bond + outcome chips).
  • Dispute form (auto-mirrors counter-outcome, min-bond clamp).
  • Finalize buttons (gated on deadline + state).
  • Historical proposals list.
  • Live countdown.
  • State pill with AnimatePresence transitions.
Voting itself is read-only in v1 (no ResolverNFTs distributed); the panel surfaces vote weights when the window closes.

v0.4 follow-up

The OO does not yet auto-bridge to settlement::mark_resolved. After finalize_* you still need to manually run pnpm binary-market:resolve with the matching outcome. Closing this bridge requires a republish.