Advanced Features
Implement advanced Aave features for sophisticated DeFi applications.
Efficiency Mode (eMode)
High Efficiency Mode (eMode) in Aave optimizes borrowing power for price-correlated assets. This feature is particularly useful when both supplied and borrowed assets share similar economic price movements, such as stablecoins or derivatives that track the same underlying asset. By using eMode, users benefit from lower collateral requirements, effectively increasing their available borrowing capacity for correlated assets.
To enable efficiency mode and maximize capital efficiency for correlated assets, follow these steps.
First, check the available eMode categories on the market to understand which category to enable.
Let's say we have the following market object with available eMode categories:
Market
const market: Market = { __typename: "Market", name: "Aave V3 Ethereum", address: "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2", chain: { __typename: "Chain", chainId: 1, name: "Ethereum", // … }, eModeCategories: [ { __typename: "EmodeMarketCategory", id: 1, label: "Stablecoins", maxLTV: { __typename: "DecimalValue", value: "0.97", // … }, liquidationThreshold: { __typename: "DecimalValue", value: "0.975", // … }, liquidationPenalty: { __typename: "DecimalValue", value: "0.01", // … }, reserves: [ { __typename: "EmodeMarketReserveInfo", underlyingToken: { __typename: "Currency", symbol: "USDC", name: "USD Coin", address: "0xA0b86a33E6441c8c5f0bb9b7e5e1f8bbf5b78b5c", // … }, canBeCollateral: true, canBeBorrowed: true, }, // … more reserves ], // … }, // … more categories ], // …};
Where each EmodeMarketCategory object has the following properties:
maxLTV.value - Maximum borrowing power (% of supplied collateral you can borrow)
liquidationThreshold.value - How close you can get to liquidation (higher = safer)
liquidationPenalty.value - How much you lose if liquidation happens (lower = better)
reserves[] - an array of EmodeMarketReserveInfo objects, each representing a reserve that indicates if the asset can be used as collateral and/or borrowed in this specific eMode.
Next, we can proceed with creating the transaction request for the desired eMode operation.
- React
- TypeScript
- GraphQL
Use the useUserSetEmode hook to create the transaction request for enabling or disabling efficiency mode.
Enable eMode Category
import { useWalletClient } from "wagmi";import { useUserSetEmode, evmAddress } from "@aave/react";
// …
const { data: walletClient } = useWalletClient();
const [setEmode, settingEmode] = useUserSetEmode();
const execute = async () => { const result = await setEmode({ market: market.address, user: evmAddress(walletClient!.account.address), categoryId: 1, // Enable category 1 (Stablecoins) chainId: market.chain.chainId, });
// …};
To disable eMode, set categoryId to null:
Disable eMode
import { useWalletClient } from "wagmi";import { useUserSetEmode, evmAddress } from "@aave/react";
// …
const { data: walletClient } = useWalletClient();
const [setEmode, settingEmode] = useUserSetEmode();
const execute = async () => { const result = await setEmode({ market: market.address, user: evmAddress(walletClient!.account.address), categoryId: null, // Disable eMode chainId: market.chain.chainId, });
// …};
Finally, send the transaction.
- React
- TypeScript
- GraphQL
Use the useSendTransaction hook for the wallet library of your choice to send the transaction.
Viem
import { useWalletClient } from "wagmi";import { useUserSetEmode } from "@aave/react";import { useSendTransaction } from "@aave/react/viem";
// …
const { data: walletClient } = useWalletClient();
const [setEmode, settingEmode] = useUserSetEmode();const [sendTransaction, sending] = useSendTransaction(walletClient);
// …
// Optional: combine loading statesconst loading = settingEmode.loading || sending.loading;const error = settingEmode.error || sending.error;
// …
const execute = async () => { const result = await setEmode({ // … }).andThen(sendTransaction);
if (result.isErr()) { console.error("eMode operation failed:", result.error); } else { console.log("eMode operation successful with hash:", result.value); }};
Liquidations
Liquidate undercollateralized positions to earn liquidation bonuses and help maintain protocol stability.
First, identify a target user with a health factor below 1.0, and one of their borrow positions that is eligible for liquidation.
const targetUser = evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234");
Let's say you have identified the following user's borrow position:
MarketUserReserveBorrowPosition
const position: MarketUserReserveBorrowPosition = { __typename: "MarketUserReserveBorrowPosition", market: { __typename: "Market", address: "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2", chainId: 1, // … }, currency: { __typename: "Currency", symbol: "WETH", name: "Wrapped Ether", address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // … }, debt: { __typename: "TokenAmount", amount: { __typename: "DecimalValue", value: "1.5", raw: "1500000000000000000", decimals: 18, // … }, // … }, // …};
It's not in the scope of this guide to explain how to users with a health factor below 1.0 and identify an undercollateralized position.
Next, decide which collateral token to receive as a liquidation bonus from the target user's collateral positions.
Let's say you have identified the following collateral position.
MarketUserReserveSupplyPosition
const collateral: MarketUserReserveSupplyPosition = { __typename: "MarketUserReserveSupplyPosition", market: { __typename: "Market", address: "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2", chainId: 1, // … }, currency: { __typename: "Currency", symbol: "USDC", name: "USD Coin", address: "0xA0b86a33E6441c8c5f0bb9b7e5e1f8bbf5b78b5c", // … }, isCollateral: true, canBeCollateral: true, // …};
Then, create the transaction request for the liquidation operation.
- React
- TypeScript
- GraphQL
Use the useLiquidate hook to create the transaction request for liquidating the undercollateralized position.
Liquidate Position
import { useLiquidate } from "@aave/react";
// …
const [liquidate, liquidating] = useLiquidate();
const execute = async () => { const result = await liquidate({ chainId: position.market.chainId, market: position.market.address, user: targetUser, underlyingToken: position.currency.address, debtToCover: { max: true }, // Liquidate maximum debt collateralToken: collateral.currency.address, receiveAToken: false, // Receive collateral as aToken });
// …};
Finally, send the transaction to execute the liquidation.
- React
- TypeScript
- GraphQL
Use the useSendTransaction hook for the wallet library of your choice to send the transaction.
Viem
import { useWalletClient } from "wagmi";import { useLiquidate } from "@aave/react";import { useSendTransaction } from "@aave/react/viem";
// …
const { data: walletClient } = useWalletClient();
const [liquidate, liquidating] = useLiquidate();const [sendTransaction, sending] = useSendTransaction(walletClient);
// …
// Optional: combine loading statesconst loading = liquidating.loading || sending.loading;const error = liquidating.error || sending.error;
// …
const execute = async () => { const result = await liquidate({ // … }).andThen(sendTransaction);
if (result.isErr()) { console.error("Liquidation failed:", result.error); } else { console.log("Liquidation successful with hash:", result.value); }};
User Transaction History
Track user transaction history across Aave markets with detailed transaction information.
- React
- TypeScript
- GraphQL
Use the useUserTransactionHistory hook to fetch paginated transaction history for a user.
Fetch user transaction history ordered by date.
User Transaction History
import { useUserTransactionHistory, evmAddress, chainId, PageSize, OrderDirection,} from "@aave/react";
// …
const { data, loading } = useUserTransactionHistory({ market: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"), user: evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"), chainId: chainId(1), orderBy: { date: OrderDirection.DESC }, pageSize: PageSize.FIFTY,});
if (loading) { return <p>Loading transaction history...</p>;}
// data.items: UserTransactionItem[]// data.pageInfo.next: Cursor | null// data.pageInfo.prev: Cursor | null
Filter transactions by type.
Filtered Transaction History
import { useUserTransactionHistory, evmAddress, chainId, PageSize, OrderDirection, UserTransactionType,} from "@aave/react";
// …
const { data, loading } = useUserTransactionHistory({ market: evmAddress("0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2"), user: evmAddress("0x742d35cc6e5c4ce3b69a2a8c7c8e5f7e9a0b1234"), chainId: chainId(1), filter: [UserTransactionType.SUPPLY, UserTransactionType.WITHDRAW], orderBy: { date: OrderDirection.DESC }, pageSize: PageSize.TEN,});
Transaction Types
The user transaction history includes the following transaction types with their specific data:
SUPPLY - Asset supply transactions with amount and reserve information
WITHDRAW - Asset withdrawal transactions with amount and reserve information
BORROW - Asset borrowing transactions with amount and reserve information
REPAY - Debt repayment transactions with amount and reserve information
USAGE_AS_COLLATERAL - Collateral enable/disable transactions with enabled flag
LIQUIDATION_CALL - Liquidation transactions with collateral and debt repaid details
Filtering Options
Use the filter parameter to narrow down transaction results by transaction types:
filter: [UserTransactionType.SUPPLY, UserTransactionType.WITHDRAW];
Available filter values: SUPPLY, WITHDRAW, BORROW, REPAY, USAGE_AS_COLLATERAL, LIQUIDATION_CALL
Ordering Options
Order transactions using the orderBy parameter:
date - Order by transaction date (ASC or DESC)