get_defi_health
Assess DeFi ecosystem health by analyzing total TVL, trends, top chains, protocols, health scores, revenue patterns, and concentration risks.
Instructions
Assess DeFi ecosystem health: total TVL, TVL trends, top chains and protocols, health score, revenue trends, and ecosystem concentration risk.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/get-defi-health.ts:9-126 (handler)The handler function `getDefiHealth` retrieves DeFi market data (TVL, chains, protocols, fees), processes it into a health report, and caches the result.
export async function getDefiHealth(cache: CacheService): Promise<DefiHealthOutput | ErrorOutput> { const cached = cache.get<DefiHealthOutput>(CACHE_KEY); if (cached) return cached.data; try { const [historicalTvl, chains, protocols, feesResult] = await Promise.allSettled([ getHistoricalTvl(), getChains(), getProtocols(), getFees(), ]); // Total TVL and changes let totalTvl = 0; let tvlChange24h = 0; let tvlChange7d = 0; if (historicalTvl.status === 'fulfilled') { const data = historicalTvl.value; if (data.length > 0) { totalTvl = data[data.length - 1].tvl; if (data.length > 1) { const yesterday = data[data.length - 2].tvl; tvlChange24h = yesterday > 0 ? ((totalTvl - yesterday) / yesterday) * 100 : 0; } if (data.length > 7) { const weekAgo = data[data.length - 8].tvl; tvlChange7d = weekAgo > 0 ? ((totalTvl - weekAgo) / weekAgo) * 100 : 0; } } } // TVL trend const tvlTrend = classifyTvlTrend(tvlChange7d); // Top chains let topChains: ChainTvl[] = []; if (chains.status === 'fulfilled') { const sorted = chains.value.sort((a, b) => b.tvl - a.tvl).slice(0, 10); const totalChainTvl = sorted.reduce((s, c) => s + c.tvl, 0); topChains = sorted.map(c => ({ name: c.name, tvl_usd: c.tvl, tvl_change_7d: 0, // Not directly available from chains endpoint dominance_percentage: totalChainTvl > 0 ? Math.round((c.tvl / totalChainTvl) * 10000) / 100 : 0, })); } // Top protocols let topProtocols: ProtocolTvl[] = []; if (protocols.status === 'fulfilled') { topProtocols = protocols.value .sort((a, b) => b.tvl - a.tvl) .slice(0, 10) .map(p => ({ name: p.name, tvl_usd: p.tvl, category: p.category ?? 'Unknown', change_7d: p.change_7d ?? 0, })); } // Protocol revenue trend let revenueTrend: RevenueTrend = 'stable'; if (feesResult.status === 'fulfilled' && feesResult.value.protocols) { const topFeeProtocols = feesResult.value.protocols .filter(p => p.total24h !== null && p.total7d !== null) .slice(0, 10); if (topFeeProtocols.length > 0) { const avgDaily = topFeeProtocols.reduce((s, p) => s + (p.total24h ?? 0), 0) / topFeeProtocols.length; const avgWeeklyDaily = topFeeProtocols.reduce((s, p) => s + ((p.total7d ?? 0) / 7), 0) / topFeeProtocols.length; if (avgWeeklyDaily > 0) { const ratio = avgDaily / avgWeeklyDaily; if (ratio > 1.2) revenueTrend = 'growing'; else if (ratio < 0.8) revenueTrend = 'declining'; } } } // Ecosystem concentration const topChainDominance = topChains.length > 0 ? topChains[0].dominance_percentage : 0; const concentration: EcosystemConcentration = topChainDominance > 70 ? 'dangerous' : topChainDominance > 40 ? 'concentrated' : 'healthy'; // Health score const healthScore = calculateHealthScore(tvlChange7d, topChainDominance, revenueTrend); const guidance = generateDefiGuidance(tvlTrend, healthScore, concentration, revenueTrend, totalTvl); const result: DefiHealthOutput = { total_tvl_usd: totalTvl, tvl_change_24h: Math.round(tvlChange24h * 100) / 100, tvl_change_7d: Math.round(tvlChange7d * 100) / 100, tvl_trend: tvlTrend, top_chains: topChains, top_protocols: topProtocols, defi_health_score: healthScore, protocol_revenue_trend: revenueTrend, ecosystem_concentration: concentration, agent_guidance: guidance, }; cache.set(CACHE_KEY, result, getCacheTtl(BASE_TTL)); return result; } catch (err) { return { error: true, error_source: 'get_defi_health', agent_guidance: 'DeFi health data unavailable. Without DeFi context, avoid yield farming or protocol-specific positions. Stick to spot holdings until DeFi data is restored.', last_known_data: cache.get<DefiHealthOutput>(CACHE_KEY)?.data ?? null, data_warnings: ['DeFi data source temporarily unavailable. Retry shortly.'], }; } }