Aave V3 Market Data
Learn how to discover available markets and access detailed market information in Aave.
Market Structure
Aave market data describes lending pools across different chains:
- Market identification (name, chain, address)
- The reserves in the market
- Efficiency Mode (E-Mode) categories and configurations
- Market metrics (total size, available liquidity)
When you provide a user account address, the data also includes user-specific information such as net worth, health factor, and current positions.
The following TypeScript interfaces illustrate the core Market type and its related types:
interface Market {
name: string;
chain: Chain;
address: EvmAddress;
icon: string;
totalMarketSize: BigDecimal;
totalAvailableLiquidity: BigDecimal;
eModeCategories: EmodeMarketCategory[];
userState?: MarketUserState;
borrowReserves: Reserve[];
supplyReserves: Reserve[];
}
interface EmodeMarketCategory {
id: number;
label: string;
maxLTV: PercentValue;
liquidationThreshold: PercentValue;
liquidationPenalty: PercentValue;
reserves: EmodeMarketReserveInfo[];
}
interface MarketUserState {
netWorth: BigDecimal;
netAPY: PercentValue;
userEarnedAPY: PercentValue;
userDebtAPY: PercentValue;
healthFactor: BigDecimal | null;
eModeEnabled: boolean;
totalCollateralBase: BigDecimal;
totalDebtBase: BigDecimal;
availableBorrowsBase: BigDecimal;
currentLiquidationThreshold: PercentValue;
ltv: PercentValue;
isInIsolationMode: boolean; // deprecated in Aave V3.7
}
interface EmodeReserveInfo {
categoryId: number;
label: string;
maxLTV: PercentValue;
liquidationThreshold: PercentValue;
liquidationPenalty: PercentValue;
canBeCollateral: boolean;
canBeBorrowed: boolean;
hasLtvZero: boolean;
}
The following GraphQL fragments illustrate the core Market type and its related types:
fragment Market on Market {
__typename
name
chain {
...Chain
}
address
icon
totalMarketSize
totalAvailableLiquidity
eModeCategories {
...EmodeMarketCategory
}
userState {
...MarketUserState
}
borrowReserves: reserves(request: { reserveType: BORROW }) {
...Reserve
}
supplyReserves: reserves(request: { reserveType: SUPPLY }) {
...Reserve
}
}
fragment EmodeMarketCategory on EmodeMarketCategory {
__typename
id
label
maxLTV {
...PercentValue
}
liquidationThreshold {
...PercentValue
}
liquidationPenalty {
...PercentValue
}
isolated
reserves {
...EmodeMarketReserveInfo
}
}
fragment EmodeMarketReserveInfo on EmodeMarketReserveInfo {
__typename
underlyingToken {
...Currency
}
canBeCollateral
canBeBorrowed
}
fragment MarketUserState on MarketUserState {
__typename
netWorth
netAPY {
...PercentValue
}
userEarnedAPY {
...PercentValue
}
userDebtAPY {
...PercentValue
}
healthFactor
eModeEnabled
totalCollateralBase
totalDebtBase
availableBorrowsBase
currentLiquidationThreshold {
...PercentValue
}
ltv {
...PercentValue
}
isInIsolationMode # deprecated in Aave V3.7
}
fragment MarketInfo on MarketInfo {
__typename
name
chain {
...Chain
}
icon
}
fragment EmodeReserveInfo on EmodeReserveInfo {
__typename
categoryId
label
maxLTV {
...PercentValue
}
liquidationThreshold {
...PercentValue
}
liquidationPenalty {
...PercentValue
}
canBeCollateral
canBeBorrowed
hasLtvZero
}
fragment Chain on Chain {
__typename
name
icon
chainId
}
fragment DecimalValue on DecimalValue {
__typename
raw
decimals
value
}
fragment PercentValue on PercentValue {
__typename
raw
decimals
value
formatted
}
fragment Currency on Currency {
__typename
address
imageUrl
name
symbol
decimals
chainId
}
fragment NativeCurrency on NativeCurrency {
__typename
imageUrl
name
symbol
decimals
chainId
}
fragment TokenAmount on TokenAmount {
__typename
usdPerToken
amount {
...DecimalValue
}
usd
}
Reserve Structure
Each reserve within an Aave market describes the lending and borrowing data for a specific asset:
- Token information (underlying, aToken, vToken addresses and metadata)
- Supply information (APY, liquidity, caps, collateral configuration)
- Borrow information (APY, available liquidity, utilization rates, caps)
- Reserve incentives (Merit programs, Aave governance rewards)
- Market mechanics (flash loans, permits, pause/freeze states)
- Efficiency Mode (E-Mode) configurations for the asset
- Isolation Mode settings Deprecated in Aave V3.7
- User-specific state (balances, borrowable amounts, collateral usage)
When you provide a user account address, the reserve data also includes user-specific information such as current balances, borrowing capacity, and collateral status.
The following TypeScript interfaces and GraphQL fragments illustrate the core Reserve type and its related types:
interface Reserve {
market: MarketInfo;
underlyingToken: Currency;
aToken: Currency;
vToken: Currency;
acceptsNative?: NativeCurrency;
size: TokenAmount;
usdExchangeRate: BigDecimal;
usdOracleAddress: EvmAddress;
isFrozen: boolean;
isPaused: boolean;
flashLoanEnabled: boolean;
permitSupported: boolean;
supplyInfo: ReserveSupplyInfo;
borrowInfo?: ReserveBorrowInfo;
isolationModeConfig?: ReserveIsolationModeConfig; // deprecated in Aave V3.7
eModeInfo: EmodeReserveInfo[];
incentives: ReserveIncentive[];
userState?: ReserveUserState;
}
interface ReserveSupplyInfo {
apy: PercentValue;
total: DecimalValue;
maxLTV: PercentValue;
liquidationThreshold: PercentValue;
liquidationBonus: PercentValue;
canBeCollateral: boolean;
supplyCap: TokenAmount;
supplyCapReached: boolean;
}
interface ReserveBorrowInfo {
apy: PercentValue;
total: TokenAmount;
borrowCap: TokenAmount;
reserveFactor: PercentValue;
availableLiquidity: TokenAmount;
utilizationRate: PercentValue;
variableRateSlope1: PercentValue;
variableRateSlope2: PercentValue;
optimalUsageRate: PercentValue;
borrowingState: ReserveBorrowingState;
borrowCapReached: boolean;
}
// Deprecated in Aave V3.7: Isolation Mode was removed
interface ReserveIsolationModeConfig {
canBeCollateral: boolean;
canBeBorrowed: boolean;
debtCeiling: TokenAmount;
debtCeilingDecimals: number;
totalBorrows: TokenAmount;
}
interface ReserveUserState {
balance: TokenAmount;
suppliable: TokenAmount;
borrowable: TokenAmount;
emode?: EmodeReserveInfo;
canBeCollateral: boolean;
canBeBorrowed: boolean;
isInIsolationMode: boolean; // deprecated in Aave V3.7
}
type ReserveIncentive =
| MeritSupplyIncentive
| MeritBorrowIncentive
| MeritBorrowAndSupplyIncentiveCondition
| AaveSupplyIncentive
| AaveBorrowIncentive;
interface MeritSupplyIncentive {
__typename: "MeritSupplyIncentive";
extraSupplyApr: PercentValue;
claimLink: string;
}
interface MeritBorrowIncentive {
__typename: "MeritBorrowIncentive";
borrowAprDiscount: PercentValue;
claimLink: string;
}
interface MeritBorrowAndSupplyIncentiveCondition {
__typename: "MeritBorrowAndSupplyIncentiveCondition";
extraApr: PercentValue;
supplyToken: Currency;
borrowToken: Currency;
claimLink: string;
}
interface AaveSupplyIncentive {
__typename: "AaveSupplyIncentive";
extraSupplyApr: PercentValue;
rewardTokenAddress: EvmAddress;
rewardTokenSymbol: string;
}
interface AaveBorrowIncentive {
__typename: "AaveBorrowIncentive";
borrowAprDiscount: PercentValue;
rewardTokenAddress: EvmAddress;
rewardTokenSymbol: string;
}
fragment Reserve on Reserve {
__typename
market {
...MarketInfo
}
underlyingToken {
...Currency
}
aToken {
...Currency
}
vToken {
...Currency
}
acceptsNative {
...NativeCurrency
}
size {
...TokenAmount
}
usdExchangeRate
usdOracleAddress
isFrozen
isPaused
flashLoanEnabled
permitSupported
supplyInfo {
...ReserveSupplyInfo
}
borrowInfo {
...ReserveBorrowInfo
}
isolationModeConfig {
...ReserveIsolationModeConfig
}
eModeInfo {
...EmodeReserveInfo
}
incentives {
...ReserveIncentive
}
userState {
...ReserveUserState
}
}
fragment ReserveSupplyInfo on ReserveSupplyInfo {
__typename
apy {
...PercentValue
}
total {
...DecimalValue
}
maxLTV {
...PercentValue
}
liquidationThreshold {
...PercentValue
}
liquidationBonus {
...PercentValue
}
canBeCollateral
supplyCap {
...TokenAmount
}
supplyCapReached
}
fragment ReserveBorrowInfo on ReserveBorrowInfo {
__typename
apy {
...PercentValue
}
total {
...TokenAmount
}
borrowCap {
...TokenAmount
}
reserveFactor {
...PercentValue
}
availableLiquidity {
...TokenAmount
}
utilizationRate {
...PercentValue
}
variableRateSlope1 {
...PercentValue
}
variableRateSlope2 {
...PercentValue
}
optimalUsageRate {
...PercentValue
}
borrowingState
borrowCapReached
}
# Deprecated in Aave V3.7: Isolation Mode was removed
fragment ReserveIsolationModeConfig on ReserveIsolationModeConfig {
__typename
canBeCollateral
canBeBorrowed
debtCeiling {
...TokenAmount
}
debtCeilingDecimals
totalBorrows {
...TokenAmount
}
}
fragment ReserveUserState on ReserveUserState {
__typename
balance {
...TokenAmount
}
suppliable {
...TokenAmount
}
borrowable {
...TokenAmount
}
emode {
...EmodeReserveInfo
}
canBeCollateral
canBeBorrowed
isInIsolationMode # deprecated in Aave V3.7
}
fragment ReserveIncentive on ReserveIncentive {
__typename
... on MeritSupplyIncentive {
...MeritSupplyIncentive
}
... on MeritBorrowIncentive {
...MeritBorrowIncentive
}
... on MeritBorrowAndSupplyIncentiveCondition {
...MeritBorrowAndSupplyIncentiveCondition
}
... on AaveSupplyIncentive {
...AaveSupplyIncentive
}
... on AaveBorrowIncentive {
...AaveBorrowIncentive
}
}
fragment MeritSupplyIncentive on MeritSupplyIncentive {
__typename
extraSupplyApr {
...PercentValue
}
claimLink
}
fragment MeritBorrowIncentive on MeritBorrowIncentive {
__typename
borrowAprDiscount {
...PercentValue
}
claimLink
}
fragment MeritBorrowAndSupplyIncentiveCondition on MeritBorrowAndSupplyIncentiveCondition {
__typename
extraApr {
...PercentValue
}
supplyToken {
...Currency
}
borrowToken {
...Currency
}
claimLink
}
fragment AaveSupplyIncentive on AaveSupplyIncentive {
__typename
extraSupplyApr {
...PercentValue
}
rewardTokenAddress
rewardTokenSymbol
}
fragment AaveBorrowIncentive on AaveBorrowIncentive {
__typename
borrowAprDiscount {
...PercentValue
}
rewardTokenAddress
rewardTokenSymbol
}
See Incentive Programs for details.
Listing Available Markets
Discover all available Aave markets across supported blockchain networks.
Use the use hook in React, the markets action in TypeScript, or the markets query in GraphQL to fetch available markets across different chains.
In React, the use hook supports both a loading state and React Suspense.
const { data, loading, error } = useAaveMarkets({
chainIds: ChainId[],
user: EvmAddress | undefined,
borrowsOrderBy: MarketReservesRequestOrderBy | undefined,
suppliesOrderBy: MarketReservesRequestOrderBy | undefined,
});
const { data } = useAaveMarkets({
chainIds: ChainId[],
user: EvmAddress | undefined,
borrowsOrderBy: MarketReservesRequestOrderBy | undefined,
suppliesOrderBy: MarketReservesRequestOrderBy | undefined,
suspense: true,
});
Specify one or more chains to retrieve markets for.
import { useAaveMarkets, chainId } from "@aave/react";
// …
const { data, loading, error } = useAaveMarkets({
chainIds: [chainId(1)],
});
if (loading) {
return <p>Loading…</p>;
}
if (error) {
return <p>{error.message}</p>;
}
// data: Market[]
import { chainId } from "@aave/client";
import { markets } from "@aave/client/actions";
import { client } from "./client";
const result = await markets(client, {
chainIds: [chainId(1)],
});
if (result.isErr()) {
console.error(result.error);
} else {
// result.value: Market[]
console.log(result.value);
}
import { AaveClient } from "@aave/client";
export const client = AaveClient.create();
query {
markets(
request: {
chainIds: [1]
# Optional: include account-level data for each market and reserve
# user: "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"
}
) {
name
chain {
name
chainId
}
address
icon
totalMarketSize
totalAvailableLiquidity
}
}
{
"data": {
"markets": [
{
"name": "Aave V3 Ethereum",
"chain": {
"name": "Ethereum",
"chainId": 1
},
"address": "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
"icon": "https://app.aave.com/icons/networks/ethereum.svg",
"totalMarketSize": "12345678900.50",
"totalAvailableLiquidity": "987654321.75"
}
]
}
}
Use a user address to include account-level data for each market and reserve. In GraphQL, set the optional user field shown in the query above.
import { useAaveMarkets, evmAddress, chainId } from "@aave/react";
const { data, loading, error } = useAaveMarkets({
chainIds: [chainId(1)],
user: evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"),
});
import { markets } from "@aave/client/actions";
import { evmAddress, chainId } from "@aave/client";
import { client } from "./client";
const result = await markets(client, {
chainIds: [chainId(1)],
user: evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"),
});
Fetching a Single Market
Retrieve detailed information about a specific market including reserves and user state.
Use the use hook in React, the market action in TypeScript, or the market query in GraphQL to fetch detailed information about a specific market.
In React, the use hook supports both a loading state and React Suspense.
const { data, loading, error } = useAaveMarket({
address: EvmAddress,
chainId: ChainId,
user: EvmAddress | undefined,
borrowsOrderBy: MarketReservesRequestOrderBy | undefined,
suppliesOrderBy: MarketReservesRequestOrderBy | undefined,
});
const { data } = useAaveMarket({
address: EvmAddress,
chainId: ChainId,
user: EvmAddress | undefined,
borrowsOrderBy: MarketReservesRequestOrderBy,
suppliesOrderBy: MarketReservesRequestOrderBy,
suspense: true,
});
Fetch a specific market by address and chain.
import { useAaveMarket, evmAddress, chainId } from "@aave/react";
// …
const { data, loading, error } = useAaveMarket({
address: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
chainId: chainId(1),
});
if (loading) {
return <p>Loading market…</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
if (!data) {
return <p>Market not found</p>;
}
// data: Market
import { market } from "@aave/client/actions";
import { evmAddress, chainId } from "@aave/client";
import { client } from "./client";
const result = await market(client, {
address: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
chainId: chainId(1),
});
if (result.isErr()) {
console.error(result.error);
} else {
// result.value: Market | null
console.log(result.value);
}
import { AaveClient } from "@aave/client";
export const client = AaveClient.create();
query {
market(
request: {
address: "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"
chainId: 1
# Optional: include account-level data for the market and its reserves
# user: "0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"
}
) {
name
chain {
name
chainId
}
address
totalMarketSize
totalAvailableLiquidity
userState {
netWorth
healthFactor
eModeEnabled
}
reserves {
underlyingToken {
symbol
name
}
supplyInfo {
apy {
raw
decimals
value
formatted
}
canBeCollateral
}
borrowInfo {
apy {
raw
decimals
value
formatted
}
}
incentives {
__typename
... on MeritSupplyIncentive {
extraSupplyApr {
formatted
}
claimLink
}
... on AaveSupplyIncentive {
extraSupplyApr {
formatted
}
rewardTokenSymbol
}
}
}
}
}
{
"data": {
"market": {
"name": "Aave V3 Ethereum",
"chain": {
"name": "Ethereum",
"chainId": 1
},
"address": "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2",
"totalMarketSize": "12345678900.50",
"totalAvailableLiquidity": "987654321.75",
"userState": {
"netWorth": "5000.0",
"healthFactor": "2.5",
"eModeEnabled": false
},
"reserves": [
{
"underlyingToken": {
"symbol": "USDC",
"name": "USD Coin"
},
"supplyInfo": {
"apy": {
"raw": "45000000000000000000000000",
"decimals": 27,
"value": "0.045",
"formatted": "4.5"
},
"canBeCollateral": true
},
"borrowInfo": {
"apy": {
"raw": "65000000000000000000000000",
"decimals": 27,
"value": "0.065",
"formatted": "6.5"
}
},
"incentives": []
}
]
}
}
}
Use a user address to include account-level data for the market and its reserves. In GraphQL, set the optional user field shown in the query above.
import { useAaveMarket, evmAddress, chainId } from "@aave/react";
// …
const { data, loading, error } = useAaveMarket({
address: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
chainId: chainId(1),
user: evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"),
});
import { market } from "@aave/client/actions";
import { evmAddress, chainId } from "@aave/client";
import { client } from "./client";
const result = await market(client, {
address: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
chainId: chainId(1),
user: evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"),
});
APY History
Retrieve historical APY data for reserves to analyze interest rate trends over time.
Use the use and use hooks in React, the borrow and supply actions in TypeScript, or the borrow and supply queries in GraphQL to fetch historical APY data for specific reserves.
In React, both hooks support a loading state and React Suspense.
const { data, loading, error } = useBorrowAPYHistory({
chainId: ChainId,
underlyingToken: EvmAddress,
market: EvmAddress,
window: TimeWindow,
});
const { data, loading, error } = useSupplyAPYHistory({
chainId: ChainId,
underlyingToken: EvmAddress,
market: EvmAddress,
window: TimeWindow,
});
const { data } = useBorrowAPYHistory({
chainId: ChainId,
underlyingToken: EvmAddress,
market: EvmAddress,
window: TimeWindow,
suspense: true,
});
const { data } = useSupplyAPYHistory({
chainId: ChainId,
underlyingToken: EvmAddress,
market: EvmAddress,
window: TimeWindow,
suspense: true,
});
Fetch borrow and supply APY history for a specific reserve over a given time window.
import {
useBorrowAPYHistory,
evmAddress,
chainId,
TimeWindow,
} from "@aave/react";
// …
const { data, loading, error } = useBorrowAPYHistory({
chainId: chainId(1),
underlyingToken: evmAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), // USDC
market: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
window: TimeWindow.LastWeek,
});
if (loading) {
return <p>Loading APY history…</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
// data: APYSample[]
import {
useSupplyAPYHistory,
evmAddress,
chainId,
TimeWindow,
} from "@aave/react";
// …
const { data, loading, error } = useSupplyAPYHistory({
chainId: chainId(1),
underlyingToken: evmAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), // USDC
market: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
window: TimeWindow.LastMonth,
});
if (loading) {
return <p>Loading APY history…</p>;
}
if (error) {
return <p>Error: {error.message}</p>;
}
// data: APYSample[]
import { borrowAPYHistory } from "@aave/client/actions";
import { evmAddress, chainId, TimeWindow } from "@aave/client";
import { client } from "./client";
const result = await borrowAPYHistory(client, {
chainId: chainId(1),
underlyingToken: evmAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), // USDC
market: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
window: TimeWindow.LastWeek,
});
if (result.isErr()) {
console.error(result.error);
} else {
// result.value: APYSample[] | null
result.value?.forEach((sample) => {
console.log(`Date: ${sample.date}, APY: ${sample.avgRate.formatted}%`);
});
}
import { supplyAPYHistory } from "@aave/client/actions";
import { evmAddress, chainId, TimeWindow } from "@aave/client";
import { client } from "./client";
const result = await supplyAPYHistory(client, {
chainId: chainId(1),
underlyingToken: evmAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), // USDC
market: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"),
window: TimeWindow.LastMonth,
});
if (result.isErr()) {
console.error(result.error);
} else {
// result.value: APYSample[] | null
}
import { AaveClient } from "@aave/client";
export const client = AaveClient.create();
query {
history: borrowAPYHistory(
request: {
chainId: 1
underlyingToken: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
market: "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"
window: LAST_WEEK
}
) {
avgRate {
raw
decimals
value
formatted
}
date
}
}
query {
history: supplyAPYHistory(
request: {
chainId: 1
underlyingToken: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
market: "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"
window: LAST_MONTH
}
) {
avgRate {
raw
decimals
value
formatted
}
date
}
}
{
"data": {
"history": [
{
"avgRate": {
"raw": "45000000000000000000000000",
"decimals": 27,
"value": "0.045",
"formatted": "4.5"
},
"date": "2024-01-15T00:00:00Z"
},
{
"avgRate": {
"raw": "46000000000000000000000000",
"decimals": 27,
"value": "0.046",
"formatted": "4.6"
},
"date": "2024-01-16T00:00:00Z"
}
]
}
}
Each returned APYSample contains:
avg: Average APY for the time periodRate date: Timestamp for the data point
Available time windows include (GraphQL enum value in parentheses):
Time(Window. Last Day LAST_)DAY Time(Window. Last Week LAST_)WEEK Time(Window. Last Month LAST_)MONTH Time(Window. Last Six Months LAST_)SIX_ MONTHS Time(Window. Last Year LAST_)YEAR