Every market carries an on-chain price index: the protocol’s view of what one whole unit of the synth (1,000,000 tokens) is worth, denominated in lamports per unit. The index is launch-scaled: at launch, one unit is defined as worth 0.625 SOL, the launch curve’s migration price, and every push moves it proportionally with the collectible from there:
Two estimator pipelines, one launch-scaled index.Two estimator pipelines, one launch-scaled index.

Two estimator pipelines, one launch-scaled index.

The index therefore carries the collectible’s move since launch rather than its absolute price, which keeps premium, funding, the breaker, and CDP math on the same footing for every market, and seeds the AMM at zero premium at graduation. The index is the reference that everything else keys off: collateral checks, liquidations, and the funding rate that tethers the synth price.

Push oracle

The index is fed by a push oracle. The market’s price feed, a signed relayer service that reads the collectible’s real prices from marketplaces and filters manipulation (see Oracle Architecture), submits it with the push_index instruction, signed by the oracle authority key stored in the global config. No other signer can push. Each push carries a single price_lamports value for the whole unit, already launch-scaled by the feed. The first push at launch is 625_000_000 (0.625 SOL); for a collectible that has since doubled, the push is 1_250_000_000. Four gates apply before a push is absorbed:
  1. Not frozen: a frozen market refuses pushes entirely, so the index cannot be walked during a freeze. See Circuit Breaker.
  2. Non-zero: price_lamports > 0, otherwise the push is rejected.
  3. Rate limit: at least min_push_interval_secs must have elapsed since the previous push. The first push for a market is exempt.
  4. Circuit breaker: the push is compared against the current TWAP. If it deviates by more than breaker_bps, the market freezes instead of absorbing the value.

TWAP smoothing

Accepted pushes do not overwrite the index directly. The market stores two values:
  • index_last_raw: the most recent accepted observation, kept for transparency
  • index_twap: the smoothed index every risk check actually uses
Smoothing is a time-weighted EMA. Each accepted push pulls the TWAP toward the observation in proportion to how much time has passed, capped at the full window:
If the full window has elapsed since the last push, the TWAP lands exactly on the new observation. Rapid-fire pushes move it only fractionally, so no single print can jerk the index.
The very first push for a market seeds index_twap directly with the observed price. There is no history to average against yet, and most instructions refuse to run until an index exists.

What consumes the index

The index is the valuation leg for every solvency computation. Token amounts are converted to lamport value with:
(1e12 base units per whole unit, see The Synth Token.)
The AMM’s own price (the mark) never enters a collateral or liquidation check. Only the oracle index does. Manipulating the on-chain pool cannot force a liquidation; only the external market price, as reported through the smoothed and breaker-guarded index, can.

Staleness guard

An index is only as good as its freshness. Every market records index_last_ts, the time of the last accepted push, and when max_index_age_secs is set (non-zero), index-priced operations refuse to run against an index older than that:
  • open_short
  • withdraw_collateral when the position still has debt
  • accrue_funding
  • liquidate
A stale market returns IndexStale until the next accepted push, at which point everything resumes with no reset needed. Trading (curve and AMM), repay_burn, and add_collateral stay available throughout, so nobody is trapped: shorts can still de-risk, and holders can still exit through the pool. This bounds the damage of a dead relayer: prices stop being trusted after the configured age instead of being trusted forever. Set max_index_age_secs comfortably above the relayer’s push cadence (see Parameters); 0 disables the guard, which is only appropriate for testing.

Instruction and event surface

  • Instruction: push_index(price_lamports), oracle authority only, see Instructions
  • Emits IndexPushed { market, raw, twap } on absorption, or BreakerTripped { market, observed, twap } on a breaker hit, see Events
  • State fields: index_twap, index_last_raw, index_last_ts on the Market account
External-venue markets additionally receive an oracle-pushed mark price through push_mark, smoothed the same way over mark_window_secs. The mark only steers funding; it never enters collateral or liquidation math, which always use the index documented here.