RiskState on its Market account. The keeper writes it with each price push (update_risk_state_v2). The state sets two surcharges, one on the fee and one on the confidence band, and decides whether mint and redeem are open at all. A separate staleness gate freezes mint and redeem when pushes stop, most often because the underlying market has closed.
On devnet, every market runs in
ProxyMode all the time, by design. ProxyMode means the program prices off the keeper-pushed user_twap_price instead of reading a Pyth account. Normal is the mainnet steady state, where mint and redeem read Pyth directly.The states
Stress blocks both sides because allow_mint_in_stress and allow_redeem_in_stress default to false, and both are false on all markets, 14 when checked on 10 Oct 2026 and 13 live now. The market authority can turn either on with configure_risk_fees. A mint in Stress is then also held to stress_mint_cap per transaction. That cap is 0 (no cap) on every market.
Fee and confidence multipliers
Each state multiplies the market’s posted fee and its confidence band. Both multipliers are surcharges on top of the posted values, and every live setting is 1× or more.
These are the defaults, and the values on every live market as of 10 Oct 2026. The market authority sets the fee multipliers with
configure_risk_fees and the confidence multipliers with configure_worst_case_quoting. The confidence multiplier applies only where worst-case quoting is on; see NAV math.
On devnet the 1.5× fee multiplier always applies: QQQ posts an 18 bps fee and is charged 27 bps.
The Recovery decline is linear and starts when the market enters Recovery. The program sets risk_state_updated_at only when the state changes, so later pushes in Recovery don’t restart the clock. The keeper holds Recovery for an hour after leaving Stress, so the surcharge is back to 1× by the time the keeper moves the market to its next state.
Transition rules
The on-chain transition matrix stops a compromised keeper from skipping recovery:Stress can only move to Recovery (or stay in Stress). A direct Stress → Normal or Stress → ProxyMode jump is rejected, which would otherwise drop the surcharge from 3× straight away. Every other transition is allowed: ProxyMode and Recovery move freely, and Normal can be entered from any state except Stress. Each push is also capped on price (a 25% move limit); see Oracle.
The staleness chain (off-hours behavior)
Risk states describe the oracle’s quality. A separate chain handles its absence, most often when the underlying market closes for the night or the weekend:twap_updated_at, so the freeze lasts exactly as long as the keeper withholds. While frozen, mint and redeem revert in every state except Normal, the bin books, which fill only while the price is stale outside Normal, trade against free-float books, and committed orders can’t settle; the keeper refunds each one about 5 s after its 180 s TTL. The first accepted push at reopen re-anchors NAV. The full chain is on Oracle.
If you only check one thing before you submit a mint or redeem, check market.twap_updated_at.
What you should do in each state
ProxyMode (devnet)
Operate normally. Fees carry the 1.5× surcharge, and quotes carry a 1.5× confidence markup on both legs, usually a few bps. If you run a bot, remember that a mint or redeem needs a push no more than 300 s old.
Stress
Mint and redeem are blocked by default (MintNotAllowedInStress, RedeemNotAllowedInStress). Committed orders still fill while the keeper pushes prices, and the bin books open once the price is more than 300 s old. If you build a UI, say so:
“QQQ is in Stress mode. Minting and redeeming are paused; you can still trade QQQL and QQQS.”
Recovery
Mint and redeem reopen. Fees and confidence markups start at 3× and fall evenly to 1× over the first hour.
Reading risk state
Normal, the price age is the authoritative “will my transaction go through” signal.
State during maintenance
For a hard halt, the market authority setsmarket.is_active = false with update_market. Mint and redeem then revert (MarketNotActive), and so does commit_swap (MarketInactive). pool_swap doesn’t check the flag, so the books still fill while the price is stale, and settle_swap refunds the orders of a paused market; after the TTL anyone can send cancel_swap to refund an order, whatever the state.
Read more
Oracle
The price source, the push pipeline and the staleness chain in full.
Solvency
What the program enforces independently of risk state.

