Skip to main content
Two distinct settlement paths:

Price markets (auto via resolver keeper)

The resolver’s auto-settle keeper runs every 60s. On expiry of any Predict oracle with opted-in redeemers (or any indexed PositionMinted event), it builds one PTB per redeemer:
pyth::update_price_feeds([priceFeedData])       # first push triggers OracleSVI → Settled
  → market_key::new (or range_key::new)
  → predict::redeem_permissionless<T>           # void; credits manager balance
  → predict_facade::attribute_redeem             # event
Per-position PTBs isolate aborts (one stale-qty position can’t sink the batch). Results land in redemptions table; /profile realized-P&L tile + chart update on next refresh. Log excerpt:
[resolver] tick: 12 expired tuples
[resolver] redeem ok oracle=0x… strike=$65000 isUp=true digest=AbcD…
Manual trigger (via REST):
curl -X POST http://localhost:8082/markets/0xABC/resolve \
  -H 'Content-Type: application/json' \
  -d '{
    "oracleSviObjectId": "0x…",
    "pythPriceInfoObjectId": "0x…",
    "pythFeedIdHex": "e62df6c8…",
    "optedInRedeemers": [{"predictManagerId": "0x…", "marketKind": 0}]
  }'

Binary event markets (manual via ResolverCap)

After the real-world outcome is known, the holder of the market’s ResolverCap signs:
pnpm binary-market:resolve \
  --settlement <SETTLEMENT_ID> \
  --resolver-cap <RESOLVER_CAP_ID> \
  --package <PACKAGE_ID> \
  --outcome 1 \
  --execute
All three IDs come from .binary-markets/registry.json. Outcome: 1 = YES, 2 = NO. The script calls settlement::mark_resolved(settlement, resolver_cap, outcome, clock, ctx) which:
  1. Asserts clock.timestamp_ms >= settlement.expiry_ms.
  2. Sets final_outcome.
  3. Emits MarketResolved.

Verify

curl -s http://localhost:8081/v1/binary-markets/<settlementId> | jq
# → finalOutcome: 1 (or 2)
Refresh EventMarketDetail. The hero gets a green/red RESOLVED YES/NO badge and the Redeem panel appears.

User redeem

UI: click Redeem X YES. PTB:
settlement::redeem_yes<DUSDC>(settlement, yes_coin, ctx) → Coin<DUSDC>
  → transferObjects(coin, sender)
Merges multiple YES coin objects into one before redeeming (single tx for the full basket). Losing-side coins are worthless. The frontend hides them from /positions for resolved markets to remove a misleading “redeem” CTA.

Settlement → dark pool vault

After binary-market:resolve fires, the next keeper tick that runs against a vault on that market flips to settlement mode and sweeps the V3 BM → vault → state == SETTLED. See Vault Deposit Flow step 4.