Skip to main content
NAV (Net Asset Value) is what each long and short token is worth in cUSDC, at the protocol layer. It is what you pay to mint, what you receive to redeem, and what the keeper anchors pool prices to.

The two formulas

user_twap_price is the on-chain TWAP from the oracle program, updated by the keeper roughly every 15 seconds. initial_l_price and initial_s_price are set at market initialization and never change. γ is the volatility-decay scalar (s_gamma_index / 1e9), 1.0 unless the keeper has marked the short leg down — see Volatility decay. While γ = 1.0 the trailing factor is a no-op and these are the plain constant-product NAVs. For QQQ at launch: initial_l_price = 480, initial_s_price = 1. So if L_NAV = 528 (QQQ moved +10%), then S_NAV = 480 × 1 / 528 = 0.909.

Why constant-product

The relationship L_NAV × S_NAV = initial_l × initial_s is invariant by construction. This produces several useful properties:
  1. Pair value is bounded. L_NAV + S_NAV is minimized at L_NAV = S_NAV = √(initial_l × initial_s) (the geometric mean) and grows as either side moves away. There is no scenario where the pair value collapses to zero.
  2. No funding rate needed. In a perp DEX, funding redistributes from longs to shorts (or vice versa) when one side is over-popular. Continuum doesn’t need this - the constant-product NAV does the redistribution automatically through reciprocal NAV movement. If everyone holds L, S becomes cheap, and any new mint on the popular side is dilutive in NAV terms.
  3. Short side can never go negative. As L_NAV → ∞, S_NAV → 0. A holder of S can lose 100% of their position but never owe more.
  4. Long side has unbounded upside. No cliff, no liquidation; if the underlying 100xs, the L side 100xs.

Computing paired position value

For a position holding n_L long tokens and n_S short tokens:
For a position minted from mint_amount cUSDC at the time of minting:
So at mint time, the position value equals mint_amount × (1 - mint_fee_bps / 10_000) - i.e., your deposit minus fees. Trivially.

How position value moves with the underlying

Take a 100 cUSDC mint at QQQ = 480 (initial_l = 480, initial_s = 1, mint fee = 10 bps):
Now QQQ moves to some new price P. New NAVs:
Position value:
Some sample values: Note: a paired position has near-zero delta locally - it’s a curved zero-coupon. The pair becomes valuable only at large moves in either direction. To take a directional view, sell one leg.

Volatility decay

The short-leg γ-index. All of the pair’s convexity lives in the short leg: L_NAV = P is linear (d²L/dP² = 0), while S_NAV = K/P is convex (d²S/dP² = 2K/P³ > 0). The protocol is the counterparty to that convexity, so it is structurally short volatility on the short side. To charge for that, the keeper can post a decay scalar γ = s_gamma_index / 1e9 that marks the short NAV down:
  • Ratchet-down only. The on-chain set_s_gamma_index instruction rejects any value above the current γ, and clamps to a floor of 0.5 (at most 50% cumulative decay). γ can never be raised to retroactively restore short claims.
  • It charges realized variance, not direction. The keeper decays γ by the realized per-cycle variance (Δγ/γ ≈ σ²), so a choppy path costs the decay while a smooth directional move barely does — the directional payoff lives in the untouchable long leg. This banks the choppiness-convexity the protocol is short as collateral surplus.
  • It is not a funding rate. There is no periodic cash transfer between holders. γ is a structural mark on the short token’s value; an instant mint→redeem round-trip is unaffected at a fixed γ, and long positions never pay it. The frontend surfaces it on the short side as “volatility decay,” deliberately not “funding.”
  • Default 1.0 (off). Until the keeper posts a value (CLMM_GAMMA_DECAY_ENABLED, off by default), s_gamma_index reads as 1e9 and every formula above reduces to the plain constant-product NAV.
See Solvency for why this only covers the variance regime and not a directional run. The relevant fields on the Market PDA:
To read NAV from a client:
The 6-decimal scaling means lNav.toNumber() / 1e6 gives a human-readable price.

TWAP and risk-state effects on NAV

The TWAP is what the user-facing flow uses. There’s also a keeper TWAP (shorter window) used internally for arb decisions. They derive from the same observation buffer in the oracle program but with different windows. When the oracle’s risk state is not Normal, the mint-redeem program applies a worst-case quoting markup to mint pricing. This is bounded by oracle_confidence (also stored on the market) and a state-specific multiplier: Redeem prices are not marked up - only mint. (Otherwise users would be stranded when the oracle goes shaky.) Risk states explained

When TWAP is zero

On a freshly initialized market, user_twap_price = 0 until the keeper has pushed enough observations to populate the TWAP window (default 5 observations / ~75 seconds). During this window:
Mints during the boot window use the initial prices. Once TWAP populates, NAV becomes price-responsive.

Edge: oracle stale or paused

If last_oracle_update is past the staleness threshold, the oracle’s OracleHealth flips to Passive, and the mint-redeem program rejects new mints (OraclePriceUnavailable). Existing redeems still work, but at the last-fresh NAV - see Risk states. NAV is what the protocol mints/redeems at. Book price is what the native per-side CLMM book trades at between repositions - the two are kept close by structure, not by arbitrage. The keeper re-pins each book’s base to NAV whenever drift exceeds the per-market gate (20-40bps), and the standing half-spread means the book never quotes inside NAV ± spread anyway. In steady state, book_price ≈ NAV ± half_spread. During closed market hours the oracle withholds pushes and the books float - the gap can widen, and the first fresh print re-anchors everything. A user choosing a venue picks by size and urgency:
  • Small size, urgent: hit the book (pool_swap) - instant, pays the bin ladder’s real spread.
  • Large size: commit an order - fills at the next oracle print at NAV ± 10bps, any size.
  • Want the pair, not a direction: mint or redeem at NAV (pays the mint/redeem fee, no spread).
Trading venues Continuum’s frontend overlays NAV on a TradingView chart. The long-side book price is shown directly; the short-side is derived from the long side via the constant-product invariant for visual coherence (otherwise two charts that should be inverse appear unrelated). When you read the S book programmatically, you get its actual base price.