Skip to main content

Deposit Assets into Firelight Vault

Overview

This guide demonstrates how to deposit assets into a Firelight vault. The Firelight vault implements the ERC-4626 standard, which allows users to deposit assets (e.g., FXRP) and receive vault shares in return.

Depositing assets is the process of transferring assets to the vault and receiving vault shares, which represent your proportional ownership of the vault's assets.

Prerequisites

Firelight Vault Deposit Script

The following script demonstrates how to deposit assets into the Firelight vault:

scripts/firelight/deposit.ts
/**
* FirelightVault Deposit Script
*
* This script deposits assets into the FirelightVault (ERC-4626).
* It approves tokens and deposits the specified amount, receiving vault shares in return.
*/

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 tokensToDeposit = 1; // Number of tokens to deposit

// @ts-expect-error - Type definitions issue, but works at runtime
const 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 logDepositInfo(
account: string,
assetAddress: string,
symbol: string,
assetDecimals: number,
amount: bigint,
) {
console.log("=== Deposit (ERC-4626) ===");
console.log("Sender:", account);
console.log("Vault:", FIRELIGHT_VAULT_ADDRESS);
console.log("Asset:", assetAddress, `(${symbol}, decimals=${assetDecimals})`);
console.log(
"Deposit amount:",
amount.toString(),
`(= ${tokensToDeposit} ${symbol})`,
);
}

async function validateDeposit(
vault: IFirelightVaultInstance,
account: string,
amount: bigint,
) {
const maxDeposit = bnToBigInt(await vault.maxDeposit(account));
console.log("Max deposit:", maxDeposit.toString());
if (amount > maxDeposit) {
console.error(
`Cannot deposit ${amount.toString()} assets. Max allowed: ${maxDeposit.toString()}`,
);
process.exit(1);
}
}

async function approveTokens(
assetToken: ERC20Instance,
vault: IFirelightVaultInstance,
amount: bigint,
account: string,
) {
const approveTx = await assetToken.approve(vault.address, amount.toString(), {
from: account,
});
console.log("Approve tx:", approveTx.tx);
}

async function executeDeposit(
vault: IFirelightVaultInstance,
amount: bigint,
account: string,
) {
const depositTx = await vault.deposit(amount.toString(), account, {
from: account,
});
console.log("Deposit tx:", depositTx.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 deposit amount
const depositAmount = BigInt(tokensToDeposit * 10 ** assetDecimals);

// 5. Log deposit info
logDepositInfo(account, assetAddress, symbol, assetDecimals, depositAmount);

// 6. Validate the deposit (check max deposit)
await validateDeposit(vault, account, depositAmount);

// 7. Approve tokens for transfer
await approveTokens(assetToken, vault, depositAmount, account);

// 8. Execute the deposit
await executeDeposit(vault, depositAmount, account);
}

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

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 deposit amount: Converts the desired amount into the correct units based on decimals.
  5. Log deposit info: Displays the deposit details, including sender, vault, and amount.
  6. Validate the deposit: Checks if the amount exceeds the maximum allowed.
  7. Approve tokens for transfer: Approves the vault to spend the deposit amount.
  8. Execute the deposit: Calls deposit() to transfer assets and mint shares.

Running the Script

To run the Firelight vault deposit script:

  1. Ensure you have the Flare Hardhat Starter Kit set up.
  2. Update the FIRELIGHT_VAULT_ADDRESS constant with the correct vault address for your network.
  3. Adjust the DEPOSIT_AMOUNT constant to the desired number of tokens.
  4. Ensure your account has sufficient asset balance (e.g., FXRP) to cover the deposit.
  5. Run the script using Hardhat:
npx hardhat run scripts/firelight/deposit.ts --network coston2

Output

The script outputs the following information:

=== Deposit (ERC-4626) ===
Sender: 0x0d09ff7630588E05E2449aBD3dDD1D8d146bc5c2
Vault: 0x91Bfe6A68aB035DFebb6A770FFfB748C03C0E40B
Asset: 0x0b6A3645c240605887a5532109323A3E12273dc7 (FTestXRP, decimals=6)
Deposit amount: 1000000 (= 1 FTestXRP)
Max deposit: 115792089237316195423570985008687907853269984665640564039457584007913129639935
Approve tx: 0x87a36c1009575719fd3adb9a1bb2e3062a601bf910fc7fac3248da71891c39a4
Deposit tx: 0x446b7a171859d676677fc870cff81c7e8c0d618fc3588e60665792da86b94c50

Difference Between Deposit and Mint

The Firelight vault provides two ways to add assets:

  • deposit: You specify the amount of assets to deposit, and the vault calculates how many shares you'll receive based on the current exchange rate.
  • mint: You specify the number of shares you want, and the vault calculates how many assets you need to deposit.

Both functions follow the ERC-4626 standard and result in the same outcome: you deposit assets and receive vault shares.

Summary

In this guide, you learned how to deposit assets into a Firelight vault by specifying the amount of assets to deposit.

What's next

To continue your Firelight development journey, you can: