Borrow Assets
Learn how to borrow assets from Aave v4 reserves against your collateral.
Borrowing assets from Aave v4 allows you to:
Access liquidity without selling your assets
Leverage your positions with borrowed capital
Repay borrowed assets at any time to close your position
Borrowing assets creates a debt that reduces the position's health factor. Make sure to maintain sufficient collateralization to avoid liquidation. Monitor the position's health factor regularly and consider market volatility.
Borrowing
Borrowing on Aave v4 takes place at the spoke level, and users can only borrow against collateral supplied to that same spoke.
Borrowing can be broken down into the following steps:
Identify the Reserve to borrow from
Preview the impact of the borrow operation
Borrow the assets
Identify the Reserve
The first step is to filter the borrow reserves on the same spoke as the collateral to those marked with canBorrow: true.
Reserves List
const reserves: Reserve[] = [ { id: "SGVsbG8h", onChainId: "42", canBorrow: true, borrowCap: "1000000000.000000", // 1B USDC status: { frozen: false, paused: false, }, spoke: { address: "0x123…", // … }, // … }, { id: "V29ybGQh", onChainId: "43", canBorrow: false, // cannot borrow from this reserve borrowCap: "500000000.000000", // 500M DAI status: { frozen: true, // reserve is frozen paused: false, }, spoke: { address: "0x123…", // … }, // … }, // …];The canBorrow flag confirms that the reserve is active: it isn’t frozen, it isn’t paused, and the borrow cap has not been reached.
From the remaining borrowable reserves, select the one that:
Best matches the desired token with a sufficient borrowable amount — this already accounts for the combined collateral factors (LTV ratios) of the position's collateral
Offers the lowest borrow APY — the effective borrow APY combines the reserve’s borrow APY with the Risk Premium tied to the position's collateral
Reserve
const reserve: Reserve = { id: "SGVsbG8h", onChainId: "42", canBorrow: true, chain: { chainId: 1, name: "Ethereum", }, spoke: { address: "0x123…", // … }, asset: { underlying: { address: "0xa0b86a33e6e2ad05ad6c9ac3b6e5e5f6e7b6c1b2", // USDC }, // … }, userState: { borrowApy: { normalized: "3.73", // 3.73% APY // … }, borrowable: { amount: { value: "10000.000000", // 10,000 USDC }, // … }, // … },};Make sure you include a user address when fetching reserve data—otherwise userState will be null.
Preview Borrow
Preview the impact of a borrow operation before committing to it.
- React
- TypeScript
- GraphQL
- Solidity
Use the usePreview hook (or the imperative usePreviewAction variant) to preview the impact of the borrow operation on the user's position.
Where the BorrowRequest can be as follows:
Borrow ERC-20
const request: BorrowRequest = { sender: evmAddress("0x789…"), // User's address reserve: reserve.id, amount: { erc20: { value: bigDecimal(1000), // 1000 USDC }, },};You can also specify a different currency to return fiat amounts in.
The PreviewUserPosition shows the impact of the borrow operation by comparing current and after states, with the table below outlining key fields and how to interpret them.
| Current → After | Impact | |
|---|---|---|
| healthFactor?.current → healthFactor?.after: BigDecimal | Higher is better | |
| riskPremium.current → riskPremium.after: PercentNumber | Lower is better | |
| netApy.current → netApy.after: PercentNumber | Higher is better | |
| netCollateral.current → netCollateral.after: FiatAmount | Higher is better | |
| netBalance.current → netBalance.after: FiatAmount | Updated balance |
Step-by-Step
Now that we know how to identify a reserve to borrow from, and we know how to preview the impact of a borrow operation, let's see how to borrow assets from this reserve.
- React
- TypeScript
- GraphQL
- Solidity
To borrow assets from an Aave reserve with AaveKit React, follow these steps.
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);Then, execute the desired borrow operation.
Borrow ERC-20
import { bigDecimal, evmAddress } from "@aave/react";
const execute = async () => { const result = await borrow({ sender: evmAddress(wallet.account.address), // User's address reserve: reserve.id, amount: { erc20: { value: bigDecimal(100), // 100 USDC }, }, });
// …};Finally, handle the result.
Example
const execute = async () => { const result = await borrow(/* … */);
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;
default: console.error(result.error.message); break; } return; }
console.log("Borrow successful with hash:", result.value);};Advanced Usage
Network Fee
This experimental AaveKit React hook currently works only with Viem or Wagmi integrations. Support for additional wallet libraries may be added later.
Estimate the network cost of any action using the same PreviewAction you pass to the usePreview hook.
Let's consider the following example:
PreviewAction
import { type PreviewAction } from "@aave/react";
const action: PreviewAction = { borrow: { sender: evmAddress("0x789…"), // User's address reserve: reserve.id, amount: { erc20: { value: bigDecimal(1000), // 1000 USDC }, }, },};Use the useNetworkFee hook to estimate both the network fee for the provided action and its fiat equivalent.
Viem
import { type PreviewAction, Currency } from "@aave/react";import { useNetworkFee } from "@aave/react/viem";
function NetworkFee({ action }: { action: PreviewAction }) { const { data: fee, loading, error, } = useNetworkFee({ query: { estimate: action }, currency: Currency.Eur, });
if (loading) return <p>Loading fee…</p>; if (error) return <p>Error: {error.message}</p>;
return ( <p> Network Fee: {fee.amount.value.toDisplayString(2)} {fee.token.info.symbol} <span> ≈{fee.fiatAmount.symbol} {fee.fiatAmount.value.toDisplayString(2)} </span> </p> );}Native Tokens
When the Reserve's underlying token is the wrapped version of the chain's native token (e.g., WETH on Ethereum), you can borrow the asset as the chain's native token using the Native Token Gateway.
Use the asset.underlying.isWrappedNativeToken flag to determine if the underlying token is a wrapped native token. The Native Gateway address is available from the chain details.
WETH Reserve
const reserve: Reserve = { id: "SGVsbG8h", onChainId: "42", borrowCap: "1000000000.000000", // 1B WETH supplyCap: "2000000000.000000", // 2B WETH canBorrow: true, canSupply: true, canUseAsCollateral: true, asset: { underlying: { address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", info: { name: "Wrapped Ether", symbol: "WETH", decimals: 18, // … }, isWrappedNativeToken: true, // … }, // … }, spoke: { address: "0x123…", // … }, chain: { chainId: 1, name: "Ethereum", nativeGateway: "0xabc…", }, // …};Specify the amount in the amount field as a native value.
- React
- TypeScript
- GraphQL
- Solidity
Borrow Native
const execute = async () => { const result = await borrow({ sender: evmAddress(wallet.account.address), // User's address reserve: reserve.id, amount: { native: bigDecimal(1), // 1 ETH }, });
// …};