Docs›Vault Risk Intelligence
Webacy continuously scores 2,800+ DeFi vaults across Ethereum, Arbitrum, Base, Optimism, Polygon, and BSC. Every vault gets a composite risk score, a listing verdict, real-time withdrawal signals, and a 90-day history.
Every vault receives a listing_verdict — a clear signal for teams deciding whether to integrate, list, or accept a vault as collateral. It's computed from the composite risk score plus hard blocking conditions, updated with every data refresh.
| Verdict | When | What it means |
|---|---|---|
| Safe to list | Score < 30, no blocking flags | Structurally sound with no critical findings — suitable for listing or integration. |
| Caution | Score 30–54 | Moderate structural risk — list with active monitoring and exposure limits. |
| Review required | Score 55–74 | Elevated risk — manual security review recommended before proceeding. |
| Do not list | Score ≥ 75 or blocking flag present | Critical structural issue — do not list. Blocking flags: redemption_closed, dormant, unverified. |
Available via GET /api/vaults → listing_verdict field on each vault item.
The withdrawal_risk field tells you how freely users can exit a vault right now. For Morpho vaults, utilization is fetched live every ~5 minutes, so this signal reflects actual on-chain liquidity — not yesterday's data.
Redemptions are disabled at the contract level. No withdrawals possible.
Lockup period > 7 days. Funds cannot be withdrawn until the lockup expires.
Morpho utilization > 95%. Most assets are currently borrowed — partial exits available, full exit requires waiting for borrowers to repay.
Morpho utilization 85–95%. Partial liquidity available; large withdrawals may fail.
Withdrawal delay or timelock is set. Exits require a waiting period before execution.
Several signals are fetched live at request time and overlaid on top of nightly pipeline data. This means the dashboard reflects current on-chain conditions, not just yesterday's snapshot.
| Signal | Source | Freshness | Coverage |
|---|---|---|---|
| Share price | DeFiLlama coins API | ~5 min | ~18% of vaults (those with DEX liquidity) |
| Morpho utilization rate | Morpho Blue GraphQL | ~5 min | All Morpho vaults |
| Vault score (utilization) | Recomputed from live utilization | ~5 min | All Morpho vaults |
| Withdrawal risk level | Live utilization + stored flags | ~5 min | All vaults |
Every vault detail page includes a 90-day score sparkline so you can see whether a vault is improving, degrading, or stable over time. The delta badge shows the score change vs 30 days ago.
History endpoint: GET /api/vaults/[chain:address]/history — returns up to 90 snapshots.
last_share_price is the vault token price in USD. For yield-bearing vaults — sDAI, sUSDe, Yearn, Fluid — the share price legitimately drifts above $1 as yield accumulates. This is expected behaviour, not a risk signal. Depeg flags only fire when the price falls meaningfully below par.
The composite score (0–100) is a weighted sum of sub-scores. Higher = riskier. The score feeds directly into the listing verdict and tier.
| Sub-Score | Weight | What it measures |
|---|---|---|
| Protocol risk | 15% | Trading Strategy label: Blacklisted / Severe / Dangerous / High / Unknown |
| Closed liquidity | 12% | Deposits or redemptions currently closed — curator-intentional vs utilization-driven distinguished |
| Centralization | 12% | EOA owner, pause capability, admin key concentration, strategy manager |
| Code | 10% | Contract verification + audit count. Unverified: +65 sub-score. Zero audits: +30. Each audit: −15 reduction (cap −30). See thresholds below. |
| Upgrade risk | 10% | Proxy upgradeability, beacon patterns, delegatecall |
| Utilization | 10% | Market utilization rate — nonlinear; ≥95% functionally locks users out (live for Morpho) |
| Strategy | 5% | External strategies, leverage complexity, nesting |
| Depeg | 5% | Active share price loss signal; hard state floors supplement |
| Asset quality | 5% | Collateral classification — USR collapse was an asset-layer failure |
| Looping | 4% | Recursive lending exposure — cascade amplifier during depeg events |
| Oracle | 3% | Oracle type quality, TWAP vs spot, price deviation |
| Maturity | 3% | Vault age < 6 months |
| Webacy code risk | 2% | Reentrancy, unchecked calls, malicious external calls |
| Audit recency | 3% | Time since last security audit — 4 tiers: Fresh (<6mo) → 5, Moderate (6-18mo) → 10-30, Aging (18-36mo) → 30-60, Stale (>3yr) → 70. Reputable firm bonus: −10 (≥1 firm), −20 (≥3 firms). |
| Size | 2% | Low TVL = fragility and lower liquidity buffer |
| TVL outflow | 2% | Capital flight signal from negative TVL trend |
morpho_liquidity = 0 (markets are liquid), both utilization and utilisation_risk sub-scores are zeroed to avoid double-penalizing deployment rate as a withdrawal risk.perp_dex_trading_vault; a share price below $0.99 is expected behavior, not a depeg signal.morpho_liquidity = 0, both utilization and utilisation_risk sub-scores are zeroed. Detected via ts_feature_tags (euler_earn_like, pendle_*).event_count reflects user-facing deposit/withdraw events, not keeper harvest() calls. Inactivity and dormant flags are suppressed for vaults with architecture = "strategy" to avoid false positives from programmatic allocators. Harvest inactivity is scored separately via days_since_harvest using graduated tiers: < 30 days → no penalty; 30–60 days → +10 penalty, harvest_slow flag; 60–90 days → +25 penalty, harvest_stale flag; ≥ 90 days → full inactivity penalty, harvest_dormant flag. When days_since_harvest is null (data unavailable), the harvest penalty is suppressed entirely.Each vault receives a letter grade (A–F) derived from its composite risk score. Grades are the inverse of risk — A is safest, F is most dangerous. The expected capital-at-risk ranges are calibrated against historical DeFi exploit loss data.
Letter grades align with risk tiers: A maps to Low, B spans Low/Medium, C spans Medium/High, D maps to High, and F maps to Critical. Thevault_grade field is available on all vault records alongside the numeric vault_score (0–100).
Each vault is assigned a monitoring_status derived from TVL and trend data. Legacy and deprecated vaults are hidden by default in the dashboard (toggle with 'Show legacy (N)').
| Status | Condition | What it means |
|---|---|---|
active | TVL ≥ $500K and no severe trend decline | Fully monitored and shown by default |
watch | TVL $100K–$500K OR TVL dropped >50% in 90d | At-risk; shown by default but flagged |
legacy | TVL < $100K | Effectively dead capital; hidden by default |
deprecated | Protocol officially shut down | Hidden by default |
Every vault output includes an actionability_class that identifies the dominant risk driver and returns a targeted one-line action recommendation. The class with the highest weighted average sub-score wins.
| Class | Key sub-scores | Example action |
|---|---|---|
smart_contract | Protocol risk (40%), Code (20%), Audit recency (10%), Oracle (10%), Asset (10%), Webacy code (10%) | "Reduce position: elevated code or protocol risk warrants caution." |
liquidity_lock | Closed liquidity (50%), Utilization (30%), Utilisation risk (10%), Exit liquidity (10%) | "Exit now: liquidity is critically constrained." |
governance | Centralization (40%), Upgrade (30%), Strategy (15%), Governance behavior (15%) | "Reduce position: centralization or upgrade risk is elevated." |
market_conditions | Depeg (35%), Looping (25%), TVL outflow (20%), Size (10%), Maturity (10%) | "Reduce exposure: market or collateral conditions are deteriorating." |
actionability_class, actionability_action, actionability_detail, and actionability_class_scores fields are all available in the API output.Flags highlight specific structural issues. Blocking flags force a Do not list verdict regardless of score.
unverifiedredemption_closeddormantdepegyield_trapemergency_deposit_capshared_collateral_exposureexchange_rate_spikeexchange_rate_crasherc4626_donation_riskthin_collateral_markethigh_loopinglooping_lock_riskoracle_gap_riskcollateral_depeg_riskno_auditseoa_ownerpause_capableupgradeableunaudited_upgraderecent_upgraderepeated_pausingownership_transferconcentrated_borrowerconcentrated_depositorbad_debt_exposureliquidation_proximity_risklow_exit_liquidityhigh_market_concentrationmorpho_low_liquidityreward_dependent_yieldnegative_returnlockup_7dwithdrawal_delaydeposit_closeddeposit_cap_reachedlow_tvlnew_vaultinactiveharvest_slowharvest_staleharvest_dormantcollateral_frozen_alertsubvaultlarge_redemption_alertERC-4626 vaults accumulate yield slowly — a 15% APY vault moves ~0.04% per day. A sudden large movement in the exchange rate is a direct indicator of an attack in progress or structural failure.
| Signal | Threshold | Scoring Impact | Pattern |
|---|---|---|---|
exchange_rate_spike | > +2% since last checkpoint | Hard floor at 70 (critical boundary) | Donation attack — assets transferred directly into vault inflate convertToAssets() without minting shares. Venus wUSDM: 65% jump → $902K bad debt (Feb 2024). |
exchange_rate_crash | > −1% since last checkpoint | Hard floor at 65 (high tier) | Exploit in progress, collateral collapse, or bad-debt crystallisation. Yield vaults should never go down for stablecoins. |
Previous price is persisted across pipeline runs. No external API required — uses the share price already fetched by the Trading Strategy enrichment.
When an ERC-4626 vault is used as collateral in a lending protocol and that protocol prices it via convertToAssets(), the vault becomes vulnerable to a donation attack: an attacker transfers assets directly into the vault contract (without calling deposit()), inflating the exchange rate without minting new shares. The lending protocol's oracle reads the inflated rate and allows overborrowing against the manipulated collateral.
convertToAssets() as its price oracle with no TWAP or manipulation protection. ~$902K bad debt generated from a $350 initial deposit.collateralAsset in ≥ 1 active Morpho market. Queried via Morpho Blue GraphQL at scoring time.erc4626_donation_risk = true → +15 additive penalty + erc4626_donation_risk flag. This is a latent (pre-exploit) structural risk; pair with exchange rate velocity for real-time detection.Every 6 hours, Webacy scans 24 hours of on-chain Withdraw events across 600+ vaults (TVL ≥ $500K) to detect concentrated exits before they appear in price data. A vault is flagged when a single wallet redeems more than $500K or more than 1% of vault TVL within the lookback window.
| Chain | Lookback window | Data source |
|---|---|---|
| Ethereum | 24h | Alchemy (primary) → Etherscan V2 (fallback) |
| Arbitrum | 2h (high-frequency chain) | Etherscan V2 → Moralis (fallback) |
| Base | 24h | Etherscan V2 → Moralis (fallback) |
| Optimism | 24h | Etherscan V2 → Moralis (fallback) |
| Polygon | 24h | Etherscan V2 → Moralis (fallback) |
| BSC | 6h | Etherscan V2 → Moralis (fallback) |
large_redemption_alert risk flag and expose four fields: large_redemption_count_24h, large_redemption_usd_24h, large_redemption_max_pct_tvl, and large_redemption_wallets. Each alert run is archived to S3 at vaults/redemption-alerts/{date}/{timestamp}.json.| Source | What we use | Cadence |
|---|---|---|
| Trading Strategy API | TVL, risk tier, lifetime return, share price, max drawdown, volatility, looping %, flags | Every 6h |
| DeFiLlama coins API | Live vault token prices (share price) | ~5 min — live overlay |
| DeFiLlama protocols API | Audit records for protocol-level coverage | Every 6h |
| Morpho Blue GraphQL | Live utilization rate, available liquidity, net APY, curator, timelock, collateral addresses | ~5 min — live overlay |
| Aave V3 GraphQL API | Live reserve composition across all 8 supported chains — active collateral, frozen reserves, paused markets. Primary collateral source for Aave wrapper vaults; fallback to DeFiLlama if unavailable | Every 6h (pipeline) |
| Moralis analytics API | 24h DEX buy+sell volume per collateral token (primary source for thin_collateral_market detection) | Every 6h |
| Etherscan V2 (unified) | Bytecode, source code, proxy detection, upgradeability, events; Withdraw event scanning for large redemption alerts | Per-vault + every 6h (redemptions) |
| Webacy API | Contract vulnerability findings, deployer risk, code analysis | Per-vault (pipeline) |
Every vault includes a risk_summary field — a one-sentence plain-English explanation of why the vault scored the way it did. Generated deterministically from the top weighted sub-score contributors and highest-priority active flags. No LLM required.
Available as risk_summary on every vault record. Useful for surfacing in alerts, reports, and API consumers without additional processing.
Additional fields returned on every vault record. These fields feed into the scoring pipeline and are exposed in the API response for consumers that need to inspect data freshness, vault architecture, or audit provenance directly.
| Field | Type | Description |
|---|---|---|
data_as_of | ISO 8601 timestamp | When this vault was last scored and enriched by the pipeline. Used in the UI as a staleness indicator — an amber ⚠ badge appears when the timestamp is more than 48 hours old. Useful for API consumers to detect stale records before acting on them. |
ts_feature_tags | string[] | Trading Strategy feature tags for the vault architecture (e.g. euler_earn_like, pendle_pt, yearn_v3_like). Used internally to apply architecture-specific scoring rules — for example, utilization zero-out for EulerEarn and Pendle vaults, and depeg suppression for Pendle PT vaults. See Architecture-specific scoring rules above for how each tag affects scoring. |
last_audit_date | ISO date string | Date of the most recent security audit on record (sourced via DeFiLlama protocols API and manual curation). Drives the graduated audit recency sub-score: Fresh (<6 months) → 5, Moderate (6–18 months) → 10–30, Aging (18–36 months) → 30–60, Stale (>3 years) → 70. null when no audit date is available. |
audit_firms | string[] | Names of the audit firms that have reviewed this protocol (e.g. Trail of Bits, OpenZeppelin, Spearbit, Pashov). Reputable firms with audits within the last 12 months apply up to a −20 reduction to the audit recency sub-score. An empty array means no audit firms are on record — equivalent to no_audits for scoring purposes. |
auditor_tier | "top" | "mid" | "low" | null | Quality tier of the auditors on record for this protocol. top — elite security firms (Trail of Bits, OpenZeppelin, Spearbit, Certora, ChainSecurity). mid — established firms (Halborn, PeckShield, Hacken, Quantstamp). low — entry-level or less established firms. null when no auditor data is available. Shown as a badge in the Security Indicators panel on vault detail pages. |
days_since_harvest | integer (nullable) | Days since the vault's last harvest() keeper call. Populated from last_harvest_at in Trading Strategy data. Used to apply graduated harvest inactivity penalties for strategy/keeper vaults (Yearn V2/V3, Harvest, etc.): < 30 days → no penalty; 30–60 days → +10, harvest_slow; 60–90 days → +25, harvest_stale; ≥ 90 days → full inactivity penalty, harvest_dormant. null when unavailable — harvest penalty is suppressed when data is absent. |