> 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/for-operators/monitoring.md).

# Monitoring & Alerts

> v1 monitors the **Phoenix** position and Ember margin.

The ksUSD vault is one PDA — most monitoring reduces to watching that account plus a few external signals.

***

## Key metrics

| Metric                                  | Source                                                                   | Alert when                                                                                        |
| --------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| Share price (`share_price_1e9`)         | Derived from `effective_nav_usdc / total_shares`                         | Drops > 2% in 24h, or > `emergency_close_dd_bps` from `peak_share_price_1e9`                      |
| `cached_nav_usdc` vs. computed-live NAV | On-chain vs. off-chain reconciliation against Phoenix / Kamino positions | Discrepancy > 1%                                                                                  |
| Pyth SOL/USD staleness                  | Last-update timestamp on the Pyth feed                                   | > 5 min                                                                                           |
| Pyth confidence                         | `confidence / price`                                                     | > 1.5% (program reverts at 2%)                                                                    |
| jitoSOL/SOL depeg                       | Derived from `jitosol_oracle.price / sol_oracle.price`                   | > 80% of `lst_depeg_bps`                                                                          |
| `cached_nav_usdc` cap utilization       | `cached_nav_usdc / deposit_cap_usdc`                                     | > 90% (raise cap or pause new deposits)                                                           |
| `position_mode`                         | `vault.position_mode`                                                    | `Parked` (`Idle`) for > 24h while funding signal is active                                        |
| `position_base_amount`                  | `vault.position_base_amount`                                             | Drifts > 1% from expected (1× of the jitoSOL spot leg)                                            |
| `funding_apr_smoothed_bps` staleness    | `now - funding_smooth_last_ts`                                           | Approaching `funding_max_staleness_seconds`                                                       |
| `consecutive_dd_settles_observed`       | `vault.consecutive_dd_settles_observed`                                  | ≥ 1 (single-tick warning before lethal)                                                           |
| Perp-venue health factor                | Phoenix trader-account margin                                            | < 1.5                                                                                             |
| SOL-PERP funding rate                   | Phoenix `PerpAssetMap`                                                   | Sustained across `normal_thresh` past dwell                                                       |
| Pending withdrawals                     | `queue_next_id − queue_processed_through`                                | > 0 for more than one keeper cycle                                                                |
| Reserve fund                            | `reserve_fund_usdc` and `reserve_lent_kamino`                            | Reserve ATA empty while `reserve_fund_usdc > 0` (means `unlend_reserve` needed before any payout) |
| Lending balances                        | `usdc_lent_kamino`, `reserve_lent_kamino`                                | Sudden drop without a matching `unlend_*` event = Kamino-side anomaly                             |
| `vault.paused`                          | bool                                                                     | Unexpected `true` = investigate `LstDepeg` or admin action                                        |
| `vault.position_mode == WindDown`       | enum                                                                     | Terminal — only `claim_wind_down` should run                                                      |

***

## Reconciliation

Once per cycle, an off-chain script should compute the "true" NAV by summing:

1. Vault USDC ATA balance
2. `usdc_lent_kamino × kamino USDC reserve cToken exchange rate` (lent vault USDC, current value)
3. `reserve_fund_usdc` (already includes `reserve_lent_kamino` per the vault's accounting)
4. `(jitoSOL spot holdings) × Pyth jitoSOL price` — the unlevered spot leg (normal basis only)
5. Phoenix trader-account margin balance — posted USDC margin + settled funding + accrued PnL

Compare against `vault.cached_nav_usdc`. A discrepancy > 1% means:

* `settle` is overdue, **or**
* `attest_nav` is needed to capture unrealized PnL

***

## Emergency conditions

| Signal                                                                                | Response                                                                       |
| ------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Pyth SOL/USD stale > 10 min OR confidence > 2%                                        | Pause new deposits + positions; manual `emergency_close` if a position is open |
| jitoSOL depeg > `lst_depeg_bps`                                                       | `settle` auto-pauses; investigate and either unpause or emergency-close        |
| Phoenix outage / market halted                                                        | Same — pause and investigate                                                   |
| NAV drawdown ≥ `emergency_close_dd_bps` for `consecutive_dd_settles_required` settles | Anyone can call `emergency_close` permissionlessly; keeper should do it first  |
| `position_mode == WindDown`                                                           | Stop the keeper; broadcast `claim_wind_down` instructions to depositors        |

***

## Suggested external infra

* A serverless function (Cloudflare Workers / AWS Lambda) running every 5 min: fetch `vault` + Pyth + Phoenix trader account, compute the deltas, push to Grafana / Datadog / PagerDuty.
* A `program.addEventListener` consumer that subscribes to `DepositEvent`, `WithdrawEvent`, `WithdrawalRequested`, `WithdrawalProcessed`, `FeesCollected`, `PositionOpened`, `PositionClosed`, `NavAttested`, `IdleLent`, `IdleUnlent`, `ReserveLent`, `ReserveUnlent`, `WindDownInitiated`, and writes to a database for audit / reporting.
* A page in the operator dashboard tying `cached_nav_usdc` to the reconciliation script's live computation, with a visible delta and an "attest now" button that calls `attest_nav` when the delta crosses an internal threshold.

***

## Related

* [Keeper bot](/for-operators/keeper-bot.md) · [Admin operations](/for-operators/admin-ops.md)
* [Events](/for-developers/events.md) · [Errors](/for-developers/errors.md)
