Precise, not promotional — this page exists so a technical reader can verify every number LiquiScope reports.
Health factor is read directly from the protocol's own on-chain aggregate —
Pool.getUserAccountData(user).healthFactor — never recomputed or
approximated. Liquidation prices are derived from the same call's
currentLiquidationThreshold and per-reserve data:
HF = weightedCollateralUsd / debtUsd liquidationPrice(dominant asset) solves HF = 1 for that asset's price, holding every other balance and price constant
E-mode caveat: per-reserve liquidation thresholds understate an e-mode
user's real threshold. When the wallet is in an e-mode category, the
position-wide weighted-average threshold (from the same
getUserAccountData call) is substituted on every leg — exact
for single-collateral positions, a close approximation otherwise. The
health factor itself is always the on-chain aggregate, e-mode or not.
Compound has no single on-chain health-factor field, so LiquiScope composes the equivalent from the same inputs Comet itself liquidates against:
HF = Σ(collateral_i_usd × liquidateCollateralFactor_i) / debt_usd
liquidateCollateralFactor comes from each market's
getAssetInfo; collateral balances from userCollateral;
debt from borrowBalanceOf, priced via the market's own base-token
feed. This is the exact ratio Comet liquidates a whole-account position
against the moment it crosses 1 — not a stylistic mirror of Aave's formula,
the same underlying accounting.
WETH-market price feeds are denominated in ETH, not USD — converted via the chain's Aave oracle WETH/USD price (shared price data only; Compound's risk logic never depends on Aave's risk logic). Verified empirically per chain, not assumed.
A single 0-100 number summarizing a wallet's entire cross-protocol, cross-chain exposure:
base_score = piecewise-linear interpolation of the WORST health factor
across all positions, anchored at the same tier breakpoints
used everywhere else (1.0→10, 1.05→30, 1.15→55, 1.5→80, 3.0→100)
concentration_penalty = up to 15 points, scaled by the Herfindahl-Hirschman
Index of collateral value across unique asset symbols
final_score = round(base_score × (1 − 0.15 × HHI))
Zero debt-bearing positions returns a null score with label no_active_positions — never a fabricated number.
getAssetsPrices), read at the same block as the position data.getPrice feed per asset, plus the base-token feed for debt.GET /proof): the identical oracle reads above, pinned to a historical block instead of the latest one — never a separate historical price model.
A source is labeled beta in the coverage matrix when its reads
succeed and are computed by the exact same formula as every "ok" source,
but have never been checked against a real, live position — no fixture
wallet was found for that specific protocol×chain combination. Every
position returned from a beta source is stamped provisional: true,
so a paid report never silently presents an unconfirmed number as
equivalent to a battle-tested one.
| Protocol | Ethereum | Base | Arbitrum | Optimism |
|---|---|---|---|---|
| Aave v3 | ok | ok | ok | ok |
| Compound v3 | beta | ok | ok | unsupported |
Compound v3 / Ethereum is beta because free-tier RPCs cap eth_getLogs
ranges too tightly for event-based wallet discovery to be practical (as
tight as 50 blocks on some providers) — a free-infrastructure ceiling, not
an archive-tier gap that would ease with more waiting. Re-evaluated
2026-07-24, still beta, same reason. This table is hardcoded and needs a
manual update if coverage changes — GET /report's live
coverage field is the source of truth if the two ever disagree.