Withdrawing (redeeming) from a smart vault

Yelay protocol enables users to make a withdrawal from a smart vault in a standard, cost saving way, or a fast, more gas-intensive way.

To see an example withdrawing implementation of the SDK in the frontend and try it out yourself, check out the the Yelay v2 SDK Cookbook.

Standard withdrawal

To withdraw in a standard way, users interract with the Smart vault manager contract to first make a withdrawal and then claim it.

Initiating withdrawal

Before actually claiming the withdrawal, it has to be initiated in one of two possible way, described bellow.

Options for withdrawing

The withdraws can be made in 2 different ways: using dNFTs or using SVTs.

Option 1: Withdrawing using dNFTs

dNFTs can be exchanged with the protocol for a withdraw NFT (wNFT). Users usually want to burn the whole dNFT at once, but the protocol also supports partial burning (each dNFT consists of 1 million units). Burning multiple dNFTs at once is also possible.

In that case, user must provide:

  • the list of dNFT IDs they want to burn

  • the list of amounts of those dNFTs they woud like to burn (from 1 to 1 million)

  • the amount of SVTs the burning of dNFTs will equate to (this calculation must be done by the user)

Option 2: Withdrawing using SVTs

In theory, the user that wants to make a withdrawal doesn't have to hold any dNFTs as long as they have unredeemed SVTs (SVTs are also transferrable).

To receive the wNFT using only SVTs the user only provides:

  • the amount of SVTs they would like to burn


In both cases, the guards are then run by Smart vault manager contract to verify the request.

After all guards pass:

  • dNFT(s) is/are burnt and SVTs are marked under user (only applicable in withdrawing option 1)

  • SVTs get burnt and a wNFT is minted and marked under the user

Before the withdrawal can be claimed, another flush->DHW->sync cycle must run.

Withdrawing using the SDK

Withdrawal process will be demonstrated by an example that considers a scenario where a user deposited 100 USDC into a USDC Vault. The example demonstates the withdrawal process of the whole deposit and of partial deposit.

In this case, the user would receive 1,000,000 dNFTs (e.g., with an ID of 7), representing a certain number of SVTs or 'shares' in the smart vault. The exact number of SVTs is determined by the ratio between the user's deposit and the vault's total supply.

Let's suppose the deposit was already processed by the flush->DHW->sync cycle.

The examples assume user did not exchange their dNFTs for SVTs (Option 1).

Withdraw scenario 1. User wants to withdraw their entire deposit.

The getUserSvtBalance() function will always return the corresponding number of SVTs associated with the user's deposit, even though the dNFT has not been exchanged.

When constructing the function parameters for withdrawal, the 'shares' parameter should be set to the total number of SVTs the user is entitled to. Since these shares are still locked within the dNFT, the withdrawal process must be instructed to retrieve the shares from this specific dNFT. To achieve this, the 'nftIds' parameter should be set to [7], and the 'nftAmounts' should be set to [1,000,000], effectively converting the entire amount of D-NFTs to SVTs.

Withdraw scenario 2. User wants to do partial withdrawal.

In this scenario, let's assume the user wishes to withdraw 50% of their deposited assets. Since the user only intends to redeem half of their shares, the 'shares' parameter should be set to 50% of the total SVTs associated with the deposit. These shares are still contained within the dNFTs, so the withdrawal process must once again be instructed to utilize the NFTs.

In this scenario, the 'nftIds' parameter should again be set to [7]. Since the user wants to withdraw at least half of the shares, the 'nftAmounts' should be set to a value between 500,000 and 1,000,000.

To withdraw half of the shares, at least 500,000 shares of the dNFTs must be burned. However, burning the entire dNFT is also an option, in which case the user will receive any leftover 'shares' as SVT tokens.

Note: If the entire dNFT is burned but only half the shares are withdrawn, the user won't need to specify the 'nftIds' and 'nftAmounts' arrays in subsequent withdrawals, as the dNFT would have already been converted to SVTs.

In this case, the 'shares' parameter should be set to 50% of the total SVTs, while 'nftIds' and 'nftAmounts' can be left empty ([]). If only half of the NFT was burned in the previous withdrawal, the remaining half must be burned now to complete the withdrawal process.


Before using the redeem function, ensure that you have access to a Signer or Fireblocks provider with the capability to sign transactions.

const redeem = async () => {
    const userNfts = await yelaySDK.getUserDNFTForVault({
        vaultAddress:"vault_address",
        userAddress: signer.address.toLowerCase()
    })
    const shares = await yelaySDK.getUserSVTBalance("vault_address".toLowerCase(), signer.address.toLowerCase())

const redeemBagStruct: RedeemBagStruct = {
        smartVault: "vault_address",
        shares,
        nftIds: userNfts,
        nftAmounts: userNfts.map(input => 1000000),
    };

    const tx = await yelaySDK.redeem(
        redeemBagStruct,
        signer.address,
        true,
    );
}

RedeemBagStruct parameter Explanation:

  • smartVault: Address of smart vault to redeem from.

  • shares: The amount of SVTs to return from a vault - check getUserSVTBalance function.

  • nftIds: dNFT IDs to redeem from the vault - check getUserDNFTForVault function (returns all deposit NFTs for a vault).

  • nftAmounts: Shares of the dNTFs to redeem.

Claiming the withdrawal

User can only claim their withdrawal from the smart vault, if the flush->DHW->sync cycle has been completed for that particular vault in the meantime.

With a wNFT the user can claim their withdrawal by providing it to The Smart vault manager contract.

The contract then:

  • burns the wNFT

  • claims the assets marked under it

  • runs withdrawal actions (in the same way as when depositing)

  • transfers assets to the user.

Claiming using the SDK

The claimWithdrawal function enables users to transfer the withdrawn assets from the Master Wallet directly to their personal account.

const claimRedeem = async () => {

    const userNfts = await yelaySDK.getUserWNFTForVault({
        vaultAddress:"vault_address",
        userAddress: signer.address.toLowerCase()
    })
    const tx = await yelaySDK.claimWithdrawal(
        "vault_address",
        userNfts,
        userNfts.map(input => 1000000),
        signer.address,
    );

    const recpt = await tx.wait()
    console.log(recpt)
}

claimWithdrawal parameter explanation:

  • smartVault: Address of smart vault to withdraw from.

  • nftIds: wNFT IDs to withdraw from the vault - check getUserWNFTForVault function (returns all withdrawal NFTs for a vault).

  • nftAmounts: Shares of NFT to claim.

  • receiver: Address of the receiving account.

Fast withdraw (redeem fast)

There is also a special case, when the user doesn't want to wait for the DHW to finish to be able to claim the withdrawal, so they initiate a fast withdrawal.

When utilizing Fast Withdrawal, users immediately receive the underlying asset tokens, eliminating the need to initiate the withdrawal claiming process separately.

The process here begins in the same manner as with regular withdrawing:

  • user specifies the amount of SVTs they would like to redeem and optionally the lists of the dNFTs and their shares they would like to burn in the process.

  • guards are run

  • dNFT(s) is/are burnt and SVTs are marked under user

  • SVTs get burnt

After that:

  • SSTs are trasfered from the smart vaults to their strategies, where they get burnt

  • the strategies redeem the appropriate amounts of assets from their protocols

  • the assets get transferred to the Master wallet

  • finally, the assets get transferred to the user

Note: Withdrawing using "Fast Withdraw", users must provide their own slippage caluclations.

In that way, users can claim their withdrawal immediately, but they don't enjoy any benefits of Yelay's group processing gas cost optimizations. Calling Fast Withdraw, users bear the gas cost of executing the withdrawal process themselves.

Fast withdrawing using the SDK

const redeemFast = async () => {
    const userNfts = await yelaySDK.getEnrichedUserDNFTForVault({
        vaultAddress: "vault_address".toLowerCase(),
        userAddress: "user_address".toLowerCase()
    })

const shares = await yelaySDK.getUserSVTBalance("vault_address".toLowerCase(), "user_address".toLowerCase())

const redeemBagStruct: RedeemBagStruct = {
        smartVault: "vault_address".toLowerCase(),
        shares,
        nftIds: userNfts.filter(item => !item.isBurned && item.shares.gt(BigNumber.from("0")) && item.isDHWFinished).map(item => item.nftId),
        nftAmounts: userNfts.filter(item => !item.isBurned && item.shares.gt(BigNumber.from("0")) && item.isDHWFinished).map(item => item.shares),
    };

const tx = await yelaySDK.redeemFast(
        redeemBagStruct,
        "user_address".toLowerCase(),
        await rpc.getBlockNumber()
    );

}

RedeemBagStruct parameter Explanation

  • smartVault: Address of smart vault to redeem from.

  • shares: The amount of SVTs to return from a vault - check getUserSVTBalance function.

  • nftIds: dNFT IDs to redeem from the vault - check getUserDNFTForVault function (returns all deposit NFTs for a vault).

  • nftAmounts: Shares of NTF to redeem.

Last updated