α = 0.3. Compared against per-asset, per-class thresholds.
Resolved through a 5-state FSM with asymmetric hysteresis so a noisy signal does
not produce noisy alerts.
Reading order
Intrinsic value
What the asset is supposed to be worth. Per-class definition (LST, stable, CDP, NAV, FX).
Market value
What you’d get swapping it. Jupiter routed quote, repriced via Pyth.
The spread
Formula, EWMA smoothing, per-asset thresholds, the 5-state FSM with hysteresis.
Honesty about limits
What we don’t model. Where the signal can lie. When to mistrust an alert.
Sources, in one table
| Source | Read by Pegana | Used for |
|---|---|---|
| Sanctum | sol_value per LST mint, every 15s | SOL-pegged LST intrinsic |
| Pyth | SOL/USD, FX crosses, Redemption Rate feeds | All USD conversion + yield-bearing NAV |
| Hylo (on-chain decode) | total_sol_cache.total_sol from Exchange PDA | hyUSD CDP collateral ratio |
| Jupiter | Best routed quote, USDC numeraire | Market value of every asset |
| Solayer / Piggybank | Mint-level rebasing rate / dashboard NAV | Sub-set of yield-bearing accounting |
crates/indexer-rs/src/sources/. One source per asset class is a
deliberate constraint — we do not “blend” prices.
The 5-state FSM, in one table
| State | Meaning | Alert? |
|---|---|---|
PEGGED | Spread inside the calm band | No |
DRIFT | Spread crossed the per-asset drift threshold | Yes |
DEPEG | Spread crossed depeg (2.00 – 5.00%) | Yes, urgent framing |
CRITICAL | Spread > 5.00% | Yes, Telegram urgent |
UNKNOWN | Source stale or low confidence | No (sticky) |
BLACK_SWAN for spreads beyond any historically-observed level — terminal until
human review.
Update cadence
- Indexers poll their sources every 15s (Sanctum, Solayer, Piggybank, Hylo, Jupiter)
- Pyth pushes via SSE — sub-second arrivals
- Engine recomputes on every source event, publishes to Redis + Postgres
- API snapshots are
<1sold; the WebSocket pushes within ~200ms of the engine - Alert delivery (Telegram / Webhook) fires within 1–3s of the state transition
How to verify
Every parameter — threshold, dwell time, EWMA α, source endpoint — is committed inassets.toml and
crates/engine-rs/src/config.rs.
The methodology is reproducible from raw inputs.
To inspect any asset’s live parameters: