DeFi Risk Engine
Technical documentation for the defi-risk-engine repository.
Whitepaper | Quantir UI Walkthrough | Use Cases | DeFi Risk Engine | Roadmap
This page is part of the externalized documentation layer that sits beside the main Quantir whitepaper. The whitepaper should stay focused on narrative, methodology, validation framing, and buyer logic, while the deeper runtime and service-level description of the system can live here.
What This System Is
defi-risk-engine is a monitoring and risk-explanation platform for DeFi protocols. It consists of several independent runtime services that together do the following:
- collect on-chain and market data for protocols
- calculate base risk and transaction-driven pressure
- build snapshot and chart payloads for the UI
- generate AI explanations for state and events
- publish alerts and realtime websocket updates
- expose dashboard-friendly APIs for the frontend
Main Runtime Parts
| Service | Path | Role |
|---|---|---|
| API service | api/ |
Auth, dashboard/bootstrap API, watchlist, alerts, websocket token issuance |
| On-chain engine | src/onchain_data/ |
Main ingestion runtime, snapshots, tx events, charts, audit hydration |
| Explain service | src/explain_service/ |
Durable explain jobs and provider ensemble |
| Alert system | src/alert_system/ |
Router/worker delivery pipeline via Redis Streams |
| Forecast system | src/forecast_system/ |
Chronos-based short-horizon forecasting |
| Risk model | src/risk_model/ |
Rust scoring service for base risk |
| Off-chain news worker | src/offchain_data/ |
RSS/Atom ingestion for protocol_news |
System Architecture

Main Data Flow
src/onchain_data/index.jsstarts the engine, connects to MongoDB, and syncs the protocol catalog.- Collectors gather TVL, whale, tx behavior, token health, candles, and historical bootstrap data.
- The engine computes derived metrics and calls the Rust risk model.
- The engine obtains forecasts from the forecast service and stores precomputed chart artifacts.
- The engine writes
protocolsnapshots,tx_risk_events,protocolchartpayloads, andmarketcandles. - The engine sends explain requests to
src/explain_service/when needed. - The off-chain news worker writes
protocol_news. - The alert router/worker reads events, routes delivery jobs, and writes user notifications.
api/reads MongoDB and serves user-scoped payloads torisk-ui.- The frontend gets a websocket token through
POST /api/ws/tokenand connects to the alert socket.
Repository Landscape
| Layer | Path | Role |
|---|---|---|
| Core runtime | src/onchain_data/ |
Main engine runtime |
| Core runtime | src/explain_service/ |
Explain jobs, provider orchestration, and fusion |
| Core runtime | src/alert_system/ |
Router and worker alerts pipeline |
| Core runtime | src/forecast_system/ |
Node orchestration for Chronos forecasting |
| Core runtime | src/risk_model/ |
Rust scoring service |
| Core runtime | src/offchain_data/ |
Off-chain protocol news ingestion |
| Shared contracts and persistence | src/db/ |
Mongo connection, schemas, and repositories |
| Shared contracts and persistence | src/bootstrap/ |
Startup helpers and initial catalog sync |
| Shared contracts and persistence | src/strategies/ |
Transaction-driven risk adjustment |
| Shared contracts and persistence | src/config_builder/ |
Generator for src/onchain_data/config/protocols.json |
| User-facing delivery | api/ |
Authenticated backend for the dashboard |
| User-facing delivery | risk-ui/ |
Frontend application |
| Historical / legacy layers | src/routers/ |
Express-era routers |
| Historical / legacy layers | src/services/ |
Express-era service helpers |
| Historical / legacy layers | src/modules/ |
Shared domain helpers between the legacy layer and the newer api/src/modules/ |
On-Chain Engine
Purpose
src/onchain_data/ is the central runtime of the entire platform. It is responsible for:
- orchestrating protocol collectors
- persisting snapshots and tx risk events
- triggering explain flows
- hydrating forecast data
- exposing the alerts websocket used by the frontend
Bootstrap Sequence
src/onchain_data/index.js starts the engine in this order:
- connect to MongoDB
- sync protocol metadata from
config/protocols.json - hydrate stored ABI and contract-audit intelligence
- start the alerts websocket API
- bootstrap missing snapshots
- bootstrap scheduled explain requests
- start transaction monitoring
- start the model explanation loop
- start periodic collector loops
- asynchronously refresh contract audits
Main Responsibilities
- collect protocol state from on-chain and market data sources
- compute derived metrics used by the risk model
- call the Rust risk model service
- request short-horizon forecasts from the forecast service
- persist
protocolsnapshots,tx_risk_events, and chart payloads - dispatch explain requests to
explain-service - publish websocket alert events
Key Components
src/onchain_data/collectors/
TVLCollector, WhaleCollector, TxBehaviourCollector, TokenRiskProfileCollector, CandleCollector, HistoricalBootstrapCollector
src/onchain_data/explain/
explain rule matching, context construction, dispatch
src/onchain_data/chartHelpers/
precomputed payload generation for dashboard charts
src/onchain_data/audit/
contract capability audit and ABI hydration
src/onchain_data/base/
collector base abstractions and websocket helpers
Strategy-Adjusted Risk
After the base model score, the system adds a transaction-driven contribution.
Formula used by the strategy layer:
R_total = clamp01(R_base + Delta_tx)
Where:
R_basecomes from the Rust risk modelDelta_txis computed from recent transaction events- severity is normalized relative to amount vs. FDV
- time decay and saturation are then applied over a recent window
Illustration:

Explain Service
What It Does
src/explain_service/ does not calculate risk itself. It turns already-normalized risk context into durable explanation jobs:
- accept explain requests
- persist
explain_jobs - run several LLM-backed providers in parallel
- normalize outputs into a fixed-width hypothesis vector
- fuse successful provider outputs
- expose the result through a small HTTP API
Main Use Cases
- daily protocol refresh explanations
- event-triggered explanations dispatched by the engine
- manual operator or dashboard explain requests
Providers
The current implementation uses a practical provider ensemble:
OpenAIProviderClaudeProviderGeminiProvider
Runtime Architecture
RequestDeduper
cooldown handling, duplicate active jobs, duplicate event_id
ExplainJobService
creates durable explain job payloads and reconstructs context for manual requests
ExplainOrchestrator
runs enabled providers in parallel and writes job state transitions
HypothesisAggregator
fuses successful provider outputs into judge_result, final_summary, and confidence
Explain Service Diagrams
Conceptual Architecture

Agent Weighting Reference

Example Hypothesis Distribution

Model Explanation Loop
This is a separate loop from explain_service.
model_explanation
explains the current model state over a time window
explain_service
explains a specific event or trigger through provider fusion
What The Loop Does
For each protocol it:
- selects a recent time window
- loads recent
ProtocolSnapshot - loads recent
TxRiskEvent - builds a prompt payload
- requests a concise explanation
- persists the result into
protocol_risk_explanations
Outputs
risk_scoresummarywhy_nowkey_driversconfidencewindow_startwindow_endsnapshot_at
API Service
Purpose
api/ is an authenticated Next.js backend that reads data already persisted by engine-side services and exposes UI-friendly contracts.
It is responsible for:
- user authentication and sessions via NextAuth
- user-scoped dashboard/bootstrap responses
- watchlist and alert subscription management
- query access to alerts, news, model explanations, explain jobs, and contract audits
- short-lived websocket token issuance
- health and development utility endpoints
Main Route Groups
api/src/app/api/auth/[...nextauth]/route.ts
NextAuth entrypoint
api/src/app/api/register/route.ts
credentials registration
api/src/app/api/me/*
authenticated dashboard-facing data APIs
api/src/app/api/monitor/*
watchlist and settings flows
api/src/app/api/ws/token/route.ts
websocket JWT issuance
api/src/app/api/telegram/*
Telegram account linking
api/src/app/api/health/*
liveness/readiness
Core Service Modules
dashboard
builds bootstrap payloads, metrics, precomputed chart payloads, and fallbacks
monitor
watched protocols and alert subscriptions
alerts
reads tx_risk_events and produces UI-ready alerts
news
reads protocol_news, normalizes aliases, and deduplicates articles
model-explanation
exposes stored protocol_risk_explanations
explain
lists explain_jobs and forwards manual explain requests
contract-audit
exposes stored audit artifacts
subscription
resolves plan capabilities and protocol limits
ws
signs short-lived websocket tokens
API Module Map
| Module | Responsibility | Main Data / Contract |
|---|---|---|
auth |
NextAuth config, providers, JWT/session enrichment | session, JWT, redirect allowlist |
users |
user and Telegram-link persistence models | users, telegram_link_tokens |
userContext |
resolve authenticated Mongo user from session | withUser(...) boundary |
dashboard |
bootstrap payloads, metrics, charts, fallbacks | protocolsnapshots, protocolchartpayloads, marketcandles |
monitor |
watchlist, subscriptions, monitor settings | user_protocols, user_alert_protocols, user_settings |
alerts |
UI-shaped risk event feed and counters | tx_risk_events |
news |
normalized news feed for watchlist and protocol pages | protocol_news |
model-explanation |
recent interval-level model explanations | protocol_risk_explanations |
explain |
list explain jobs and forward manual explain requests | explain_jobs, EXPLAIN_SERVICE_URL |
contract-audit |
expose stored audit findings and capability maps | protocol_contract_audits |
subscription |
plan limits and feature flags | plan to capability mapping |
plans |
minimal shared plan helper | plans.ts |
notifications |
in-app notification persistence model | user_notifications |
protocol |
warm enabled-protocol cache for reads | in-memory protocol cache |
candle_chart |
external price-candle fallback loader | CoinGecko candle contract |
ws |
websocket JWT issuance | short-lived HS256 token |
Main Endpoints
Bootstrap And Metrics
GET /api/me/bootstrapGET /api/dashboard/bootstrapGET /api/me/dashboard-metrics
Monitor / Watchlist
GET /api/monitor/protocolsGET /api/monitor/me/protocolsPOST /api/monitor/me/protocolsDELETE /api/monitor/me/protocols/:protocol
Alerts / News / Explanations
GET /api/me/alertsGET /api/me/alerts/countGET /api/me/newsGET /api/me/model-explanationsGET /api/me/explain-jobsPOST /api/me/explain-jobsGET /api/me/contract-audits
Realtime / Ops
POST /api/ws/tokenGET /api/healthGET /api/strategies
Alert System
src/alert_system/ is split into two runtime stages:
Router
- listens to upstream risk and tx event streams
- enriches and filters events
- maps alerts to subscribed users
- enqueues delivery jobs into Redis Streams
Worker
- consumes jobs from a Redis Streams consumer group
- delivers alerts to channels
- handles retries and DLQ routing
Why This Split Exists
This removes the for user -> await deliver bottleneck and allows delivery to scale horizontally.
Main Files
src/alert_system/alertManager.jssrc/alert_system/queue/redisStreamQueue.jssrc/alert_system/deliveryWorker.jssrc/alert_system/index.jssrc/alert_system/worker.jssrc/alert_system/telegramLinkBot.js
Forecast System
src/forecast_system/ is a standalone Node.js service for short-horizon protocol forecasting.
Pipeline
- read protocol snapshots and tx risk events from MongoDB
- build fixed time buckets (
15mor1h) and store them inprotocol_metrics_ts - send metric series to the local Chronos endpoint (Python adapter)
- recompute future risk from forecasted metrics
- store future bars in
predicted_risk_ts
Components
- Node orchestrator:
src/forecast_system - Python predictor adapter:
src/forecast_system/predictor
Metrics Sent To Chronos
risk_scoretvl_usdprice_usdfdv_usdalerts_count
Risk Model
src/risk_model/ is a Rust scoring service that turns normalized protocol features into a base risk score.
Input Features
tvltvl_delta_1dtvl_delta_7dprice_delta_1dprice_delta_7dvolume_spikemcap_tvl_ratio
Runtime Modes
traininferserve
HTTP Contract
POST /score
Request:
{
"tvl": 1000000,
"tvl_delta_1d": 0.01,
"tvl_delta_7d": -0.03,
"price_delta_1d": 0.02,
"price_delta_7d": -0.09,
"volume_spike": 0.6,
"mcap_tvl_ratio": 0.2
}
Response:
{
"risk": 0.42
}
Off-Chain Protocol News Worker
This worker ingests RSS/Atom feeds and fallback HTML article pages, matches articles to enabled protocols, and persists them into protocol_news.
Responsibilities
- read feeds from
config/protocol_rss_sources.json - fall back to parsing article links from HTML pages when feeds are unavailable
- match each article to enabled protocols from MongoDB
- save matched articles to
protocol_news - deduplicate by
(protocol, dedupeKey)
Database Layer
src/db/ is the shared persistence contract between runtime components and the API.
Main Collections
| Collection | Schema / Role |
|---|---|
protocols |
protocol registry and metadata |
protocolsnapshots |
time-series snapshots |
protocolchartpayloads |
precomputed dashboard chart payloads |
marketcandles |
price candles |
tx_risk_events |
normalized transaction risk events |
explain_jobs |
explain-service job state |
protocol_risk_explanations |
model explanation loop output |
users |
user accounts |
user_protocols |
watchlist entries |
user_alert_protocols |
alert subscriptions |
user_settings |
per-user settings |
user_notifications |
in-app notifications |
Repository Helpers
Mongo.jsProtocolRepository.jsProtocolSnapshotRepository.jsProtocolChartPayloadRepository.jsMarketCandleRepository.jsTxRiskEventRepository.jsExplainJobRepository.jsProtocolRiskExplanationRepository.jsProtocolSnapshotBuilder.js
Config Builder
src/config_builder/ generates protocol config for src/onchain_data/config/protocols.json.
What It Generates
contractsflaggedMethodsadminMethodsprotocolContractswhalesownerswhaleTransferMinliquidityShockAmounttvlwhaletoken_health
Data Sources
- ABI/source: Etherscan-like API, fallback Blockscout
- TVL: DefiLlama
- whales: Ethplorer / CoinGecko / Moralis
- thresholds: CoinGecko + DexScreener liquidity
Bootstrap And Shared Runtime Helpers
Bootstrap
src/bootstrap/ contains startup helpers for the initial persistent state before long-running loops begin.
Current main scope:
src/bootstrap/initProtocols.js
upserts protocol metadata from src/onchain_data/config/protocols.json into the Protocol collection
Shared Runtime Modules
src/modules/ contains small shared domain modules:
monitor/plans/userContext/
Legacy Layers
src/services/
legacy Express-era service helpers
src/routers/
earlier Express router layer with monitorRoutes.js
New product-facing endpoints should go through api/src/app/api/ and api/src/modules/.
Frontend Integration
The root frontend package in this repository is risk-ui/.
The main runtime contract between risk-ui and the backend looks like this:
- frontend calls
GET /api/me/bootstrap - focused reads go through
alerts,news,dashboard-metrics,model-explanations, andcontract-audits - realtime auth goes through
POST /api/ws/token - websocket connection is established against the engine-side alerts socket
risk-ui Runtime Surface
Although risk-ui currently does not have a dedicated root README, the project structure and deployment docs make the frontend scope clear:
- App Router application with authenticated dashboard flows
- protocol selector, metrics cards, charting, alerts, reasoning, audit, and news views
- consumption of
api/bootstrap endpoints and engine websocket updates - deployment via
Dockerfile.risk-uianddeploy/k8s/risk-ui
Frontend Deploy Notes
- image builds from
Dockerfile.risk-ui - public runtime config is passed through
NEXT_PUBLIC_API_BASE_URLandNEXT_PUBLIC_ALERTS_WS_URL - ingress is configured for the application domain in
deploy/k8s/risk-ui/ingress.yaml
Realtime WebSocket Flow
- frontend calls
POST /api/ws/token - API signs a short-lived HS256 JWT
- frontend connects to the alerts websocket with
?token=... - the engine-side websocket server validates the token and streams updates
Environment Variables
Engine
MONGODB_URIMONGODB_DBALCHEMY_WS_URLCOINGECKO_KEYRISK_MODEL_URLFORECAST_URLEXPLAIN_SERVICE_URLWS_TOKEN_SECRETorAUTH_SECRET
API
MONGODB_URIAUTH_SECRETEXPLAIN_SERVICE_URLGOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETWS_TOKEN_SECRETNEXTAUTH_URLAUTH_ALLOWED_REDIRECT_ORIGINSCORS_ALLOWED_ORIGINS
Alert System
ALERT_QUEUE_REDIS_URLALERT_QUEUE_STREAMALERT_QUEUE_GROUPALERT_QUEUE_DLQ_STREAMALERT_MANAGER_TX_WS_URLALERT_MANAGER_RISK_WS_URLTELEGRAM_BOT_TOKENSMTP_HOST
Forecast System
CHRONOS_ENDPOINT_URLFORECAST_PORTFORECAST_DEFAULT_INTERVALFORECAST_DEFAULT_HORIZON
Explain Service
OPENAI_API_KEYANTHROPIC_API_KEYGEMINI_API_KEY