# Withdraw Assets from Firelight Vault

> Learn how to withdraw assets from a Firelight vault

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/fxrp/firelight/withdraw

This guide demonstrates how to create a withdrawal request from a Firelight vault. The Firelight vault implements the [ERC-4626](https://eips.ethereum.org/EIPS/eip-4626) standard and uses a [period-based logic](https://docs.firelight.finance/technical-documents#period-based-logic) for withdrawals.

Withdrawing assets creates a withdrawal request that is processed after the current period ends. The assets are not immediately transferred; they must be claimed once the period has ended.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

-   [Flare Hardhat Starter Kit](/network/guides/hardhat-foundry-starter-kit)
-   [Flare Network Periphery Contracts](https://www.npmjs.com/package/@flarenetwork/flare-periphery-contracts)
-   Understanding of [FAssets](/fassets/overview)
-   Vault shares in the Firelight vault to withdraw.

## Firelight Vault Withdraw Script[​](#firelight-vault-withdraw-script "Direct link to Firelight Vault Withdraw Script")

The following script demonstrates how to create a withdrawal request from the Firelight vault:

scripts/firelight/withdraw.ts

```
/** * FirelightVault Withdraw Script * * This script creates a withdrawal request from the FirelightVault (ERC-4626). * Withdrawals are delayed and must be claimed after the period ends. */import { ethers } from "hardhat";import { bnToBigInt } from "../utils/core";import type { IFirelightVaultInstance } from "../../typechain-types/contracts/firelight/IFirelightVault";import type { ERC20Instance } from "../../typechain-types/@openzeppelin/contracts/token/ERC20/ERC20";export const FIRELIGHT_VAULT_ADDRESS =  "0x91Bfe6A68aB035DFebb6A770FFfB748C03C0E40B";export const IFirelightVault = artifacts.require("IFirelightVault");const tokensToWithdraw = 1; // Number of tokens to withdraw// @ts-expect-error - Type definitions issue, but works at runtimeconst IERC20 = artifacts.require(  "@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20",);async function getAccount() {  const [signer] = await ethers.getSigners();  return { signer, account: signer.address };}async function getVaultAndAsset() {  const vault = (await IFirelightVault.at(    FIRELIGHT_VAULT_ADDRESS,  )) as IFirelightVaultInstance;  const assetAddress = await vault.asset();  const assetToken = (await IERC20.at(assetAddress)) as ERC20Instance;  return { vault, assetAddress, assetToken };}async function getAssetInfo(assetToken: ERC20Instance) {  const symbol = await assetToken.symbol();  const assetDecimals = (await assetToken.decimals()).toNumber();  return { symbol, assetDecimals };}function logWithdrawInfo(  account: string,  assetAddress: string,  symbol: string,  assetDecimals: number,  withdrawAmount: bigint,) {  console.log("=== Withdraw (ERC-4626) ===");  console.log("Sender:", account);  console.log("Vault:", FIRELIGHT_VAULT_ADDRESS);  console.log("Asset:", assetAddress, `(${symbol}, decimals=${assetDecimals})`);  console.log(    "Withdraw amount:",    withdrawAmount.toString(),    `(= ${tokensToWithdraw} ${symbol})`,  );}async function validateWithdraw(  vault: IFirelightVaultInstance,  account: string,  withdrawAmount: bigint,) {  const maxWithdraw = bnToBigInt(await vault.maxWithdraw(account));  console.log("Max withdraw:", maxWithdraw);  if (withdrawAmount > maxWithdraw) {    console.error(      `Cannot withdraw ${withdrawAmount.toString()} assets. Max allowed: ${maxWithdraw.toString()}`,    );    process.exit(1);  }}async function checkUserBalance(  vault: IFirelightVaultInstance,  account: string,  withdrawAmount: bigint,  assetDecimals: number,) {  const userBalance = await vault.balanceOf(account);  const formattedUserBalance = (    Number(userBalance.toString()) / Math.pow(10, assetDecimals)  ).toFixed(assetDecimals);  console.log(    "User balance (shares):",    userBalance.toString(),    `(= ${formattedUserBalance} shares)`,  );  // Use previewWithdraw to calculate how many shares are needed for this withdrawal  const sharesNeeded = await vault.previewWithdraw(withdrawAmount.toString());  if (bnToBigInt(userBalance) < bnToBigInt(sharesNeeded)) {    console.error(      `Insufficient balance. Need ${sharesNeeded.toString()} shares for withdrawal, have ${userBalance.toString()}`,    );    process.exit(1);  }}async function executeWithdraw(  vault: IFirelightVaultInstance,  withdrawAmount: bigint,  account: string,) {  const withdrawTx = await vault.withdraw(    withdrawAmount.toString(),    account,    account,    { from: account },  );  console.log("Withdraw tx:", withdrawTx.tx);}async function main() {  // 1. Get the account  const { account } = await getAccount();  // 2. Get the vault and asset token  const { vault, assetAddress, assetToken } = await getVaultAndAsset();  // 3. Get asset info (symbol, decimals)  const { symbol, assetDecimals } = await getAssetInfo(assetToken);  // 4. Calculate the withdrawal amount  const withdrawAmount = BigInt(tokensToWithdraw * 10 ** assetDecimals);  // 5. Log withdraw info  logWithdrawInfo(account, assetAddress, symbol, assetDecimals, withdrawAmount);  // 6. Validate the withdrawal (check max withdraw)  await validateWithdraw(vault, account, withdrawAmount);  // 7. Check user balance and shares needed  await checkUserBalance(vault, account, withdrawAmount, assetDecimals);  // 8. Execute the withdrawal  await executeWithdraw(vault, withdrawAmount, account);}main().catch((error) => {  console.error(error);  process.exitCode = 1;});
```

## Script Breakdown[​](#script-breakdown "Direct link to Script Breakdown")

The `main()` function executes the following steps:

1.  **Get the account:** Retrieves the signer account from the Hardhat environment.
2.  **Get the vault and asset token:** Connects to the vault contract and retrieves the underlying asset token.
3.  **Get asset info:** Fetches the asset token's symbol and decimals.
4.  **Calculate the withdrawal amount:** Converts the desired amount into the correct units based on decimals.
5.  **Log withdraw info:** Displays the withdrawal details, including sender, vault, and amount.
6.  **Validate the withdrawal:** Checks if the amount exceeds the maximum allowed.
7.  **Check user balance and shares needed:** Verifies the user has sufficient shares for the withdrawal.
8.  **Execute the withdrawal:** Calls `withdraw()` to create a withdrawal request for the current period.

## Understanding Withdrawal Process[​](#understanding-withdrawal-process "Direct link to Understanding Withdrawal Process")

The Firelight vault uses a period-based withdrawal system:

1.  **Withdrawal Request**: When you call `withdraw`, it creates a withdrawal request associated with the current period.
2.  **Period End**: The withdrawal is processed after the current period ends.
3.  **Claim Withdrawal**: Once the period has ended, you must claim the withdrawal to receive your assets.

This delayed withdrawal mechanism is part of the vault's [period-based logic](https://docs.firelight.finance/technical-documents#period-based-logic) and helps manage liquidity and ensure fair distribution of rewards.

## Running the Script[​](#running-the-script "Direct link to Running the Script")

To run the Firelight vault withdraw script:

1.  Ensure you have the [Flare Hardhat Starter Kit](/network/guides/hardhat-foundry-starter-kit) set up.
2.  Update the `FIRELIGHT_VAULT_ADDRESS` constant with the correct vault address for your network.
3.  Adjust the `tokensToWithdraw` constant to the desired number of tokens.
4.  Ensure your account has sufficient vault shares to cover the withdrawal.
5.  Run the script using Hardhat:

```
yarn hardhat run scripts/firelight/withdraw.ts --network coston2
```

## Output[​](#output "Direct link to Output")

The script outputs the following information:

```
=== Withdraw (ERC-4626) ===Sender: 0x0d09ff7630588E05E2449aBD3dDD1D8d146bc5c2Vault: 0x91Bfe6A68aB035DFebb6A770FFfB748C03C0E40BAsset: 0x0b6A3645c240605887a5532109323A3E12273dc7 (FTestXRP, decimals=6)Withdraw amount: 1000000 (= 1 FTestXRP)Max withdraw: 2000061User balance (shares): 2000061 (= 2.000061 shares)Withdraw tx: 0x23d8f34b582ef9935d3e3686a15e7fff34417ac01f68f7f928b14e2b4ef10ba9
```

## Difference Between Withdraw and Redeem[​](#difference-between-withdraw-and-redeem "Direct link to Difference Between Withdraw and Redeem")

The Firelight vault provides two ways to remove assets:

-   **`withdraw`**: You specify the amount of assets to withdraw, and the vault calculates how many shares need to be burned based on the current exchange rate.
-   **`redeem`**: You specify the number of shares to redeem, and the vault calculates how many assets you'll receive.

Both functions follow the [ERC-4626](https://eips.ethereum.org/EIPS/eip-4626) standard and create withdrawal requests that must be claimed after the period ends.

## Summary[​](#summary "Direct link to Summary")

In this guide, you learned how to create a withdrawal request from a Firelight vault by specifying the amount of assets to withdraw. Remember that withdrawals are delayed and must be claimed after the current period ends.

What's next

To continue your Firelight development journey, you can:

-   Learn how to [claim withdrawals from a Firelight vault](/fxrp/firelight/claim) after the period ends.
-   Learn how to [get Firelight vault status](/fxrp/firelight/status) to monitor your withdrawal requests.
-   Learn how to [redeem assets from a Firelight vault](/fxrp/firelight/redeem) by specifying the number of shares.
-   Learn how to [deposit assets into a Firelight vault](/fxrp/firelight/deposit).
-   Learn how to [mint Firelight vault shares](/fxrp/firelight/mint) by specifying the number of shares.
-   Explore the [FAssets system overview](/fassets/overview) to understand the broader ecosystem.
