Morpho Blue is not a pool. It is a single contract holding thousands of
isolated markets, each one a tuple: a collateral token, a loan token, an
oracle, an interest-rate model, and a liquidation LTV. Nothing is shared
between them, which changes what a number means.
Bad debt is realized, and published
In Aave, a shortfall sits on the protocol’s books until
governance deals with it. In Compound v3, the protocol
absorbs it into its own reserves.
In Morpho, when a liquidation exhausts a borrower’s collateral and debt
remains, that remainder is written off against that market’s suppliers,
immediately, and the Liquidate event carries the amount. That is the
figure a lender in an isolated market actually needs, and it is the headline
of the tracking page.
The pattern in the data is worth seeing: bad debt clusters in markets with
volatile collateral at high LLTVs, and barely appears in the blue-chip ones.
That is the design working as intended: the losses stayed where they were
taken.
Why nothing is added up
Every market names its own oracle, and we have not replicated them. So an
amount is reported in that market’s own tokens and never converted to dollars.
That is a deliberate refusal twice over:
- Adding a WETH to a USDC to reach a headline figure would be an invention.
- Summing across isolated markets would misdescribe the protocol. A shortfall
in one market is borne by its suppliers and by nobody else, so a
protocol-wide total answers a question nobody in Morpho is exposed to.
An amount whose token we cannot identify is left at zero rather than scaled by
a guessed number of decimals: being wrong by a factor of 10¹² looks entirely
plausible in a table.
Where the market list comes from
Markets are read from the chain’s own CreateMarket events, which carry the
full parameters, so the registry needs no contract calls to be built. rake
morpho:markets:verify re-checks a sample against idToMarketParams on the
contract anyway: a decoding this load-bearing should be confirmed rather than
trusted.
How current the table is
Extended every night at 03:55 UTC, after the Aave and Spark runs, resuming
from the newest liquidation stored and stopping 64 blocks behind the head.
The market registry is re-read from CreateMarket events on each run, so a
market created yesterday is known tonight. A run that finds the warehouse
busy is recorded as skipped and the next night covers the gap; see
liquidations for the rule every nightly extraction
follows.
What isn’t here
Health factors and a position panel, which the health factors
guide covers for Aave. Morpho’s borrowing capacity is per market against a
per-market oracle, so the Aave replay does not carry over; it would need each
market’s oracle replicated first, which is the same reason there are no dollar
figures.
Coverage and the CSV
The page’s coverage card reads the persisted statement of the last nightly
extraction: every liquidation is in the table whatever its tokens, and the
exclusion counted is rows whose token decimals were unknown, which are stored
as zero rather than scaled by a guess. The CSV of the newest liquidations,
amounts in each market’s own tokens, opens with the same lines as #
comments and needs the Data subscription. See
health factors for what a coverage statement is.