> ## Documentation Index
> Fetch the complete documentation index at: https://docs.darkpool.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimistic Oracle

> Move-native propose, dispute, vote, and settle for non-price markets.

Sports outcomes, election results, geopolitical events. None of them have a numeric feed. They need a **human resolution** with bond-backed incentives. DarkPool's answer is `oo_resolution.move`: a Sui-native optimistic oracle with a 30-minute challenge window. Polymarket's UMA window is 7 days.

## State machine

<Frame caption="A proposal starts OPEN. If no one disputes within the challenge window, finalize_auto closes it. If a dispute lands, ResolverNFT holders vote and finalize_vote closes it. The side with majority weight wins both bonds.">
  <img src="https://mintcdn.com/dp-550c5f99/_navSIwbhBEUJaeN/images/oo-lifecycle.png?fit=max&auto=format&n=_navSIwbhBEUJaeN&q=85&s=1197fea88e8a0d95d3246be91ae4c491" alt="Proposal lifecycle. A proposal starts at OPEN where it is open for challenge. Three transitions: dispute (within challenge window) moves to DISPUTED; finalize_auto (window closed, no dispute) moves to FINALIZED_AUTO; finalize_vote (after vote window) moves DISPUTED to FINALIZED_VOTE. FINALIZED_AUTO and FINALIZED_VOTE are end states." width="1024" height="1536" data-path="images/oo-lifecycle.png" />
</Frame>

## Lifecycle

<Steps>
  <Step title="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.
  </Step>

  <Step title="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.
  </Step>

  <Step title="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).
  </Step>

  <Step title="Finalize">
    Two paths:

    * `finalize_auto<COLLATERAL>`. No dispute happened. Proposer wins their bond back. State moves to `FINALIZED_AUTO`.
    * `finalize_vote<COLLATERAL>`. Vote window closed. The side with majority weight wins both bonds. State moves to `FINALIZED_VOTE`.
  </Step>
</Steps>

## 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_auto` when window closed and no dispute. `finalize_vote` otherwise.
* **Historical proposals** list
* **State pill** (OPEN / DISPUTED / FINALIZED\_AUTO / FINALIZED\_VOTE) with `AnimatePresence` transitions
* **Live countdown** to challenge or vote deadline

Voting itself is read-only in v1 (no `ResolverNFT`s have been distributed yet). The panel surfaces vote weights when the window closes.

## Scripts

```bash theme={"system"}
# Propose YES with 50 DUSDC bond
pnpm oo:propose \
  --market-link <SPORTS_OO_MARKET_LINK_ID> \
  --outcome 1 \
  --bond 50 \
  --execute

# 30-minute window. To auto-finalize:
pnpm oo:finalize --proposal 0x... --mode auto --execute
```

`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 to `settlement::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.
