Skip to main content
Predict’s OracleSVI is numeric-only. Sports, politics, and geopolitical events have no numeric feed. DarkPool’s answer is a per-market binary event market: one published Move package per question, with real Coin<YES> / Coin<NO> outcome tokens and a shared Settlement<COLLATERAL> object.

Why one package per market

Sui’s one-time-witness rule means each Coin type needs its own published module. So every event market is a full Move publish:
packages/binary-market-template/sources/
  yes.move          # Coin<YES> OTW + TreasuryCap
  no.move           # Coin<NO> OTW + TreasuryCap
  settlement.move   # Settlement<COLLATERAL> shared object, mint_pair / burn_pair / mark_resolved / redeem
scripts/create-binary-market.ts materialises this template into .binary-markets/binary_market_<slug>/, substitutes slug + label into module names + metadata, builds, publishes, then calls settlement::create_market<DUSDC> which:
  1. Consumes both TreasuryCaps into a shared Settlement<DUSDC>.
  2. Mints a ResolverCap and transfers it to --resolver.
  3. Appends the entry to .binary-markets/registry.json.
The server reads this on every /v1/binary-markets request, with a 4s LRU on live Settlement state. New markets show up immediately, no migration needed.

Lifecycle

1

Create

pnpm binary-market:create \
  --slug btc_80k_eoy \
  --label "BTC > \$80k by EOY 2026" \
  --expiry-ms 1798761600000 \
  --resolver 0xc0ffee... \
  --execute
Publishes the package (~30s, ~0.30 SUI gas), shares the Settlement, mints ResolverCap to --resolver.
2

Mint a pair

A user deposits DUSDC → settlement::mint_pair returns equal quantities of Coin<YES> and Coin<NO>. The trader can hold both, swap one leg for DUSDC on V3 pools, or burn the pair to recover collateral.
3

Trade on V3

Per-market pools (Pool<YES, DUSDC> + Pool<NO, DUSDC>) live on real DeepBook V3 testnet. Bootstrapped via scripts/create-v3-pools.ts (500 DEEP fee each) + scripts/seed-v3-liquidity.ts (two-sided POST_ONLY quotes).Users market-buy / market-sell either leg via pool::swap_exact_quantity with pay_with_deep=false. Fees in the input token, so the user never has to hold DEEP.
4

Burn the pair

Pre-resolution, settlement::burn_pair accepts the smaller of YES / NO balances and pays back the matching DUSDC.
5

Resolve

Once the event is decided, the resolver signs settlement::mark_resolved with the ResolverCap. The winning side becomes redeemable at $1 / token.
pnpm binary-market:resolve \
  --settlement <SETTLEMENT_ID> \
  --resolver-cap <RESOLVER_CAP_ID> \
  --package <PACKAGE_ID> \
  --outcome 1 \
  --execute
6

Redeem

Holders of the winning side call settlement::redeem_yes (or redeem_no) and get DUSDC. Losing coins remain worthless and unredeemable.

The registry on disk

.binary-markets/registry.json is the authoritative source of all scaffolded markets. The server merges it with live Settlement state to serve /v1/binary-markets. New markets need an indexer restart before their event stream exists, but /v1/binary-markets picks them up immediately.
{
  "wc26_euro_champion": {
    "slug": "wc26_euro_champion",
    "label": "Will a European team win the 2026 FIFA World Cup?",
    "packageId": "0xd68bdfd9...",
    "settlementId": "0xef168fa6...",
    "resolverCapId": "0x...",
    "yesType": "0xd68bdfd9...::yes::YES",
    "noType": "0xd68bdfd9...::no::NO",
    "yesPoolId": "0x3990cd7b...",
    "noPoolId": "0x62d0daec...",
    "ooMarketLinkId": "0x7925455e...",
    "expiryMs": 1721433600000
  }
}
The optional ooMarketLinkId field bridges the event market to a MarketLink for the Optimistic Oracle panel.