# Redeem Assets from Firelight Vault

> Learn how to redeem 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/redeem

This guide demonstrates how to create a redemption 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 redemptions.

Redeeming shares burns vault shares and allows assets to be withdrawn. Redemptions create 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 redeem.

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

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

scripts/firelight/redeem.ts

```
/** * FirelightVault Redeem Script * * This script creates a redemption request from the FirelightVault (ERC-4626). * Redeem burns shares to withdraw assets. Redemptions are delayed and must be claimed after the period ends. */import { ethers } from "hardhat";import type { IFirelightVaultInstance } from "../../typechain-types/contracts/firelight/IFirelightVault";import type { ERC20Instance } from "../../typechain-types/@openzeppelin/contracts/token/ERC20/ERC20";import { bnToBigInt } from "../utils/core";export const FIRELIGHT_VAULT_ADDRESS =  "0x91Bfe6A68aB035DFebb6A770FFfB748C03C0E40B";export const IFirelightVault = artifacts.require("IFirelightVault");const sharesToRedeem = 1; // Number of shares to redeem// @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 logRedeemInfo(  account: string,  assetAddress: string,  symbol: string,  assetDecimals: number,  sharesAmount: bigint,) {  console.log("=== Redeem (ERC-4626) ===");  console.log("Sender:", account);  console.log("Vault:", FIRELIGHT_VAULT_ADDRESS);  console.log("Asset:", assetAddress, `(${symbol}, decimals=${assetDecimals})`);  console.log(    "Shares to redeem:",    sharesAmount.toString(),    `(= ${sharesToRedeem} share${sharesToRedeem > 1 ? "s" : ""})`,  );}async function validateRedeem(  vault: IFirelightVaultInstance,  account: string,  sharesAmount: bigint,) {  const maxRedeem = bnToBigInt(await vault.maxRedeem(account));  console.log("Max redeem:", maxRedeem);  if (sharesAmount > maxRedeem) {    console.error(      `Cannot redeem ${sharesAmount.toString()} shares. Max allowed: ${maxRedeem.toString()}`,    );    process.exit(1);  }}async function checkUserBalance(  vault: IFirelightVaultInstance,  account: string,  sharesAmount: 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)`,  );  if (bnToBigInt(userBalance) < sharesAmount) {    console.error(      `Insufficient balance. Need ${sharesAmount.toString()} shares, have ${userBalance.toString()}`,    );    process.exit(1);  }}async function executeRedeem(  vault: IFirelightVaultInstance,  sharesAmount: bigint,  account: string,) {  const redeemTx = await vault.redeem(    sharesAmount.toString(),    account,    account,    { from: account },  );  console.log("Redeem tx:", redeemTx.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 shares amount to redeem  const sharesAmount = BigInt(sharesToRedeem * 10 ** assetDecimals);  // 5. Log redeem info  logRedeemInfo(account, assetAddress, symbol, assetDecimals, sharesAmount);  // 6. Validate the redeem (check max redeem)  await validateRedeem(vault, account, sharesAmount);  // 7. Check user balance  await checkUserBalance(vault, account, sharesAmount, assetDecimals);  // 8. Execute the redemption  await executeRedeem(vault, sharesAmount, 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 shares amount to redeem:** Converts the desired shares into the correct units based on decimals.
5.  **Log redeem info:** Displays the redemption details, including sender, vault, and shares.
6.  **Validate the redeem:** Checks if the amount exceeds the maximum allowed.
7.  **Check user balance:** Verifies the user has sufficient shares.
8.  **Execute the redemption:** Calls `redeem()` to create a redemption request for the current period.

## Understanding Redemption Process[​](#understanding-redemption-process "Direct link to Understanding Redemption Process")

The Firelight vault uses a period-based redemption system:

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

This delayed redemption 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 redeem 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 `sharesToRedeem` constant to the desired number of shares.
4.  Ensure your account has sufficient vault shares to cover the redemption.
5.  Run the script using Hardhat:

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

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

The script outputs the following information:

```
=== Redeem (ERC-4626) ===Sender: 0x0d09ff7630588E05E2449aBD3dDD1D8d146bc5c2Vault: 0x91Bfe6A68aB035DFebb6A770FFfB748C03C0E40BAsset: 0x0b6A3645c240605887a5532109323A3E12273dc7 (FTestXRP, decimals=6)Shares to redeem: 1000000 (= 1 share)Max redeem: 1000061User balance (shares): 1000061 (= 1.000061 shares)Redeem tx: 0x3f1bd8c766852d3b835bcde79f6d8e20afeeb227d737e0ed28d057dc0e6b2ba9
```

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

The Firelight vault provides two ways to remove assets:

-   **`redeem`**: You specify the number of shares to redeem, and the vault calculates how many assets you'll receive.
-   **`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.

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 redemption request from a Firelight vault by specifying the number of shares to redeem. Remember that redemptions 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 redemption requests.
-   Learn how to [withdraw assets from a Firelight vault](/fxrp/firelight/withdraw) by specifying the amount of assets.
-   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.
