Search projects, hackathons, sponsors and tech

    ← All projects

    DeFi-Risk-Sentinel

    AI-powered DeFi liquidation risk monitor for Aave V3 on Ethereum

    Demo

    About

    Detailed Description What It Does The Sentinel continuously monitors DeFi lending positions on the Aave V3 protocol (Ethereum mainnet) and answers one critical question: "How close is this wallet to liquidation?" It fetches real user reserve data — collateral balances (aTokens), stable/variable debt, per-asset liquidation thresholds, and oracle prices — directly from a live The Graph subgraph via GraphQL. No mocks, no hardcoded data. Every number originates from on-chain state. How It Works 1. Data Layer (src/data/) graphClient.js — A GraphQL transport client that queries The Graph's decentralized gateway (gateway.thegraph.com), with built-in retries and rate limiting. aaveQueries.js — Aave V3-specific GraphQL queries to fetch user reserves, price oracles, and active users. Parses raw subgraph responses into a normalized position format. 2. Risk Engine (src/engine/) riskEngine.js — Core computation module. Calculates the health factor using the formula: Health Factor = Σ(collateral_i × price_i × liquidationThreshold_i) / Σ(debt_j × price_j) Classifies positions into three risk tiers: Level Health Factor Meaning 🔴 DANGER < 1.05 Imminent liquidation 🟡 WATCH < 1.20 Elevated risk 🟢 SAFE ≥ 1.20 Healthy Also identifies the weakest collateral (the asset whose price drop has the largest marginal impact on health factor) and the largest debt position. scenarios.js — Scenario simulation engine. Can: Simulate arbitrary price changes and recompute health factors Analytically solve the exact liquidation price for any collateral asset (not just brute-force search) Run multi-drop stress tests (e.g. 5%, 10%, 20%, 30%, 50% simultaneous crashes) Handle correlated assets via aliases (WETH/stETH/cbETH all track ETH; USDC/USDT/DAI all track USD) 3. AI Reasoning Layer (src/reasoning/) nlGenerator.js — Generates rich, natural-language risk reports from computed data. Not template-filling — produces context-aware narratives explaining why a position is risky, what the weakest link is, and what actions to take. Supports an optional OpenAI GPT-4 integration for even deeper analysis and a conversational Q&A interface. 4. Alerting System (src/alerts/) poller.js — Configurable polling loop (default 60s) that re-fetches positions and detects when a wallet transitions from SAFE/WATCH into DANGER. webhook.js — Sends alerts to Discord, Slack, or any generic webhook endpoint. 5. Interfaces REST API ( api.js ) — 12 endpoints covering health checks, watchlist CRUD, risk assessments, simulation, stress testing, and natural-language queries. Web Dashboard ( public/ ) — Premium dark-themed glassmorphic UI with animated backgrounds, real-time risk tables, an AI chat panel, per-wallet stress test controls, and auto-refresh. CLI ( cli.js ) — Interactive terminal interface for all features. Tech Stack Component Technology Runtime Node.js 18+ (ES Modules) Data Source The Graph (Aave V3 Ethereum Subgraph, decentralized network) Server Express.js HTTP Client node-fetch AI (optional) OpenAI GPT-4 for enhanced NL reasoning Frontend Vanilla HTML/CSS/JS (glassmorphic dark theme) Agent Integration MCP config + SKILL.md for AI agent compatibility Key Design Decisions Protocol-agnostic engine: Only src/data/aaveQueries.js is Aave-specific. The risk engine, simulation, reasoning, and alerting layers operate on a normalized position format — swapping to Compound, Morpho, or any lending protocol only requires a new data adapter. No mocks: Every data point is fetched live from Ethereum mainnet via The Graph. The app works against real positions with real risk. Analytical liquidation solving: Instead of binary search, the scenarios module solves the liquidation price algebraically for O(1) precision. Graceful AI degradation: Works fully without an OpenAI key (rule-based NL generation), but produces richer output when one is configured.

    How it's made

    We built the Sentinel as a from-scratch Node.js (ES Modules) application with a clean five-layer architecture: Data → Engine → Reasoning → Alerts → Interface. Each layer only depends on the one below it, making the whole system protocol-swappable — only one file knows anything about Aave. The Graph (Partner Technology) is the backbone. Every number in the app — collateral balances, debt amounts, liquidation thresholds, oracle prices — comes from live GraphQL queries to the Aave V3 Ethereum subgraph (GQFbb95cE6d8mV989mL5figjaGaKCQB3xqYrr1bRyXqF) on The Graph's decentralized gateway. No RPC calls, no mocked data, no indexing infrastructure of our own. We fire two parallel GraphQL queries per wallet: one for userReserves (positions, collateral flags, reserve config) and one for priceOracles (live USD pricing). The Graph handles the heavy lifting of indexing Ethereum's state into a queryable schema — without it, we'd need our own indexer, archive node, and weeks of setup. We also ship an mcp_config.json for @thegraph/subgraph-mcp, so AI agents can query the same subgraph through the Model Context Protocol. The trickiest engineering problems: Parsing Aave V3's on-chain encoding. Balances come as raw BigInt strings scaled by token decimals (6 for USDC, 18 for WETH, 8 for WBTC). Liquidation thresholds are basis points (8250 = 82.5%). Rates use ray precision (1e27). Prices use a double-indirection: a priceInEth field scaled by 1e18, plus a separate usdPriceEth oracle value you invert and multiply. We wrote a parseTokenAmount() function using JavaScript BigInt to split integer and fractional parts without floating-point loss, and a multi-fallback pricing pipeline that tries the USD oracle first, then falls back to priceInEth × ethPrice. Analytical liquidation price solving. Instead of binary-searching for the price drop that pushes health factor to 1.0 (which is what most tools do), we derived a closed-form solution: dropFraction = 1 - (totalDebt - effectiveOther) / (balance × price × LT). This gives O(1) exact answers and lets us compute liquidation prices for every asset in every wallet on every poll cycle without blowing up compute. Correlated asset aliasing in simulations. When a user asks "what if ETH drops 20%", we need WETH, stETH, wstETH, cbETH, and rETH to all move together — they're the same underlying exposure. We built an alias map that groups synthetic/wrapped variants under their base asset (ETH, BTC, USD), so one simulation input cascades correctly through the whole portfolio. Graceful AI degradation. The NL reasoning layer works in two modes. Without an OpenAI key, it uses a rule-based engine that pattern-matches user questions with regex (price drop queries, stress test requests, wallet lookups, portfolio summaries) and generates reports by computing real numbers — collateral shares, repayment amounts to reach target HF, margin-to-liquidation percentages. With an OpenAI key, it injects the full position dataset into GPT-4o-mini's context as a system prompt and lets the LLM reason over actual numbers. If the LLM call fails, it silently falls back to rule-based. Zero-config, always works. Tech stack: Node.js 18+, Express for the REST API (12 endpoints), vanilla HTML/CSS/JS for the frontend (glassmorphic dark theme, animated gradient background, custom markdown-to-HTML renderer for the chat panel), node-fetch for HTTP, dotenv for config. Four total dependencies. The frontend auto-refreshes every 60 seconds, the backend polls The Graph on a configurable interval, and the alerting layer detects risk-level transitions (SAFE→WATCH, WATCH→DANGER) and fires Discord/Slack/generic webhooks with auto-detected payload formatting.