Withdraw Assets#
Learn how to withdraw assets from your Aave v4 supply positions.
Withdraw supplied assets from your Aave v4 positions to access your funds and any earned interest.
Withdrawing#
Withdrawing can be broken down into the following steps:
Identify the supply position to withdraw from
Preview the impact of the withdraw operation
Withdraw the assets
Identify the Supply Position#
Given a list of user's supply positions, identify the supply position matching the token you want to withdraw and with a withdrawable amount that covers your needs.
For example, let’s say you have identified the following UserSupplyItem object.
Example UserSupplyItem
const supplyPosition: UserSupplyItem = { reserve: { id: "SGVsbG8h", onChainId: "42", chain: { chainId: 1, name: "Ethereum", }, spoke: { address: "0x123…", // … }, asset: { underlying: { address: "0xa0b86a33e6e2ad05ad6c9ac3b6e5e5f6e7b6c1b2", // USDC }, // … }, status: { paused: false, }, // … other reserve properties }, isCollateral: true, balance: { amount: { value: BigDecimal(1042.5), // principal + accrued interest // … }, // … }, withdrawable: { amount: { value: BigDecimal(1000.0), // 1,000 USDC supplied // … }, // … }, // …};Keep in mind that if the asset is used as collateral (isCollateral: true), withdrawing may:
Reduce your borrowing capacity and lower the position’s health factor, increasing the risk of liquidation.
If the collateral has a
reserve.settings.collateralRiskgreater than 0, lower the borrow APY on any open borrow positions in the same Spoke, effectively making those positions cheaper to maintain.
Preview Withdraw#
Preview the impact of a withdraw operation before committing to it.
- React
- TypeScript
- GraphQL
- Solidity
Use the usePreview hook (or the imperative usePreviewAction variant) to preview the impact of the withdraw operation on the user's position.
Where the WithdrawRequest can be as follows:
The PreviewUserPosition shows the impact of the withdraw operation by comparing current and after states, with the table below outlining key fields and how to interpret them.
| Field | Impact |
|---|---|
healthFactor.[current → after]: BigDecimal|null | Higher is better ( null if not applicable) |
riskPremium.[current → after]: PercentNumber | Lower is better |
netApy.[current → after]: PercentNumber | Higher is better |
netCollateral.[current → after]: ExchangeAmount | Higher is better |
netBalance.[current → after]: ExchangeAmount | Updated balance |
maxBorrowingPower.[current → after]: ExchangeAmount | Maximum borrowing power |
remainingBorrowingPower.[current → after]: ExchangeAmount | Remaining borrowing power |
otherConditions: UserPositionConditionVariation[] | Dynamic config changes |
Withdrawing collateral updates the Dynamic Config within the same user position.
The otherConditions field is an array of objects describing the resulting dynamic config changes.
CollateralFactorVariation– Collateral factor changeLiquidationFeeVariation– Liquidation fee changeMaxLiquidationBonusVariation– Maximum liquidation bonus change
You can also specify a different currency to return fiat amounts in.
Step-by-Step#
Now that we know how to preview the impact of a withdraw operation, let's see how to withdraw assets from a supply position.
- React
- TypeScript
- GraphQL
- Solidity
To withdraw assets from an Aave supply position with AaveKit React, follow these steps.
1
Configure Wallet Integration#
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
Define the Withdraw Flow#
Then, use the useWithdraw hook to prepare the withdraw operation.
3
Execute the Withdraw Operation#
Then, execute the desired withdraw operation.
4
Handle the Result#
Finally, handle the result.
Example
const execute = async () => { const result = await withdraw(/* … */);
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(`Invalid withdrawal amount: ${result.error.message}`); break;
case "UnexpectedError": console.error(result.error.message); break; } return; }
console.log("Withdraw successful with hash:", result.value.txHash);};Advanced Usage#
Network Fee#
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 = { withdraw: { sender: evmAddress("0x123…"), // User's address reserve: supplyPosition.reserve.id, amount: { erc20: { value: { exact: bigDecimal(42), // 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.exchange.symbol} {fee.exchange.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 withdraw the asset as the chain's native token using the Native Token Gateway.
Use the reserve.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 Supply Position
const supplyPosition: UserSupplyItem = { reserve: { id: "SGVsbG8h", onChainId: "42", asset: { underlying: { address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", info: { name: "Wrapped Ether", symbol: "WETH", decimals: 18, // … }, isWrappedNativeToken: true, // … }, // … }, spoke: { address: "0x123…", // … }, chain: { chainId: 1, name: "Ethereum", nativeGateway: "0xabc…", }, // … }, balance: { amount: { value: BigDecimal(1.25), // … }, // … }, // …};Specify the amount in the amount field as a native value.
- React
- TypeScript
- GraphQL
- Solidity