the risk engine.
MNEMON records what happens; the risk engine estimates what can go wrong. Every hour it runs METRON's estimators on the archive for each market and publishes the results as a versioned static API. Terms are defined in the glossary.
LIQUIDATION CAPACITY
Lenders are safe only if liquidators act. A Morpho liquidator repays a borrower's debt and receives collateral worth LIF times that debt; LIF depends on the market's LLTV alone. The extra, the bonus, is what pays for selling the collateral. At high LLTV the bonus is small, and so is the price drop before a liquidation stops paying.
LIF = min(1.15, 1 / (0.3 · LLTV + 0.7)) // Morpho Blue liquidation incentive factor
bonus = LIF − 1 // what a liquidator earns per unit of debt repaid
insolvency_drop = 1 − LLTV · LIF // price drop from LLTV to an unprofitable liquidation
| LLTV | LIQUIDATION BONUS | DROP TO INSOLVENCY |
|---|---|---|
| 62.5% | 12.7% | 29.6% |
| 77% | 7.4% | 17.3% |
| 86% | 4.4% | 10.2% |
| 91.5% | 2.6% | 6.1% |
| 96.5% | 1.1% | 2.5% |
capacity_ratio is the share of a market's whole borrow that liquidators could clear at a profit in one sweep, at current DEX and HyperCore liquidity. At 1.0 or more the whole book clears. Far below 1.0, a large liquidation event stalls and lenders absorb the shortfall. capacity_ratio_grouped is the stress case: every market with the same collateral sells into the same liquidity at once.
▸How capacity is computed
maxSlippage = (1 − 1/LIF) − haircut // what a liquidator can absorb
capacity = max sellable within maxSlippage // DEX quotes + HyperCore book depth
capacity_ratio = (capacity / LIF) / total_borrow // debt cleared per unit of debt
▸MNEMON's LIQUIDATABLE gate, step by step
The gate asks whether the debt one bad day would push into liquidation can be sold at a profit. A position at health factor HF is liquidated after a price drop of 1 − 1/HF.
σ_daily = vol_30d_annualized / √365 // from the archive's hourly prices
cutoff = max(3 · σ_daily, worst observed 1-day drop) // one bad day for this collateral
at_risk_debt = Σ debt where 1 − 1/HF < cutoff // positions a bad day liquidates
gate slippage(first rung ≥ at_risk_debt) ≤ 0.8 · bonus // Relay quote, refreshed hourly
- ▸A volatile or noisily priced collateral has a high cutoff, which can pull most of a book into the debt at risk.
- ▸No DEX route at that size counts as zero capacity. A quote that is missing is UNVERIFIED and fails the gate the same way.
METRIC FAMILIES
| FAMILY | METRICS | WHAT IT MEASURES |
|---|---|---|
| VOLATILITY | realized_vol_7d · realized_vol_30d · ewma_vol_30d | Annualized, from hourly collateral prices; the EWMA has a 7d half-life |
| DRAWDOWN | max_drawdown_30d · worst_window_7d_30d | Max peak-to-trough decline and worst cumulative 7d window, 30d lookback |
| BUFFER BREACH | buffer_breach_freq_1h · buffer_breach_freq_6h · buffer_breach_freq_24h | Share of the last 30 days in which the collateral fell through the whole cushion (1 − LLTV) within 1h, 6h or 24h. Drops only. Catches the fat tail that volatility hides |
| UTILIZATION | avg_util_7d · avg_util_30d · occupancy_below_kink_30d · time_at_utilization_95_30d · time_at_utilization_99_30d · util_spell_median_h · util_spell_p90_h · util_spell_survival_24h | Time-weighted mean utilization (7d/30d), time below the IRM kink, time above 95% and 99%, and u ≥ 0.95 spell statistics with Kaplan-Meier survival |
| CONCENTRATION | hhi · top1_supply_share · top3_supply_share · top1_borrow_share · top3_borrow_share | Herfindahl-Hirschman index of the lender book, and the share of each book held by its 1 and 3 largest addresses |
| RATES | rate_spread_30d | Time-weighted mean borrow-minus-supply APY over 30d |
| ORACLE | depeg_max_30d · depeg_spell_median_h · depeg_spell_p90_h · depeg_survival_24h | Max oracle-vs-reference deviation and depeg spell statistics (|deviation| ≥ 5%) |
| LIQ CAPACITY | capacity_ratio · capacity_ratio_grouped · lif · max_slippage_used | The liquidation-capacity row, also projected as standalone metrics |
Each name is an endpoint (see API). Every value carries an as_of timestamp, a status and its model version. A failed computation is a row with a null value, never a missing key.
▸Status values
| STATUS | MEANING |
|---|---|
| ok | Computed |
| no_data | No input for this market |
| insufficient_history | Not enough history for the window yet |
| no_route · no_price | Capacity only: no DEX route, or no price to size the sale |
| fee_exceeds_margin | Capacity only: the swap fee alone exceeds the liquidator's margin, so capacity is zero |
ORACLE IDENTITY
Every market carries an oracle block: what the oracle is, who can change it, and how many other markets read the same feeds. Morpho oracles are immutable, so MNEMON probes each one once on-chain; the block has no history.
| FIELD | VALUES | MEANING |
|---|---|---|
| kind | oracle-resolved · oracle-custom · feed · oracle-broken · opaque | What the contract is. oracle-broken cannot price; opaque could not be identified |
| family | meta-deviation-timelock · curve-stableswap · constant-peg · custom | Special pricing mechanisms. A constant peg serves a hardcoded price |
| owner_status | none · ok | ok: an admin can change what the contract serves. This is the real risk surface |
| modt | primary · backup · threshold · timelocks | Dual-oracle wrapper: switches to the backup when the two disagree past the threshold for the timelock |
| shared_feed_markets | integer | How many markets a broken upstream feed would hit at once |
| vendor_evidence | registry · canonical-contract · code-signature · description | How the feed's publisher was established (see below) |
| source_name · upstream | verified contract name · [{getter, address}] | The verified contract name, and the feeds an adapter reads |
Oracles built on a derived price (an ERC4626 exchange rate, a Curve LP, a Pendle PT, a hardcoded peg) differ from spot by design. Their deviation is marked STRUCT and never flagged as a depeg.
▸How a vendor is established
A vendor is named only from evidence that copying an interface cannot fake: the publisher's own feed registry (Chainlink, RedStone), or an adapter that points at the publisher's official contract (Pyth, Stork, API3). A feed that only describes itself as a brand gets a null vendor; the site shows the claimed brand with a '?'. Custom oracles get their verified contract name from Sourcify, which sets their family (Curve LP, Pendle PT, Oval wrapper).
API
STABLE BY CONTRACT. Fields are only ever added, never changed or removed. Pin the model_version you validated against.
Rebuilt every hour at :40 UTC. Markets are keyed on (chain_id, market_id).
DISCOVERY INDEX
Start here: market ids, the metric catalog (description, unit, params), the endpoint templates, and per-metric freshness.
curl -s https://api.myrmidons-strategies.com/v1/risk/index.json
{
"generated_at": "2026-08-20T13:40:01Z",
"markets": ["0x0a2e456ebd…", "…"],
"metrics": {
"hhi": {
"description": "Herfindahl index of the lender book.",
"unit": "index_0_1",
"params": { "window_days": 30, "weights": "supply_assets" }
},
"…": "…"
},
"freshness": {
"hhi": {
"latest_as_of": "2026-08-20T10:00:00Z",
"expected_as_of": "2026-08-20T12:00:00Z",
"fresh": false
},
"…": "…"
},
"endpoints": { "index": "/v1/risk/index.json", "…": "…" }
}ALL MARKETS
Every market's latest values and capacity row in one document. Poll this for a dashboard: one request per hour covers everything.
curl -s https://api.myrmidons-strategies.com/v1/risk/markets.json
{
"generated_at": "2026-08-20T13:40:01Z",
"markets": {
"0x0a2e456ebd…": {
"chain_id": 999,
"liq_capacity": {
"as_of": "2026-08-20T09:00:00Z",
"capacity_ratio": 6.4235,
"capacity_ratio_grouped": 0.00427,
"lif": 1.0262,
"max_slippage_used": 0.0175,
"status": "ok"
},
"metrics": {
"buffer_breach_freq_1h": {
"as_of": "2026-08-20T10:00:00Z",
"value": 0.0,
"status": "ok"
},
"…": "…"
}
},
"…": "…"
}
}ONE MARKET
One entry of markets.json, plus its provenance (model_versions, metron_version, schema_version).
curl -s https://api.myrmidons-strategies.com/v1/risk/markets/0x0a2e456ebd22ed68ae1d5c6b2de70bc514337ac588a7a4b0e28f546662144036.json
{
"market_id": "0x0a2e456ebd…",
"chain_id": 999,
"liq_capacity": {
"capacity_ratio": 6.4235,
"capacity_ratio_grouped": 0.00427,
"status": "ok"
},
"metrics": {
"hhi": {
"as_of": "2026-08-20T10:00:00Z",
"value": 0.99999,
"status": "ok"
},
"…": "…"
},
"model_versions": ["api-v0.2.0+metron-v1.3.0"],
"metron_version": "1.3.0"
}MARKET HISTORY
One market's full history, grouped by metric. params and input_window describe the latest point; older points can predate a model_version change.
curl -s https://api.myrmidons-strategies.com/v1/risk/markets/0x0a2e456ebd22ed68ae1d5c6b2de70bc514337ac588a7a4b0e28f546662144036/history.json
{
"market_id": "0x0a2e456ebd…",
"chain_id": 999,
"metrics": {
"buffer_breach_freq_1h": {
"params": {
"lltv": 0.915,
"buffer": 0.085,
"buffer_formula": "one_minus_lltv",
"lookback_d": 30,
"sampling": "hourly_last"
},
"input_window": {
"start": "2026-07-21T10:00:00Z",
"end": "2026-08-20T10:00:00Z"
},
"points": [{ "as_of": "…", "value": 0.0, "status": "ok" }, "…"]
},
"…": "…"
}
}METRIC HISTORY
One metric for one market, oldest point first. Points are hourly since 2026-08-20 and daily before.
curl -s https://api.myrmidons-strategies.com/v1/risk/markets/0x0a2e456ebd22ed68ae1d5c6b2de70bc514337ac588a7a4b0e28f546662144036/history/hhi.json
{
"market_id": "0x0a2e456ebd…",
"chain_id": 999,
"metric": "hhi",
"params": {
"weights": "supply_assets",
"snapshot": "latest_at_or_before_as_of_within_30d"
},
"points": [
{ "as_of": "2026-08-20T09:00:00Z", "value": 0.99999, "status": "ok" },
{ "as_of": "2026-08-20T10:00:00Z", "value": 0.99999, "status": "ok" }
]
}ONE METRIC, ALL MARKETS
One metric across every market, to rank or screen them. The capacity fields (capacity_ratio, capacity_ratio_grouped, lif, max_slippage_used) work here too.
curl -s https://api.myrmidons-strategies.com/v1/risk/metrics/capacity_ratio.json
{
"metric": "capacity_ratio",
"source": "liq_capacity",
"generated_at": "2026-08-20T13:40:01Z",
"markets": [
{
"market_id": "0x0309c02dab…",
"as_of": "2026-08-20T09:00:00Z",
"value": 0.0000664,
"status": "ok"
},
{
"market_id": "0x039503b630…",
"as_of": "2026-08-20T09:00:00Z",
"value": 0.0,
"status": "fee_exceeds_margin"
}
]
}