Skip to main content

Overview

Scope: every score is computed per chain, from the Morpho markets that exist on whichever chain your wallet is connected to. Switching chains recomputes everything. The Fear & Greed Index is the one exception.

Data sources

SourceUsed for
Morpho Blue contracts (wagmi/viem)Market state: oracle, LLTV, totalAssets, totalBorrowAssets
Morpho REST APIBad debt fields, market metadata, 30-day historical APY
On-chain oracles + CoinGecko fallbackToken prices for borrower health-factor calculation
alternative.me Fear & GreedGlobal crypto sentiment widget (external)

Update cadence

Data refreshes every 5 minutes. The “Updated” pill in the page header reflects the wall-clock age of the last fetch. Important: every score on the Risk Dashboard is a heuristic for surfacing patterns. None of them are predictions, recommendations, or a substitute for reading market parameters yourself. Always verify before supplying, borrowing, or moving capital.

Page Header Metrics

Top-right of the dashboard. Four compact pills, scoped to the connected chain.
PillDefinition
MarketsCount of Morpho Blue markets with at least one supply position. Excludes empty markets.
TVLSum of totalMarketSize (USD) across those markets. Computed from on-chain totalAssets × loan-asset oracle price.
FlaggedSum of totalMarketSize (USD) for markets classified Medium or High risk. See Risk Tier Classification below.
UpdatedWall-clock age of the last data fetch (e.g. “32 sec ago”). Refreshes every 5 minutes.

Flagged TVL Banner

The wide banner near the top showing total flagged USD, percentage of chain TVL, and a Low / Medium / High breakdown. Flagged TVL is the USD sum of all markets where riskLevel !== "low". The breakdown chips show the same USD totals split by tier. The banner is not a liquidation predictor. A flagged market can remain healthy for months; an unflagged market can still suffer liquidations if its collateral price moves fast. The signal is “this market has structural properties that warrant extra attention,” not “this market is about to break.”

Risk Tier Classification

Every market gets one of three tiers. The full classification logic (defined in src/hooks/useMorphoMarkets.ts):
riskLevel:

= "low" if lltv >= 86 AND tvl > $10M AND marketAgeDays >= 90

​= "medium" if lltv >= 77 AND tvl > $1M AND marketAgeDays >= 30

​= "high" otherwise
In plain words:
  • Low risk: large, mature market with a conservative LLTV. The kind of market most users supply into.
  • Medium risk: mid-sized or younger market, or a slightly aggressive LLTV. Workable for experienced users who understand the parameters.
  • High risk: small or very new market, or aggressive LLTV. Treat as experimental.
LLTV thresholds (86% / 77%) reflect typical Morpho Blue templates. TVL and age thresholds are stability proxies: a large mature market has survived volatility, while a small new market hasn’t been tested yet.

Systemic Risk Score

The big gauge near the top, 0 to 100. A TVL-weighted composite of five signals across all markets on the connected chain.

Formula

Systemic = 0.25 · Volatility

 + 0.20 · UtilizationStress

 + 0.20 · LiquidationClustering

 + 0.20 · LiquidityConcentration

 + 0.15 · OracleDependency

Interpretation bands

RangeReading
0 to 32Healthy. Market parameters are spread out, oracles diversified, rates stable.
33 to 65Elevated. At least one component is straining. Check which one in the gauge breakdown.
66 to 100Stressed. Multiple components co-flag. Borrowing or supplying without reading market parameters is unwise.

Component: Volatility (weight 25%)

TVL-weighted standard deviation of borrowRate across markets, rescaled so 5 percentage-point std = 100.
std = weighted_std(borrowRate, weight = totalMarketSize)

Volatility = clamp((std / 5) × 100, 0, 100)
Approximates “how much do borrow rates disagree across markets.” When all markets converge to the same rate, volatility reads low. When rates spread out (some at 1%, others at 12%), it reads high.

Component: Utilization Stress (weight 20%)

TVL-weighted average of utilization across markets.
avg_util = weighted_mean(utilization, weight = totalMarketSize)

UtilizationStress = clamp(avg_util, 0, 100)
50% utilization → 50. 100% utilization → 100. High utilization means borrowers are using most available capital, raising rates and reducing withdrawal liquidity for suppliers.

Component: Liquidation Clustering (weight 20%)

Inverse TVL-weighted std-dev of the lltv - utilization buffer across at-risk markets (risk tier ≠ low). Rescaled so 10 pp std = 0 risk, 0 std = 100 risk.
at_risk = markets where riskLevel !== "low"

buffers = max(0, lltv - utilization) for each at_risk market​

std = weighted_std(buffers, weight = totalMarketSize)

LiquidationClustering = clamp(100 - (std / 10) × 100, 0, 100)
When buffers cluster tightly around a single value (low std), many positions sit at the same distance from liquidation. A small price move could cascade. Wider spread = healthier. Returns 0 when fewer than 2 at-risk markets exist (no clustering signal possible).

Component: Liquidity Concentration (weight 20%)

Share of total chain TVL held by the top 3 markets.
top3_tvl = sum(top 3 markets by totalMarketSize)

total_tvl = sum(all markets totalMarketSize)

LiquidityConcentration = clamp((top3_tvl / total_tvl) × 100, 0, 100)
If three markets hold 90% of chain TVL, that 90 reads as concentrated systemic exposure: a problem in any of them would dominate the chain.

Component: Oracle Dependency (weight 15%)

Share of total chain TVL secured by the single most-used oracle address.
by_oracle[address] = sum(totalMarketSize where oracle = address)

top_oracle_tvl = max(by_oracle.values)

OracleDependency = clamp((top_oracle_tvl / total_tvl) × 100, 0, 100)
If one oracle secures 70% of TVL, a feed outage would impact 70% of capital. Diverse oracle adoption reads lower.

Fear & Greed Widget (External)

This widget shows the alternative.me Crypto Fear & Greed Index, updated daily. It reflects global crypto market sentiment, not Dynamo or Morpho specifically. Same value regardless of which chain you’re on. The score combines volatility, market momentum and volume, social media, dominance, and Google Trends signals. Values 0 to 24 read as Extreme Fear, 25 to 49 Fear, 50 to 54 Neutral, 55 to 74 Greed, 75 to 100 Extreme Greed. We display it as a complement to the Morpho-specific Protocol Heat below.

Protocol Heat (Internal Sentiment)

Dynamo’s own 0-to-100 sentiment score, computed from the markets on the connected chain only. Switching chains changes this; it reflects Morpho activity on that specific chain.

Formula

ProtocolHeat = 0.30 · UtilizationComponent

 + 0.25 · BorrowApyComponent

 + 0.20 · WarningComponent

 + 0.25 · RiskDistComponent
UtilizationComponent = 100 - weighted_mean(utilization, by tvl)

 (higher util → less greedy available capital → lower score)

BorrowApyComponent = 100 - clamp((weighted_mean(borrowRate) / 8) × 100, 0, 100)

​ (rates above 8% read as saturation)

WarningComponent = 100 - (warned_markets / total_markets) × 10

 (where warned = m.verified === false)

RiskDistComponent = (low_tier_tvl / total_tvl) × 100

 (share of TVL in healthy markets)

Labels

RangeLabel
0 to 19Extreme Fear
20 to 39Fear
40 to 59Neutral
60 to 79Greed
80 to 100Extreme Greed
Why two sentiment scores? The external Fear & Greed reflects the broader crypto market’s mood. Protocol Heat tells you whether Morpho lending activity on this chain is in a hot or cold cycle. The two often diverge (e.g. macro Fear plus Morpho Greed when rates spike during a sell-off).

Liquidations Panel (Per-Market)

When you select a market in the per-market section, four numbers are shown.

LLTV (Liquidation Loan-to-Value)

Pulled directly from the Morpho Blue market struct as a percentage. The maximum borrow position size relative to collateral value before liquidation is allowed.

Liquidation Penalty (LIF)

Computed from LLTV using the Morpho Blue Liquidation Incentive Factor formula:
β = 0.3 (CURVE_STEEPNESS)

LIF_MAX = 1.15 (15% cap)

LIF = min(LIF_MAX, 1 / (β · LLTV + (1 − β)))

penalty (%) = (LIF − 1) × 100
Worked examples:
LLTVPenalty
86%4.38%
91.5%2.62%
96.5%1.06%
Higher LLTV markets have lower penalties (closer to 100% allowed leverage). The penalty is what liquidators pocket above the debt they cover; the position holder forfeits it as a haircut on their collateral.

Realized Bad Debt

Cumulative bad debt that has been written off and socialized across the market’s lenders. Pulled from Morpho API field Market.realizedBadDebt { underlying, usd }. Example: if a liquidation fails to fully cover a borrower’s debt (collateral insufficient even after the penalty), the protocol absorbs the gap. That gap, written off the books, accumulates into Realized Bad Debt. Healthy markets show $0 here. Non-zero realized bad debt is a signal that liquidations have happened and not been fully covered in the past.

Unrealized Bad Debt

Currently underwater debt that is still on the books: a borrower’s collateral is worth less than what they owe, but the loss has not been written off yet. Pulled from Morpho API field Market.badDebt { underlying, usd }. Unrealized rising without realization usually means liquidators have not yet stepped in (either because penalties are insufficient, gas costs exceed the bonus, or liquidator bots are missing the chain).

Health Factor (Per-Position)

For each borrower position on a selected market, Health Factor is computed on-chain at oracle price:
maxBorrow = (collateral × oraclePrice / ORACLE_PRICE_SCALE) × LLTV / WAD

HF = maxBorrow / borrowAssets
Interpretation:
Health FactorReading
HF > 2.0Healthy buffer
1.5 to 2.0Moderate buffer
1.0 to 1.5Stress zone (small price move could trigger liquidation)
HF ≤ 1.0Liquidatable
The Stress Zone metric below tracks the percentage of top borrowers in the 1.0 to 1.5 band.

Per-Market Analysis Metrics

In the “Drill Down” section, after selecting a market, the dashboard shows the following per-market signals.

30-Day APY Trend

A sparkline of borrow APY over the trailing 30 days, sourced from Morpho API historicalState.borrowRate. Values are rescaled to 0-100% if the API returns 0-1 fractions.

Percentage-Point Change

Absolute change between the first and last points of the 30-day window:
ppChange = last_point.y - first_point.y

APY Anomaly (z-score)

Z-score of the latest APY observation against the trailing window (excluding the latest):
mean = average(window)

std = stddev(window)​

z = (latest - mean) / std
|z| > 2 is flagged as an anomaly in the Actionable Insights. Returns null when std = 0 or the window has fewer than 7 points (insufficient signal).

30-Day Trend Direction

Up, down, or flat between the first and last points:
flat if |last − first| < max(|first| × 0.005, 0.001)

up if last > first

down if last < first
The 0.5% threshold avoids flagging noise.

Liquidation Clusters

Groups of borrowers whose health factors fall within ±5% of each other. Each cluster shows count, average HF, and total collateral exposure.
Sort borrowers by healthFactor ascending.

For each borrower b:

If b.HF ≤ groupAnchor × 1.05: add to current cluster

Else: emit cluster if size ≥ 2, start new cluster
A “critical cluster” (used by the Actionable Insights) has count ≥ 3 and avgHF < 1.3. Intuition: when three or more positions are stacked near liquidation, a small adverse price move can cascade them all at once.

Stress Zone Percentage

Share of valid borrower positions with HF < 1.5:
stress_zone (%) = (count where HF < 1.5) / (count of valid HF) × 100
Quick scan of how exposed the borrower base is to a moderate price move.

Actionable Insights

The dashboard surfaces up to 5 ranked insights from a five-rule library, sorted by severity (critical > warning > info) then by exposure size.
#RuleSeverityTrigger
1Borrow pressure risingWarningMarket has utilization > 85% AND borrow APY > 4%.
2Liquidation cluster formingCriticalSelected market has a cluster with count ≥ 3 AND avgHF < 1.3.
3Oracle concentration riskCriticalTop single oracle address secures > 50% of TVL on the chain.
4Safer alternative availableInfoHighest-TVL high-risk market has a sibling low-risk market with the same collateral/loan pair.
5APY anomalyWarningSelected market has |z-score| > 2 (latest APY > 2σ from 30d mean).
Multiple rules can fire on the same chain. The list is capped at 5 items; ties are broken by exposure (USD weight).

Data Cadence & Freshness

MetricRefreshSource
Markets list, TVL, utilization, LLTV5 minMorpho Blue contracts via wagmi/viem
Bad debt, market metadata, historical APY5 minMorpho REST API
Borrower health factors, oracle prices5 minOn-chain reads
Fear & Greed (external)Dailyalternative.me API
The “Updated” pill in the page header shows the age of the last fetch in human-readable form.

What This Dashboard Is Not

  • Not a liquidation predictor. Flagged TVL and at-risk tier classification are structural heuristics, not price models. We do not estimate the probability that a specific market will be liquidated.
  • Not financial advice. Every score is a pattern-surfacing tool. Read the underlying market parameters (LLTV, oracle, curator, liquidity) before transacting.
  • Not exhaustive of all on-chain risk. Smart-contract bugs, oracle manipulation, governance attacks, and cross-protocol composability risks are not captured by any score on this page.

Glossary

TermDefinition
LLTVLiquidation Loan-to-Value. The maximum debt position size relative to collateral value before liquidation is allowed.
Health Factor (HF)Ratio of max-allowed-borrow to actual-borrow. HF > 1 = healthy; HF ≤ 1 = liquidatable.
UtilizationtotalBorrowAssets / totalAssets. The share of supplied capital currently borrowed.
TVLTotal Value Locked. Sum of totalAssets × loan-asset price, in USD.
Bad DebtDebt position whose collateral has dropped below the owed amount. Unrealized = still on books; Realized = written off and socialized to lenders.
OracleThe price feed contract Morpho consults to value collateral. Each market specifies its own oracle address.
LIFLiquidation Incentive Factor. The bonus liquidators receive for closing underwater positions. Penalty = (LIF − 1) × 100%.
Source-of-truth lives in the repo at src/lib/risk.ts, src/hooks/useRiskMetrics.ts, src/hooks/useMarketRiskAnalysis.ts, src/hooks/useActionableInsights.ts, and src/pages/RiskDashboard.tsx. The implementation is the spec; this page is its translation into plain language.