envio risk·dash

About this dashboard

Built for the Envio Growth Engineer role by Kaustubh Agrawal. Pairs with a full candidate package of strategy memos, indexer templates, and live-data assertion harnesses (48,014 cross-entity invariants passing on real on-chain data).

Where the data comes from

Every page on this dashboard fetches from a single GraphQL endpoint:

https://indexer.dev.hyperindex.xyz/8fc0607/v1/graphql

This is an Envio HyperIndex deployment of an Aave-V3-shaped indexer covering Polygon, Arbitrum, and Base. The handler source is in the candidate package's pow/envio-money-market-template-v1/ directory.

Metric definitions

Reserves indexed
Distinct (chain, asset) pairs with at least one Aave V3 event recorded. Lazy-created on first Supply / Borrow / ReserveDataUpdated.
Liquidations · all-time
Total LiquidationCall events ingested across all reserves and chains. Each event increments two reserves' counters (collateral + debt), so the dashboard divides by 2 to recover the unique-event count.
Liquidations · 24h
LiquidationCall events with a timestamp ≥ 24 hours ago at request time. Capped at 1,000 — protocols that fire more than that in a day will display "1000+".
Top reserve · supplied
ReserveAggregator ordered by totalSupplied descending; tile shows the leader plus current supply APR (RAY-encoded, displayed as a percent).
Utilization
totalBorrowed / totalSupplied × 100, computed client-side over BigInts. A "rough" Aave-shape utilization, not the protocol's exact accounting (which factors in scaled balances + indices).
Top liquidators (default · all-time)
UserAggregator entities filtered to liquidationsAsLiquidator > 0, ordered descending. The aggregator is updated every LiquidationCall event the address participates in. All-time means lifetime cumulative — a whale liquidated 47 positions in 2024 will outrank a new active liquidator. That's by design for a "who has done this historically" view; for "who's doing it now," use the window or sort toggles below.
Time-window toggle (?window=24h|7d|30d)
Switches both leaderboards from the all-time aggregator view to a windowed view: fetch all Liquidation rows in[now − window, now] (capped at 1000 events by Envio's hosted GraphQL), group by liquidator (or victim) client-side, sort by event count. The header surfaces "ranked across N events" so the sample-based nature is honest. For productized use this would paginate; for v1 the cap is acceptable.
Sort toggle (?sort=lastActive)
On the all-time view, flips ordering from liquidationsAsLiquidator desc lastActiveTimestamp desc. Shows the leaderboard ranked by recency-of-last-event instead of total count. Useful when you want "who's active right now" but still want the indexed-once aggregator entity (faster than the windowed query).
Inactive badge (90d threshold)
On all-time leaderboards, addresses whose lastActiveTimestamp is more than 90 days ago get a muted "inactive" tag and a dimmed timestamp. No row is hidden; the ranking is still the cumulative truth, but the visual cue lets a reader spot dormant whales at a glance.
"Last activity in this view" header
Each leaderboard renders the most recent timestamp in the currently-displayed result set as a relative time ("25m ago", "3h ago"). Makes data freshness explicit at the top of the page rather than buried in row timestamps.
Recent victims (windowed at-risk)
When the at-risk page has a window active, it renames itself to "Recent Victims" — different concept from the all-time at-risk heuristic. All-time at-risk is "users who have historically been liquidated and may be again"; recent victims is "who got hit in the last X period". Both are useful, both are surfaced via the same URL with the ?window param.
At-risk users (heuristic, all-time)
UserAggregator entities filtered to liquidationsAsBorrower > 0, ordered descending. This is a proxy, not an oracle. We use prior-liquidation count as the risk signal because we don't have on-chain prices indexed yet — a user with high historical liquidations and active debt is statistically more likely to face another liquidation. v2 of this dashboard adds health-factor computation via Chainlink prices and the Envio Effect API.
Rate APR
Aave V3 stores currentLiquidityRate and currentVariableBorrowRate as 27-decimal RAY-encoded BigInts representing rate-per-year. We convert to a Number percent via rateRay × 10000 / 10²⁵ / 100 — see lib/format/ray.ts.

Scope and v2 roadmap

v1 ships read-only, six pages, no oracle dependency, no wallet connect. The full candidate roadmap (USD pricing, per-user portfolios, Morpho/Spark shape variants) lives in the README.

Reproduce + fork

Click "Use this template" on the GitHub source — change NEXT_PUBLIC_GRAPHQL_ENDPOINT in .env.local to point at your indexer, deploy.