🟢redeem_from_mercurial_vault_depository
Permissionless - Callable for redeemable amount input larger than 0 and below global cap and depository cap when minting is enabled
Flow
Checks
Anchor IDL accounts checks
Validates: non-zero
redeemable_amount
Handler
Calculates to total redeem fee based on the
redeemable_amount
Calculates the LP token amount for withdraw with the
redeemable_amount
after deducting the redeem feeCalculates the possible precision loss on transferred LP token amounts
Withdraws
collateral_mint
using LP token amount (less fee) from mercurial token vault to user collateral's ATA in return for the through CPI:mercurial_vault::cpi::withdraw
Calculates the collateral withdrawn by comparing the balance change of
user_collateral
Calculates the redeemed LP token by comparing the balance change of
depository_lp_token_vault
Checks if the redeemed LP token equals to the LP token amount for withdraw (less fee), abort with slippage error otherwise
Checks if the collateral withdrawn is not below the target redeemable amount (less fee) considering the possible precision loss, abort with slippage error otherwise
Burns the redeemable amount of
redeemable_mint
from the userUpdates the accounting in both
depository
andcontroller
Parameters
redeemable_amount
- the amount of redeemable to be redeemed into collateral
Accounts in
// ...
#[derive(Accounts)]
pub struct RedeemFromMercurialVaultDepository<'info> {
/// #1
pub user: Signer<'info>,
/// #2
#[account(mut)]
pub payer: Signer<'info>,
/// #3
#[account(
mut,
seeds = [CONTROLLER_NAMESPACE],
bump = controller.load()?.bump,
constraint = controller.load()?.registered_mercurial_vault_depositories.contains(&depository.key()) @UxdError::InvalidDepository,
has_one = redeemable_mint @UxdError::InvalidRedeemableMint
)]
pub controller: AccountLoader<'info, Controller>,
/// #4
#[account(
mut,
seeds = [MERCURIAL_VAULT_DEPOSITORY_NAMESPACE, depository.load()?.mercurial_vault.key().as_ref(), depository.load()?.collateral_mint.as_ref()],
bump = depository.load()?.bump,
has_one = controller @UxdError::InvalidController,
has_one = mercurial_vault @UxdError::InvalidMercurialVault,
has_one = collateral_mint @UxdError::InvalidCollateralMint,
has_one = mercurial_vault_lp_mint @UxdError::InvalidMercurialVaultLpMint,
constraint = depository.load()?.lp_token_vault == depository_lp_token_vault.key() @UxdError::InvalidDepositoryLpTokenVault,
)]
pub depository: AccountLoader<'info, MercurialVaultDepository>,
/// #5
#[account(
mut,
seeds = [REDEEMABLE_MINT_NAMESPACE],
bump = controller.load()?.redeemable_mint_bump,
)]
pub redeemable_mint: Box<Account<'info, Mint>>,
/// #6
#[account(
mut,
constraint = user_redeemable.mint == controller.load()?.redeemable_mint @UxdError::InvalidRedeemableMint,
constraint = &user_redeemable.owner == user.key @UxdError::InvalidOwner,
)]
pub user_redeemable: Box<Account<'info, TokenAccount>>,
/// #7
pub collateral_mint: Box<Account<'info, Mint>>,
/// #8
#[account(
mut,
constraint = user_collateral.mint == depository.load()?.collateral_mint @UxdError::InvalidCollateralMint,
constraint = &user_collateral.owner == user.key @UxdError::InvalidOwner,
)]
pub user_collateral: Box<Account<'info, TokenAccount>>,
/// #9
/// Token account holding the LP tokens minted by depositing collateral on mercurial vault
#[account(
mut,
seeds = [MERCURIAL_VAULT_DEPOSITORY_LP_TOKEN_VAULT_NAMESPACE, mercurial_vault.key().as_ref(), collateral_mint.key().as_ref()],
token::authority = depository,
token::mint = mercurial_vault_lp_mint,
bump = depository.load()?.lp_token_vault_bump,
)]
pub depository_lp_token_vault: Box<Account<'info, TokenAccount>>,
/// #10
#[account(
mut,
constraint = mercurial_vault.token_vault == mercurial_vault_collateral_token_safe.key() @UxdError::InvalidMercurialVaultCollateralTokenSafe,
)]
pub mercurial_vault: Box<Account<'info, mercurial_vault::state::Vault>>,
/// #11
#[account(mut)]
pub mercurial_vault_lp_mint: Box<Account<'info, Mint>>,
/// #12
/// Token account owned by the mercurial vault program. Hold the collateral deposited in the mercurial vault.
#[account(mut)]
pub mercurial_vault_collateral_token_safe: Box<Account<'info, TokenAccount>>,
/// #13
pub mercurial_vault_program: Program<'info, mercurial_vault::program::Vault>,
/// #14
pub system_program: Program<'info, System>,
/// #15
pub token_program: Program<'info, Token>,
}
// ...
Last updated
Was this helpful?