> For the complete documentation index, see [llms.txt](https://docs.keystonefi.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.keystonefi.xyz/how-it-works/volatility-risk-management.md).

# Risk Management

> **Note.** v1 hedges on Phoenix Perps (USDC margin via Ember, jitoSOL held unlevered as the spot leg).

How the ksUSD vault handles volatility, slippage, and oracle stress.

**NAV** below is the total dollar value of everything the vault holds. A **settle** is a routine update anyone can trigger that refreshes the vault's numbers from the venues it uses.

***

## Built-in protections

| Layer                       | Mechanism                                                                                                                                                            | Default                               |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| **Liquidity buffer**        | Idle USDC kept on-vault for instant withdrawals                                                                                                                      | 10% of NAV                            |
| **Drawdown guard**          | `emergency_close` callable by anyone once `(peak − current) / peak ≥ emergency_close_dd_bps` AND `consecutive_dd_settles_observed ≥ consecutive_dd_settles_required` | 5% NAV drop, sustained 2 settles      |
| **Mode-switch dwell**       | Minimum time between mode changes to prevent ping-pong on noisy funding                                                                                              | 12 h                                  |
| **Funding EMA + staleness** | Smoothed funding on-chain; opens revert if stale                                                                                                                     | 6 h staleness                         |
| **Drawdown latency**        | Two consecutive sub-threshold settles required before drawdown trips                                                                                                 | `consecutive_dd_settles_required = 2` |
| **Slippage cap**            | Jupiter swaps revert if executed price worse than `max_swap_slippage_bps`                                                                                            | 0.5%                                  |
| **Oracle staleness**        | Pyth feed must have an update within the staleness window                                                                                                            | 5 min                                 |
| **Oracle confidence**       | Pyth `confidence / price` must be tight                                                                                                                              | < 2%                                  |
| **LST depeg check**         | `settle` auto-pauses if `jitoSOL / SOL < 1 − lst_depeg_bps`                                                                                                          | 5%                                    |
| **NAV change cap**          | `attest_nav` delta bounded per hour                                                                                                                                  | ±10%/hr                               |
| **HWM monotonicity**        | Performance fees can't be charged twice on the same gains                                                                                                            | Always                                |
| **Deposit cap**             | Total NAV cap to bound systemic exposure during early operation                                                                                                      | $500k at launch                       |
| **Reserve fund**            | Loss-absorbing buffer fed by 5% of perf fees, lent on Kamino                                                                                                         | Grows over time                       |
| **Wind-down path**          | Terminal admin instruction that blocks new state and switches users to pro-rata claim                                                                                | Manual                                |
| **Minimum margin**          | `open_position` rejects a position that posts less margin than this at the venue                                                                                     | ≥9% of deployed capital               |
| **Margin ceiling**          | `add_margin` refuses to post more than half of effective NAV to the venue                                                                                            | 50% of NAV                            |
| **Margin top-up**           | Keeper adds collateral when health falls, restoring it before liquidation                                                                                            | Automatic                             |

"EMA" above is an exponential moving average, a running average that weights recent readings more heavily. The vault uses one to smooth the funding rate so a single odd hour can't move the decision.

***

## On stress events

### Funding spikes (e.g. FTX-style)

In extreme conditions hourly funding can spike deeply negative. It hit −235% APR in Nov 2022. The smoothed funding rate and the dwell timer stop the vault from flipping on one bad sample, so it waits for a sustained signal.

In v1 the vault simply parks through deeply negative funding. It closes the short and holds USDC lending instead of chasing the move. Parking is the safer response and still earns.

### jitoSOL depeg

`settle` reads both Pyth feeds. If `jitoSOL/SOL` falls below `1 − lst_depeg_bps`, it reverts with `LstDepeg` and pauses the vault. Any existing position stays open, but nothing new can be opened. The admin then investigates and either unpauses or calls `emergency_close`.

### Oracle outage

The Pyth staleness and confidence checks make every strategy instruction that needs a SOL/USD price revert. Deposits and instant withdrawals don't read the oracle at all, so those keep working through a brief outage.

### Phoenix outage / market halt

Strategy instructions fail at the point where they call into Phoenix. Open positions keep accruing funding, since the venue settles that internally, and the next `settle` refreshes NAV. If a position has to be exited urgently, `emergency_close` can run as soon as the market can be read again.

### Sharp SOL rally

**The vault is not levered.** Its total exposure equals its NAV, and the short is sized 1:1 against the jitoSOL it holds — that 1:1 is what makes the book neutral in the first place. A SOL rally can't hurt the portfolio.

It can still hurt the *position*, because the two legs sit in different places. Only about 9% of NAV is posted at Phoenix as margin; the rest of what backs that short is the jitoSOL held here in the vault, which Phoenix cannot see. So on a rally the short's loss eats visible margin while the exactly offsetting jitoSOL gain sits somewhere outside Phoenix's accounting. From the venue's point of view the position looks thinly collateralised, and its liquidation engine acts on its own view — closing a position that was never economically at risk, and turning a paper wash into a real loss.

The drawdown guard cannot catch this. `emergency_close` triggers on NAV falling, and NAV *doesn't* fall in a hedged rally — the legs offset. The vault reads healthy right up to the moment Phoenix liquidates.

So the keeper watches it directly. The `margin-health` duty runs every tick, right after `settle`, and moves USDC into Phoenix margin when the cushion thins — funded by the leg that is gaining at that same moment. Every top-up is bounded twice: it can never draw on the withdrawal buffer, and total posted margin can never exceed half of effective NAV.

Margin only moves one way. There is no instruction that takes collateral back off a live position — surplus returns when the position closes, which the vault does on its own at the next mode flip. That costs a little yield while it sits, and buys the guarantee that nothing in the system can under-collateralise a live short.

This is an active defence rather than a static cushion, so **it depends on the keeper running.** If auto-margin is off or the keeper is down, the position should be closed rather than left to sit. Thresholds and the measured move sizes behind them: [keeper bot](/for-operators/keeper-bot.md#the-keeper-moves-margin-autonomously) and [instructions](/for-developers/instructions.md#why-margin-is-its-own-instruction).

### NAV reconciliation drift

If a keeper-reported NAV would move more than `max_nav_change_bps_per_hour` in one step, `attest_nav` reverts with `NavChangeExceedsCap`. The keeper then stages several smaller updates across consecutive hours. An outsized jump is a signal to investigate, not something to push through.

***

## What's *not* protected

* **Residual price risk. The hedge is near-zero, not zero.** The vault is delta-hedged by design, but four things stop the offset being exact:

  * **jitoSOL is not SOL.** The spot leg is jitoSOL and the short is SOL-PERP, so the two only cancel while the jitoSOL/SOL ratio behaves. A depeg is a direct loss; a 5% move trips the auto-pause, and the loss lands on NAV rather than on a reserve — the reserve fund is not depeg cover and is not sized to be (see the whitepaper).
  * **Delta drifts between rebalances.** The short is sized when the position opens. Price moves after that leave the book slightly long or short until the keeper resizes it.
  * **Staking accrual is deliberately unhedged.** jitoSOL appreciates against SOL as staking accrues — that appreciation *is* the yield — so a short sized against SOL never covers it. The vault carries a small, intentional net long as a result.
  * **The perp can trade away from spot.** Mark and index diverge, especially under stress, and the position is marked against the perp.

  None of this is large in normal conditions, and the backtest's −0.268% max drawdown is measured through a real funding compression. But "no price risk" would be the wrong claim, and it is not the one made here.
* **Smart-contract bugs.** The program is unaudited until the planned pre-mainnet audit. Don't deploy significant capital until the results are published.
* **Counterparty insolvency.** A critical exploit or a compromised upgrade key at Phoenix, Ember, Kamino, Marginfi, Jupiter, or Jito would flow straight through into NAV losses.
* **Black-swan slippage.** The modeled max drawdown of **−0.268%** counts funding only, because the backtest doesn't simulate the price impact of trading the perp leg during rebalances. A realistic worst month under stress is **−2% to −5%**. The reserve fund cushions that but doesn't remove it.
* **Regulatory action.** A jurisdiction restricting access to Solana DeFi could squeeze redemption liquidity for affected users.

***

## Related

* [Security model](/reference/security.md)
* [NAV & share pricing](/reference/nav-calculation.md) · [Whitepaper — Risk](/reference/whitepaper.md#risks)
