What this tool does
The Aave Health Factor Checker reads any wallet’s Aave V3 position and returns the health factor, total collateral, total debt, available borrows, and liquidation threshold from one expression. It is built for borrowers, liquidation bots, and risk dashboards that need a fast read on how close a position is to liquidation without writing ABI files or remembering the right scaling for each field.
How to use it
- Paste the wallet address you want to check into the form above.
- Pick the chain the Aave V3 position lives on.
- Run the query and read the health factor, collateral, debt, and thresholds in the result panel.
The result panel shows the health factor prominently, colored by risk band, along with total collateral and debt in USD, how much more the wallet could borrow, and the liquidation threshold and max LTV as percentages. Wallets with no open position show a friendly message instead of an empty grid, and wallets with no debt show an infinity symbol instead of an unreadable number.
What is happening under the hood
Aave V3’s Pool contract exposes getUserAccountData(address user), which returns collateral, debt, and risk parameters for a wallet in a single call. That single call already avoids multiple round trips, but the raw return values are scaled differently: collateral and debt use 8 decimals (Aave’s internal USD base currency), the health factor uses 18 decimals like a normal token amount, and the LTV and liquidation threshold are basis-point-style ratios with 4 decimals.
cel.bind(d, pool.getUserAccountData(user), {
"healthFactor": string(formatUnits(d.healthFactor, 18)),
"totalCollateralBase": string(formatUnits(d.totalCollateralBase, 8)),
"totalDebtBase": string(formatUnits(d.totalDebtBase, 8)),
"availableBorrowsBase": string(formatUnits(d.availableBorrowsBase, 8)),
"currentLiquidationThreshold": string(formatUnits(d.currentLiquidationThreshold, 4)),
"ltv": string(formatUnits(d.ltv, 4))
})
cel.bind(d, pool.getUserAccountData(user), …)calls the contract once and reuses the struct for every field, instead of six separate reads.useris a runtime context variable, declared assol_addressin the schema and supplied per request, so the same expression works for any wallet without being recompiled.- Each field is scaled with the decimals Aave actually uses for that value, not a single flat exponent, which is the detail that trips up a naive integration.
- When a wallet has no debt, Aave returns
healthFactorastype(uint256).max, which formats to an astronomically large number. The client detects values above a sane threshold and renders∞instead of a 59-digit string. - All six values are returned as strings so they fit in the same CEL map. CEL maps require their values to share a type, and
string(formatUnits(…))is the conversion path used across every field.
Build this yourself
Each of the snippets below makes the same POST call to the evmquery REST API against the Aave V3 Pool on Ethereum. Swap in your own wallet address; the example wallet may or may not have an open position at the time you run it.
REST (curl)
curl -X POST https://api.evmquery.com/api/v1/query \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chain": "evm_ethereum",
"schema": {
"contracts": { "pool": { "address": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2" } },
"context": { "user": "sol_address" }
},
"expression": "cel.bind(d, pool.getUserAccountData(user), { \"healthFactor\": string(formatUnits(d.healthFactor, 18)), \"totalCollateralBase\": string(formatUnits(d.totalCollateralBase, 8)), \"totalDebtBase\": string(formatUnits(d.totalDebtBase, 8)), \"availableBorrowsBase\": string(formatUnits(d.availableBorrowsBase, 8)), \"currentLiquidationThreshold\": string(formatUnits(d.currentLiquidationThreshold, 4)), \"ltv\": string(formatUnits(d.ltv, 4)) })",
"context": { "user": "0x1234567890123456789012345678901234567890" }
}'
Python
import requests
resp = requests.post(
"https://api.evmquery.com/api/v1/query",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"chain": "evm_ethereum",
"schema": {
"contracts": {"pool": {"address": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2"}},
"context": {"user": "sol_address"},
},
"expression": (
"cel.bind(d, pool.getUserAccountData(user), {"
' "healthFactor": string(formatUnits(d.healthFactor, 18)),'
' "totalCollateralBase": string(formatUnits(d.totalCollateralBase, 8)),'
' "totalDebtBase": string(formatUnits(d.totalDebtBase, 8)),'
' "availableBorrowsBase": string(formatUnits(d.availableBorrowsBase, 8)),'
' "currentLiquidationThreshold": string(formatUnits(d.currentLiquidationThreshold, 4)),'
' "ltv": string(formatUnits(d.ltv, 4))'
" })"
),
"context": {"user": "0x1234567890123456789012345678901234567890"},
},
timeout=10,
)
print(resp.json()["result"])
TypeScript
const resp = await fetch("https://api.evmquery.com/api/v1/query", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.EVMQUERY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
chain: "evm_ethereum",
schema: {
contracts: {
pool: { address: "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2" },
},
context: { user: "sol_address" },
},
expression:
'cel.bind(d, pool.getUserAccountData(user), { "healthFactor": string(formatUnits(d.healthFactor, 18)), "totalCollateralBase": string(formatUnits(d.totalCollateralBase, 8)), "totalDebtBase": string(formatUnits(d.totalDebtBase, 8)), "availableBorrowsBase": string(formatUnits(d.availableBorrowsBase, 8)), "currentLiquidationThreshold": string(formatUnits(d.currentLiquidationThreshold, 4)), "ltv": string(formatUnits(d.ltv, 4)) })',
context: { user: "0x1234567890123456789012345678901234567890" },
}),
});
const { result } = await resp.json();
The free tier has no monthly cap. Get a free API key to drop these snippets into your project.
When you would use this
- Liquidation and risk bots. Poll a watchlist of wallets and alert before a health factor crosses your own risk threshold, ahead of any liquidation.
- Borrower dashboards. Show a user their own Aave position — collateral, debt, and how much headroom they have to borrow — without hardcoding the Pool ABI.
- Portfolio and treasury monitoring. Track how a DAO or fund’s Aave exposure moves as collateral prices and interest accrual change.
- Pre-transaction sanity checks. Before submitting a withdrawal or borrow transaction, confirm the resulting health factor stays in a safe range.
FAQ
What is the Aave health factor?
The health factor is a single number Aave V3 computes from a wallet’s collateral, debt, and liquidation threshold. It measures how safe a borrowing position is: the higher the number, the safer the position. It comes directly from the pool’s getUserAccountData function.
What does a health factor below 1 mean?
A health factor below 1 means the position is eligible for liquidation. Liquidators can repay part of the debt and seize collateral at a discount. A health factor between 1 and 1.5 is generally considered close to risk and worth monitoring closely.
Which chains are supported?
The checker currently runs against the Aave V3 Pool on Ethereum and Base. Additional EVM chains are being added on the evmquery backend as Aave V3 deploys to them.
Is this real-time?
Yes. Every read hits the latest block at request time. There is no caching layer between the tool and the chain, so the numbers reflect the current on-chain state.
Does it work with wallets that have no borrows?
Yes. When a wallet has no debt, Aave returns an effectively infinite health factor (the maximum representable integer). The tool detects that case and shows ∞ with a note that the position is not at liquidation risk, instead of a 59-digit number.
Can I use this tool from my own application?
Yes. The same expression and pool address work against the public REST API. The free tier has no monthly cap, and a single check counts as one read because the pool call is a single eth_call round trip. Bring your own API key and the rate limit applied to this page no longer applies.
Limits and accuracy
- The result reflects the latest block at the time of the read. There is no historical replay of health factor over time.
- Total collateral, total debt, and available borrows are denominated in Aave’s internal USD base currency, which is derived from the protocol’s own oracle prices, not a third-party price feed.
- The demo is rate limited per browser. If you hit the limit, grab a free API key and the limit goes away.
- This tool reads the Aave V3 core Pool market on each chain. Isolated or permissioned Aave markets, and Aave V2 deployments, are out of scope.
Related
- Monitor blockchain data from Python — extend the same pattern into a polling loop that alerts on health factor changes
- Multicall3 batching for EVM contract reads — why one expression can replace many
eth_callround trips - evmquery’s free tools — try the Aave health checker and more