phasis.
Phasis Docs
Protocol

Settlement & the Pyth oracle

How Phasis halts trading at expiry, reads the Pyth EMA price on-chain, and distributes intrinsic-value payouts to all accounts.

Settlement converts open positions into USDC payouts. It is fully on-chain and driven by the cranker keeper — no user action is required to receive a payout.

The settlement price

At expiry, the protocol needs one authoritative price for the underlying asset. Phasis reads the Pyth Lazer EMA price via the on-chain function:

pyth::get_ema_price_no_older_than(state, feed_id, max_age, clock)
ParameterValue
statePyth Lazer state shared object (see Addresses).
feed_idInteger feed ID: BTC = 1, ETH = 2, SUI = 11.
max_ageMaximum staleness in milliseconds (e.g., 3_600_000 for 1 hour). Aborts if the latest price is older.
clockSui shared clock (0x6).

The function returns a Price { price, conf, exponent }. The human-readable price is price × 10^exponent. For example, { price: 6_500_000, exponent: -2 } represents $65,000.

If the Pyth price is stale or unavailable, the cranker first attempts to read a settle price from the DeepBook Predict oracle (an on-chain SVI surface seeded from external IV data). The admin holds an emergency escape hatch to force-publish a settle price if both oracles are unavailable, but this path requires multi-sig authorization.

The seven-step crank sequence

Settlement proceeds in a fixed state-machine sequence. Each step is a separate on-chain transaction submitted by the cranker.

Step 1 — halt

Condition:  now ≥ expiry_ts − halt_window_ms
Transition: Market.state: Listed → Halted
Effect:     No new orders accepted for any series in this market.

The halt window is set at market creation (typically 60 minutes before expiry). This gives the oracle time to reach finality before positions are evaluated.

Step 2 — publish settle price

Condition:  Market.state = Halted
Transition: Market.state: Halted → Settling
Effect:     Market.settle_price = Pyth EMA price (or Predict oracle price)

The cranker calls auth_entry::cranker_settle_price (Pyth fallback) or auth_entry::cranker_settle_price_from_predict (primary path). Once the settle price is on-chain, it is immutable.

Step 3 — mark series settling

For each series in the market:

Effect:  SeriesRow.state: Active → RetiredAwaitingSettle
         SeriesRow.intrinsic_value = max(0, settle_price − strike)  [call]
                                   = max(0, strike − settle_price)  [put]

Intrinsic value is computed once and stored on-chain. Subsequent steps read this stored value; the oracle is not consulted again.

Step 4 — settle each user position

For each (account, series) pair with an open position:

For longs:  credit = position_qty × intrinsic_value
For shorts: debit  = position_qty × intrinsic_value
Applied to: Account.balance_quote

If an account's balance goes negative after the debit (undercollateralized), the protocol's fee pool covers the shortfall as bad debt. The position is removed from the account regardless.

Step 5 — retire series

Once SeriesRow.open_interest == 0 (all positions settled):

Effect:  Slot coin freed; slot returned to registry.free_slots for reuse.
         SeriesRow removed from Market.series_rows.

Step 6 — retire market

Once all series in the market are retired:

Transition: Market.state: Settling → Closed
Effect:     Market archived; new market for the next expiry can be listed.

Typical weekly timeline

For a BTC weekly market expiring Friday at 4:00 pm UTC:

Time (UTC)Event
Friday 3:00 pmCranker calls cranker_halt — market halted.
Friday 3:05 pmSettle price published (Predict or Pyth EMA).
Friday 3:05–3:30 pmCranker iterates all (account, series) pairs and settles positions.
Friday ~3:30 pmAll series retired, market closed.
SaturdayNew market listed for the following Friday expiry.

No user action required

Settled USDC lands directly in Account.balance_quote. Users can withdraw at any time after their positions are settled. The cranker handles the full sequence autonomously; users do not need to submit any transaction to receive their payout.

For the oracle feed IDs and shared object addresses used on testnet, see Addresses & object IDs.

Connect a Wallet

No Sui wallet detected in this browser.

Install Sui Wallet

Phasis supports any wallet that implements the Sui Wallet Standard.