Skip to main content

Bad debt

Bad debt is the strongest realised signal available. Audits, curator AUM and protocol age are proxies for expected safety; bad debt is money that was actually lost or is currently unrecoverable. Where it exists, it dominates the rating.

Two flavours, both counted:

  • Unrealised — debt currently backed by collateral worth less than the debt, which liquidation has not cleared. It signals a market that is broken now (stale oracle, illiquid collateral, uninterested liquidators). It may still be liquidated away.
  • Realised — loss already socialised to suppliers. Permanent, and a track record for that market's parameters and curator.

Normalise, then gate

Absolute USD is not a rating: $13,582 is catastrophic in a $495 market and noise in a $1B one. The metric is the ratio

R = (badDebtUsd + realizedBadDebtUsd) / size

But raw R explodes on abandoned dust — a dead market everyone withdrew from, leaving a tiny underwater remnant, produces ratios in the thousands of percent while threatening nobody. Two guards:

  1. Materiality gate. Rate as risky only if the market is either big enough to matter (size at least $50,000) or carries a large absolute loss (at least $100,000). Anything failing both is recorded as informational.
  2. Denominator floor. Divide by max(size, $50,000) so a near-zero denominator cannot manufacture an infinite ratio.

The rating table

ConditionScoreLevel
No exposure and no warning1green
Failed the materiality gate (dust or abandoned)2green
R below 0.5%2green
R from 0.5% to 5%3yellow
R from 5% to 25%4red
R at or above 25%5red

Floors:

  • A provider's own RED bad-debt warning floors the score at 4. Their threshold is corroborating evidence and is trusted as a lower bound. YELLOW is not floored — most yellows are dust.
  • Realised loss of at least $100,000 floors the score at 3, whatever the ratio. A permanent loss that happened is worth a mark even on a market that has since grown.

No time decay. Realised bad debt is cumulative on chain and is never decayed. Normalisation ages it naturally: as a market recovers and supply grows, R shrinks on its own, and a market that once took a loss and is now large and healthy drifts back toward green without special-casing.


Where the numbers come from

The concept is universal; the plumbing is not. Each protocol family exposes losses differently, and the risk unit follows the protocol's own socialisation model.

FamilyRisk unitSourceNotes
Morpho Bluemarket (collateral, loan) pairBlue API badDebt and realizedBadDebt, plus market warningsFirst-class. Losses are isolated to that market's suppliers and the vaults supplying it
Aave V3.3+ forksreserveon-chain getReserveDeficit(asset) against aToken supplyA deficit is debt burned at liquidation with no collateral left — realised, net of what the safety module already covered. Pre-3.3 pools have no first-class figure
Gearbox V3pool, via credit accountswalk creditManagers -> creditAccounts -> calcDebtAndCollateralNo deficit counter and no lostAssets: a pool counts every open loan as an asset, so an emptied credit account is only visible account by account. Bad debt is the summed shortfall of debt over collateral value
Euler Earn / MetaMorpho V1.1vaultlostAssets, and the gap between claimed assets and what the vault can point atSee NAV integrity in Vault risk

The Gearbox case is worth stating plainly, because it is the shape of failure that ordinary metrics miss entirely: a pool whose accounts have been emptied keeps reporting its old TVL at a share price that keeps rising, because interest accrues on debt nobody will ever repay.


Vault propagation

A vault inherits its suppliers' losses. Each vault's proportional exposure is its share of every market it supplies, summed:

R_vault = (vault badDebt + vault realizedBadDebt) / vaultTotalAssets

rated through the same table. This runs two ways for redundancy: the per-vault rating computed by the bad-debt pipeline, and a live figure from the vault's current allocation, with the worse of the two winning. The second path covers every vault we score, not only the ones the provider's own bad-debt data reaches.

One refinement: a vault flagged red purely by a provider warning with no measurable bad debt is capped at yellow and labelled differently. A red on this dimension always means bad debt someone can point at.


Composition

finalMarketScore = max(curatorMarketScore, badDebtScore)
finalLevel = worst(curatorLevel, badDebtLevel)

Observed failure dominates predicted safety. The curator score, the bad-debt score, the ratio and the warning level are all exposed alongside the result, so a downgrade can always be traced to the number that caused it.