Advanced Features
Implement advanced Aave v4 features for sophisticated DeFi applications.
As protocol configurations evolve through governance votes, a user position’s risk premium may improve, allowing them to lower the interest on their borrow positions.
Due to protocol technical constraints, users must update their risk premium when eligible. You can identify the user's positions that qualify for an update by checking the betterRiskPremium field (normally null).
Eligible User Position
const position: UserPosition = { __typename: "UserPosition", id: "abc…", user: "0x456…", riskPremium: { normalized: "50", // 50% // … }, betterRiskPremium: { normalized: "25", // 25% - lower is better // … }, spoke: { id: "SGVsbG8h", address: "0x123…", chain: { chainId: 1, name: "Ethereum", // … }, // … }, // …};- React
- TypeScript
- GraphQL
- Solidity
To update the risk premium with AaveKit React, follow these steps.
1
First, instantiate the useSendTransaction hook for the wallet library of your choice.
Viem
import { useWalletClient } from "wagmi";import { useSendTransaction } from "@aave/react/viem";
// …
const { data: wallet } = useWalletClient();const [sendTransaction] = useSendTransaction(wallet);2
Then, use the useUpdateUserRiskPremium hook to prepare the transaction request.
3
Then, execute the transaction.
Update Risk Premium
import { evmAddress, type UserPosition } from "@aave/react";
const execute = async (position: UserPosition) => { const result = await updateRiskPremium({ sender: evmAddress(wallet.account.address), // User's address spoke: position.spoke.id, });};4
Finally, handle the result.
Example
const execute = async () => { const result = await updateRiskPremium(/* … */);
if (result.isErr()) { switch (result.error.name) { case "CancelError": // The user cancelled the operation return;
case "SigningError": console.error( `Failed to sign the transaction: ${result.error.message}` ); break;
case "TimeoutError": console.error(`Transaction timed out: ${result.error.message}`); break;
case "TransactionError": console.error(`Transaction failed: ${result.error.message}`); break;
case "UnexpectedError": console.error(result.error.message); break; } return; }
console.log("Risk premium updated successful with hash:", result.value);};Liquidations
Liquidate unhealthy positions to earn liquidation bonuses and help maintain protocol stability.
Identify Target Position
First, identify a position with a health factor below 1.0 that is eligible for liquidation.
User Position
const position: UserPosition = { __typename: "UserPosition", id: "abc…", user: "0x456…", healthFactor: { value: "0.85", // Below 1.0 - eligible for liquidation // … }, spoke: { address: "0x123…", chain: { chainId: 1, name: "Ethereum", }, // … }, // …};It's not in the scope of this guide to explain how to find positions with a health factor below 1.0 and identify unhealthy positions. See Health Factor for more details.
Select Liquidation Targets
To liquidate a position, we need to choose two things: which debt to repay and which collateral to receive as liquidation bonus.
When choosing positions to liquidate, ensure liquidation bonuses exceed gas costs.
First, identify which debt position to target by looking at the user's borrow positions. Consider targeting debts with larger amounts.
Fetch borrow positions from User Borrows, then pick the specific position you want to liquidate:
Borrow Position
const debtPosition: UserBorrowItem = { reserve: { id: "SGVsbG8h", onChainId: "42", asset: { underlying: { symbol: "WETH", name: "Wrapped Ether" }, }, // … }, debt: { amount: { value: "0.5", }, fiatAmount: { value: "2000", // … }, // … }, // …};If the remaining debt in the target reserve after liquidation is less than $1,000 USD, you must liquidate the entire debt in that reserve.
Next, identify which collateral position to target by examining the user's supply positions that are enabled as collateral. Only supplies with isCollateral: true can be targeted for liquidation.
Choose collateral in the token you prefer to receive as your liquidation bonus by fetching the supply positions from User Supplies:
Supply Position
const collateralPosition: UserSupplyItem = { reserve: { id: "V29ybGQ=", onChainId: "43", asset: { underlying: { symbol: "USDC", name: "USD Coin" }, }, // … }, isCollateral: true, // Can be liquidated withdrawable: { amount: { value: "2000", // … }, // … }, // …};In Aave v4, liquidation bonuses follow a Dutch auction where lower health factors result in higher liquidation bonuses.
Liquidate the Position
After selecting the debt and collateral reserves, choose the repayment amount. You can send an exact value or let the protocol determine the needed amount by using max, restoring the position to a healthy state (HF ≥ 1.0).
- React
- TypeScript
- GraphQL
- Solidity
To liquidate an unhealthy position with AaveKit React, follow these steps:
First, instantiate the useSendTransaction hook for the wallet library of your choice. This wallet will pay the debt tokens and receive the seized collateral.
Viem
import { useWalletClient } from "wagmi";import { useSendTransaction } from "@aave/react/viem";
// …
const { data: wallet } = useWalletClient();const [sendTransaction] = useSendTransaction(wallet);Then, use the useLiquidatePosition hook to prepare the liquidation operation.
Then, execute the liquidation operation. Specify an exact debt amount to cover, or use amount: { max: true } to bring the position back to a healthy state.
Finally, handle the result.
Example
const execute = async (/* … */) => { const result = await liquidatePosition(/* … */);
if (result.isErr()) { switch (result.error.name) { case "CancelError": // The user cancelled the operation return;
case "SigningError": console.error( `Failed to sign the transaction: ${result.error.message}` ); break;
case "TimeoutError": console.error(`Transaction timed out: ${result.error.message}`); break;
case "TransactionError": console.error(`Transaction failed: ${result.error.message}`); break;
case "ValidationError": console.error( `Insufficient balance: ${result.error.cause.required.value} required.` ); break;
case "UnexpectedError": console.error(result.error.message); break; } return; }
console.log("Liquidation successful with hash:", result.value);};