Contract summary
Settlement price
Joyride’s oracle feed publishes a rolling 30-minute TWAP of the underlying index. When the expiry is processed, the most recent TWAP the exchange holds for that underlying is recorded as the settlement price. In the normal case that is the window ending at expiry (07:30:00 to 08:00:00 UTC for the standard round); if processing is delayed, it is the 30-minute window ending when the expiry is processed.
Every account on the same underlying and expiry settles against that price. The recorded value is authoritative and replayable.
Settlement is deferred only when the exchange holds no TWAP for the underlying at all; it then waits for the feed and retries, trading in the expiring round stays closed, and the next round does not open early. The feed reports how much of the window its samples cover, and the exchange compares that against a configured minimum, but a value below the minimum is logged and still used. The exchange does not check the age of the TWAP it holds.
Payoff
Each position settles at intrinsic value against the settlement priceS and strike K:
S = K) settles worthless for both calls and puts. Out-of-the-money positions settle at zero, i.e. the position is still closed and a settlement record is still issued, with a cashflow of zero.
What counts as one settled unit
Settlement acts on each fill. Every finalized, non-reverted fill at that expiry is valued independently and the results are then netted into one signed balance adjustment per account for the whole expiry, applied on chain to that account’s vault subaccount. A strategy (multi-leg) fill settles as its legs, each valued independently and netted per account. Because a fee is assessed per in-the-money leg, an offsetting pair of fills nets to zero cash but still contains one in-the-money leg. The clamp under Settlement fee bounds what that leg is charged.Settlement fee
The holder of an in-the-money (ITM) position pays a fee at expiry. The writer pays nothing at settlement. Out-of-the-money (OTM) positions pay nothing since intrinsic value is zero. The fee is the lesser of a rate on index notional and a cap on intrinsic value:ppm is the rate in parts per million of index notional. cap_bps is the cap in basis points of intrinsic value. Both come from your account’s fee tier; the standard tier sets the rate to 0.015% of index notional and the cap to 12.5% of intrinsic value. The tier values and their units are set out on Fees and Limits.
The cap keeps a barely-in-the-money position from owing more than it receives. It also covers the out-of-the-money case, since zero intrinsic gives a zero cap and therefore a zero fee.
What the fee is netted against
An account can hold in-the-money longs and owe on shorts settling together. The fee is clamped against the account’s net before fees,gross_cashflow_total, the sum of its legs’ gross cashflows for the expiry: an account that nets negative pays no settlement fee, and one whose net is smaller than its assessed total pays only the net.
Which rate applies
The rate and the account’s tier assignment are frozen when the expiry’s settlement price is recorded, and the whole expiry settles against that frozen pair. Settlement can span several transactions over several minutes; without the freeze, two accounts with identical positions could be charged different rates depending on which batch landed first. A rate change never unwinds fees already collected.Where the money lands
The fee is an on-chain transfer into the fee subaccount, carried inside the settlement transaction itself as the entry that makes the batch balance.Expiry sequence
Settlement is a transaction against the margin-vault program and waits for its inputs to be final on chain before moving any balance.- A settlement delay elapses after the expiry instant (default 60 seconds), giving the settlement price and the last on-chain fill finalizations time to land.
- Preconditions are checked. Every fill at that expiry must be finalized on chain (confirmed is not sufficient), and a settlement price must exist for every underlying involved. If either is missing, settlement waits and retries; a fill that could still be reorged away is not settled.
- The expiry is planned. Across every fill at that expiry and every underlying, the planner computes for each account: its net signed balance adjustment, the collateral lock to release, how many written positions close, and any shortfall. Fees are assessed per in-the-money leg and then clamped to the account’s expiry net.
- Entries are batched. Entries are ordered deterministically, payers first and then receivers, and chunked into
apply_settlementbatches sized to one Solana transaction. Payers land first so the fee subaccount always holds what the later receiver batches pay out. - Each batch is made self-balancing. A single entry against the fee subaccount closes the batch so that its balance adjustments sum exactly to its insurance draw. This is the same entry that collects the settlement fees.
- Batches are sent in order, each recorded durably as an intent before it is submitted. A batch is keyed
(expiry, batch_id)and guarded by an on-chain receipt, so re-submitting one is a no-op rather than a double settlement. - Landed batches are ingested. The chain watcher reads the per-entry effects and the batch summary back off chain: positions clear, collateral locks release, and fee attribution is marked confirmed.
- Anything that did not land is re-planned. A re-plan excludes accounts a prior batch already settled and never reuses the id of a batch that landed, so recovery converges on exactly one settlement per account. A batch that failed to land is re-sent under its own id with a new transaction.
Settlement records
There is no live message stream for settlement, and no API returns the settlement price, the per-account payout, or the settlement fee. The authoritative record is theapply_settlement transaction on chain, which carries, per account, the signed balance adjustment, the lock release, and the position count closed.
What a maker can read from the API after settlement:
GET /api/query/vault-subaccountshows the balance after the adjustment is applied.GET /api/query/rfq-positions?status=settledlists the positions the expiry closed.GET /api/query/rfq-fillslists the fills themselves; its rows carry no settlement fields.