MYRMIDONS
ALGORITHMIC STRATEGIES
← HOMEMYRMIDONS // DOCS
[ 04 // RISK ]

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

LLTVLIQUIDATION BONUSDROP 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%
Gold: the liquidation bonus, the most slippage a liquidator can absorb and still profit. Red: the drop from LLTV to an unprofitable liquidation. Ticks: the LLTVs the Morpho DAO allows.

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.

LOADING_RISK_API…
Latest capacity_ratio for the largest books (log scale). Right of the 1x line, the whole book clears in one sweep. Markets with no capacity row are not plotted.
▸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

LOADING_ARCHIVE…
Daily returns implied by the collateral's 30-day volatility, the tail beyond −3σ (about one day in 741 under that model), and the cutoff the gate uses. A cutoff beyond 3σ means the collateral has already had a worse day than the model expects.
  • ▸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

FAMILYMETRICSWHAT IT MEASURES
VOLATILITYrealized_vol_7d · realized_vol_30d · ewma_vol_30dAnnualized, from hourly collateral prices; the EWMA has a 7d half-life
DRAWDOWNmax_drawdown_30d · worst_window_7d_30dMax peak-to-trough decline and worst cumulative 7d window, 30d lookback
BUFFER BREACHbuffer_breach_freq_1h · buffer_breach_freq_6h · buffer_breach_freq_24hShare 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
UTILIZATIONavg_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_24hTime-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
CONCENTRATIONhhi · top1_supply_share · top3_supply_share · top1_borrow_share · top3_borrow_shareHerfindahl-Hirschman index of the lender book, and the share of each book held by its 1 and 3 largest addresses
RATESrate_spread_30dTime-weighted mean borrow-minus-supply APY over 30d
ORACLEdepeg_max_30d · depeg_spell_median_h · depeg_spell_p90_h · depeg_survival_24hMax oracle-vs-reference deviation and depeg spell statistics (|deviation| ≥ 5%)
LIQ CAPACITYcapacity_ratio · capacity_ratio_grouped · lif · max_slippage_usedThe 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
STATUSMEANING
okComputed
no_dataNo input for this market
insufficient_historyNot enough history for the window yet
no_route · no_priceCapacity only: no DEX route, or no price to size the sale
fee_exceeds_marginCapacity 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.

FIELDVALUESMEANING
kindoracle-resolved · oracle-custom · feed · oracle-broken · opaqueWhat the contract is. oracle-broken cannot price; opaque could not be identified
familymeta-deviation-timelock · curve-stableswap · constant-peg · customSpecial pricing mechanisms. A constant peg serves a hardcoded price
owner_statusnone · okok: an admin can change what the contract serves. This is the real risk surface
modtprimary · backup · threshold · timelocksDual-oracle wrapper: switches to the backup when the two disagree past the threshold for the timelock
shared_feed_marketsintegerHow many markets a broken upstream feed would hit at once
vendor_evidenceregistry · canonical-contract · code-signature · descriptionHow the feed's publisher was established (see below)
source_name · upstreamverified 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
curl -s https://api.myrmidons-strategies.com/v1/risk/index.json
EXAMPLE RESPONSE (TRUNCATED)
{
  "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
curl -s https://api.myrmidons-strategies.com/v1/risk/markets.json
EXAMPLE RESPONSE (TRUNCATED)
{
  "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
curl -s https://api.myrmidons-strategies.com/v1/risk/markets/0x0a2e456ebd22ed68ae1d5c6b2de70bc514337ac588a7a4b0e28f546662144036.json
EXAMPLE RESPONSE (TRUNCATED)
{
  "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
curl -s https://api.myrmidons-strategies.com/v1/risk/markets/0x0a2e456ebd22ed68ae1d5c6b2de70bc514337ac588a7a4b0e28f546662144036/history.json
EXAMPLE RESPONSE (TRUNCATED)
{
  "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
curl -s https://api.myrmidons-strategies.com/v1/risk/markets/0x0a2e456ebd22ed68ae1d5c6b2de70bc514337ac588a7a4b0e28f546662144036/history/hhi.json
EXAMPLE RESPONSE (TRUNCATED)
{
  "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
curl -s https://api.myrmidons-strategies.com/v1/risk/metrics/capacity_ratio.json
EXAMPLE RESPONSE (TRUNCATED)
{
  "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"
    }
  ]
}
$ man risk · this page in the terminal