oo_resolution.move: a Sui-native optimistic oracle with a 30-minute challenge window. Polymarket’s UMA window is 7 days.
State machine
Lifecycle
Propose
Anyone calls
oo_resolution::propose<COLLATERAL>(market_link, outcome, bond_coin, clock, ctx) with a DUSDC bond at or above OO_MIN_BOND. If no one disputes within OO_CHALLENGE_WINDOW_MS (default 30 min), the proposal becomes the final outcome.Dispute (optional)
Anyone can call
dispute<COLLATERAL> with a counter-bond equal to the proposer’s. State moves to DISPUTED. A DAO vote is triggered.Vote (DISPUTED only)
ResolverNFT holders call cast_vote(vote_ledger, proposal, weight, vote). Each vote is weighted by the holder’s ResolverNFT weight. The vote window is OO_VOTE_WINDOW_MS (default 12 hours).States
| State | Value | Meaning |
|---|---|---|
OPEN | 0 | Proposal active, in challenge window |
DISPUTED | 1 | Dispute filed, voting open |
FINALIZED_AUTO | 2 | Auto-finalized (no dispute) |
FINALIZED_VOTE | 3 | Finalized by DAO vote |
Outcomes
| Outcome | Value |
|---|---|
YES | 1 |
NO | 2 |
Frontend integration
EventMarketDetail renders the OOPanel whenever the binary-market registry entry has an ooMarketLinkId. Full lifecycle UI:
- Propose form (bond amount + YES / NO chips)
- Dispute form (auto-mirrors counter-outcome, min-bond clamp)
- Finalize buttons.
finalize_autowhen window closed and no dispute.finalize_voteotherwise. - Historical proposals list
- State pill (OPEN / DISPUTED / FINALIZED_AUTO / FINALIZED_VOTE) with
AnimatePresencetransitions - Live countdown to challenge or vote deadline
ResolverNFTs have been distributed yet). The panel surfaces vote weights when the window closes.
Scripts
scripts/oo-finalize.ts pre-flight-reads the proposal and prints time-remaining instead of letting the Move call abort early.
Bridge to settlement (v0.4)
The OO does not yet bridge tosettlement::mark_resolved automatically. That’s a v0.4 republish follow-up. For now, after finalize_* the resolver manually signs binary-market:resolve with the matching outcome.