pub fn try_withdraw_liquidity(
    deps: DepsMut,
    env: Env,
    sender: String,
    amount: Uint128,
) -> VaultResult {
    let info: PoolInfoRaw = POOL_INFO.load(deps.storage)?;
    let profit = PROFIT.load(deps.storage)?;
    let state = STATE.load(deps.storage)?;
    let denom = DEPOSIT_INFO.load(deps.storage)?.get_denom()?;
    let fee_config = FEE.load(deps.storage)?;

    if profit.last_balance != Uint128::zero() {
        return Err(StableVaultError::DepositDuringLoan {});
    }

    // Logging var
    let mut attrs = vec![];

    // Calculate share of pool and requested pool value
    let lp_addr = info.liquidity_token.clone();
    let total_share: Uint128 = query_supply(&deps.querier, lp_addr)?;
    let (total_value, _, uaust_value_in_contract) =
        compute_total_value(&env, deps.as_ref(), &info)?;
    // Get treasury fee in LP tokens
    let treasury_fee = get_treasury_fee(deps.as_ref(), amount)?;
    // Share with fee deducted.
    let share_ratio: Decimal = Decimal::from_ratio(amount - treasury_fee, total_share);
    let mut refund_amount: Uint128 = total_value * share_ratio;
    attrs.push(("Post-fee received:", refund_amount.to_string()));

    // Init response
    let mut response = Response::new();
    // Available aUST
    let max_aust_amount = query_token_balance(
        &deps.querier,
        state.aust_address.clone(),
        env.contract.address.clone(),
    )?;
    let mut withdrawn_ust = Asset {
        info: AssetInfo::NativeToken {
            denom: denom.clone(),
        },
        amount: Uint128::zero(),
    };

    // If we have aUST, try repay with that
    if max_aust_amount > Uint128::zero() {
        let aust_exchange_rate = query_aust_exchange_rate(
            env,
            deps.as_ref(),
            state.anchor_money_market_address.to_string(),
        )?;

        if uaust_value_in_contract < refund_amount {
            // Withdraw all aUST left
            let withdraw_msg = anchor_withdraw_msg(
                state.aust_address.clone(),
                state.anchor_money_market_address,
                max_aust_amount,
            )?;
            // Add msg to response and update withdrawn value
            response = response.add_message(withdraw_msg);
            withdrawn_ust.amount = uaust_value_in_contract;
        } else {
            // Repay user share of aUST
            let withdraw_amount = refund_amount * aust_exchange_rate.inv().unwrap();

            let withdraw_msg = anchor_withdraw_msg(
                state.aust_address,
                state.anchor_money_market_address,
                withdraw_amount,
            )?;
            // Add msg to response and update withdrawn value
            response = response.add_message(withdraw_msg);
            withdrawn_ust.amount = refund_amount;
        };
        response = response
            .add_attribute("Max anchor withdrawal", max_aust_amount.to_string())
            .add_attribute("ust_aust_rate", aust_exchange_rate.to_string());

        // Compute tax on Anchor withdraw tx
        let withdrawtx_tax = withdrawn_ust.compute_tax(&deps.querier)?;
        refund_amount -= withdrawtx_tax;
        attrs.push(("After Anchor withdraw:", refund_amount.to_string()));
    };

    // LP token treasury Asset
    let lp_token_treasury_fee = Asset {
        info: AssetInfo::Token {
            contract_addr: info.liquidity_token.to_string(),
        },
        amount: treasury_fee,
    };

    // Construct treasury fee msg.
    let treasury_fee_msg = fee_config.treasury_fee.msg(
        deps.as_ref(),
        lp_token_treasury_fee,
        fee_config.treasury_addr,
    )?;
    attrs.push(("War chest fee:", treasury_fee.to_string()));

    // Construct refund message
    let refund_asset = Asset {
        info: AssetInfo::NativeToken { denom },
        amount: refund_amount,
    };
    let tax_assed = refund_asset.deduct_tax(&deps.querier)?;

    let refund_msg = CosmosMsg::Bank(BankMsg::Send {
        to_address: sender,
        amount: vec![tax_assed],
    });
    // LP burn msg
    let burn_msg = CosmosMsg::Wasm(WasmMsg::Execute {
        contract_addr: info.liquidity_token.to_string(),
        // Burn exludes fee
        msg: to_binary(&Cw20ExecuteMsg::Burn {
            amount: (amount - treasury_fee),
        })?,
        funds: vec![],
    });

    Ok(response
        .add_message(refund_msg)
        .add_message(burn_msg)
        .add_message(treasury_fee_msg)
        .add_attribute("action:", "withdraw_liquidity")
        .add_attributes(attrs))
}
/// Attempt to withdraw deposits. Fees are calculated and deducted in lp tokens.
/// This allowes the war-chest to accumulate a stake in the vault.
/// The refund is taken out of Anchor if possible.
/// Luna holdings are not eligible for withdrawal.
Attempt to withdraw deposits. Fees are calculated and deducted in lp tokens.
This allowes the war-chest to accumulate a stake in the vault.
The refund is taken out of Anchor if possible.
Luna holdings are not eligible for withdrawal.
Attempt to withdraw deposits . Fees are calculated and deducted in lp tokens . This allowes the war - chest to accumulate a stake in the vault . The refund is taken out of Anchor if possible . Luna holdings are not eligible for withdrawal .
pub fn try_withdraw_liquidity(
    deps: DepsMut,
    env: Env,
    sender: String,
    amount: Uint128,
) -> VaultResult {
    let info: PoolInfoRaw = POOL_INFO.load(deps.storage)?;
    let profit = PROFIT.load(deps.storage)?;
    let state = STATE.load(deps.storage)?;
    let denom = DEPOSIT_INFO.load(deps.storage)?.get_denom()?;
    let fee_config = FEE.load(deps.storage)?;
    if profit.last_balance != Uint128::zero() {
        return Err(StableVaultError::DepositDuringLoan {});
    }
    // Logging var
    let mut attrs = vec![];
    // Calculate share of pool and requested pool value
    let lp_addr = info.liquidity_token.clone();
    let total_share: Uint128 = query_supply(&deps.querier, lp_addr)?;
    let (total_value, _, uaust_value_in_contract) =
        compute_total_value(&env, deps.as_ref(), &info)?;
    // Get treasury fee in LP tokens
    let treasury_fee = get_treasury_fee(deps.as_ref(), amount)?;
    // Share with fee deducted.
    let share_ratio: Decimal = Decimal::from_ratio(amount - treasury_fee, total_share);
    let mut refund_amount: Uint128 = total_value * share_ratio;
    attrs.push(("Post-fee received:", refund_amount.to_string()));
    // Init response
    let mut response = Response::new();
    // Available aUST
    let max_aust_amount = query_token_balance(
        &deps.querier,
        state.aust_address.clone(),
        env.contract.address.clone(),
    )?;
    let mut withdrawn_ust = Asset {
        info: AssetInfo::NativeToken {
            denom: denom.clone(),
        },
        amount: Uint128::zero(),
    };
    // If we have aUST, try repay with that
    if max_aust_amount > Uint128::zero() {
        let aust_exchange_rate = query_aust_exchange_rate(
            env,
            deps.as_ref(),
            state.anchor_money_market_address.to_string(),
        )?;
        if uaust_value_in_contract < refund_amount {
            // Withdraw all aUST left
            let withdraw_msg = anchor_withdraw_msg(
                state.aust_address.clone(),
                state.anchor_money_market_address,
                max_aust_amount,
            )?;
            // Add msg to response and update withdrawn value
            response = response.add_message(withdraw_msg);
            withdrawn_ust.amount = uaust_value_in_contract;
        } else {
            // Repay user share of aUST
            let withdraw_amount = refund_amount * aust_exchange_rate.inv().unwrap();
            let withdraw_msg = anchor_withdraw_msg(
                state.aust_address,
                state.anchor_money_market_address,
                withdraw_amount,
            )?;
            // Add msg to response and update withdrawn value
            response = response.add_message(withdraw_msg);
            withdrawn_ust.amount = refund_amount;
        };
        response = response
            .add_attribute("Max anchor withdrawal", max_aust_amount.to_string())
            .add_attribute("ust_aust_rate", aust_exchange_rate.to_string());
        // Compute tax on Anchor withdraw tx
        let withdrawtx_tax = withdrawn_ust.compute_tax(&deps.querier)?;
        refund_amount -= withdrawtx_tax;
        attrs.push(("After Anchor withdraw:", refund_amount.to_string()));
    };
    // LP token treasury Asset
    let lp_token_treasury_fee = Asset {
        info: AssetInfo::Token {
            contract_addr: info.liquidity_token.to_string(),
        },
        amount: treasury_fee,
    };
    // Construct treasury fee msg.
    let treasury_fee_msg = fee_config.treasury_fee.msg(
        deps.as_ref(),
        lp_token_treasury_fee,
        fee_config.treasury_addr,
    )?;
    attrs.push(("War chest fee:", treasury_fee.to_string()));
    // Construct refund message
    let refund_asset = Asset {
        info: AssetInfo::NativeToken { denom },
        amount: refund_amount,
    };
    let tax_assed = refund_asset.deduct_tax(&deps.querier)?;
    let refund_msg = CosmosMsg::Bank(BankMsg::Send {
        to_address: sender,
        amount: vec![tax_assed],
    });
    // LP burn msg
    let burn_msg = CosmosMsg::Wasm(WasmMsg::Execute {
        contract_addr: info.liquidity_token.to_string(),
        // Burn exludes fee
        msg: to_binary(&Cw20ExecuteMsg::Burn {
            amount: (amount - treasury_fee),
        })?,
        funds: vec![],
    });
    Ok(response
        .add_message(refund_msg)
        .add_message(burn_msg)
        .add_message(treasury_fee_msg)
        .add_attribute("action:", "withdraw_liquidity")
        .add_attributes(attrs))
}
pub fn try_withdraw_liquidity ( deps : DepsMut , env : Env , sender : String , amount : Uint128 , ) -> VaultResult { let info : PoolInfoRaw = POOL_INFO . load ( deps . storage ) ? ; let profit = PROFIT . load ( deps . storage ) ? ; let state = STATE . load ( deps . storage ) ? ; let denom = DEPOSIT_INFO . load ( deps . storage ) ? . get_denom ( ) ? ; let fee_config = FEE . load ( deps . storage ) ? ; if profit . last_balance != Uint128 :: zero ( ) { return Err ( StableVaultError :: DepositDuringLoan { } ) ; } // Logging var let mut attrs = vec ! [ ] ; // Calculate share of pool and requested pool value let lp_addr = info . liquidity_token . clone ( ) ; let total_share : Uint128 = query_supply ( & deps . querier , lp_addr ) ? ; let ( total_value , _ , uaust_value_in_contract ) = compute_total_value ( & env , deps . as_ref ( ) , & info ) ? ; // Get treasury fee in LP tokens let treasury_fee = get_treasury_fee ( deps . as_ref ( ) , amount ) ? ; // Share with fee deducted. let share_ratio : Decimal = Decimal :: from_ratio ( amount - treasury_fee , total_share ) ; let mut refund_amount : Uint128 = total_value * share_ratio ; attrs . push ( ( " " , refund_amount . to_string ( ) ) ) ; // Init response let mut response = Response :: new ( ) ; // Available aUST let max_aust_amount = query_token_balance ( & deps . querier , state . aust_address . clone ( ) , env . contract . address . clone ( ) , ) ? ; let mut withdrawn_ust = Asset { info : AssetInfo :: NativeToken { denom : denom . clone ( ) , } , amount : Uint128 :: zero ( ) , } ; // If we have aUST, try repay with that if max_aust_amount > Uint128 :: zero ( ) { let aust_exchange_rate = query_aust_exchange_rate ( env , deps . as_ref ( ) , state . anchor_money_market_address . to_string ( ) , ) ? ; if uaust_value_in_contract < refund_amount { // Withdraw all aUST left let withdraw_msg = anchor_withdraw_msg ( state . aust_address . clone ( ) , state . anchor_money_market_address , max_aust_amount , ) ? ; // Add msg to response and update withdrawn value response = response . add_message ( withdraw_msg ) ; withdrawn_ust . amount = uaust_value_in_contract ; } else { // Repay user share of aUST let withdraw_amount = refund_amount * aust_exchange_rate . inv ( ) . unwrap ( ) ; let withdraw_msg = anchor_withdraw_msg ( state . aust_address , state . anchor_money_market_address , withdraw_amount , ) ? ; // Add msg to response and update withdrawn value response = response . add_message ( withdraw_msg ) ; withdrawn_ust . amount = refund_amount ; } ; response = response . add_attribute ( " " , max_aust_amount . to_string ( ) ) . add_attribute ( " " , aust_exchange_rate . to_string ( ) ) ; // Compute tax on Anchor withdraw tx let withdrawtx_tax = withdrawn_ust . compute_tax ( & deps . querier ) ? ; refund_amount -= withdrawtx_tax ; attrs . push ( ( " " , refund_amount . to_string ( ) ) ) ; } ; // LP token treasury Asset let lp_token_treasury_fee = Asset { info : AssetInfo :: Token { contract_addr : info . liquidity_token . to_string ( ) , } , amount : treasury_fee , } ; // Construct treasury fee msg. let treasury_fee_msg = fee_config . treasury_fee . msg ( deps . as_ref ( ) , lp_token_treasury_fee , fee_config . treasury_addr , ) ? ; attrs . push ( ( " " , treasury_fee . to_string ( ) ) ) ; // Construct refund message let refund_asset = Asset { info : AssetInfo :: NativeToken { denom } , amount : refund_amount , } ; let tax_assed = refund_asset . deduct_tax ( & deps . querier ) ? ; let refund_msg = CosmosMsg :: Bank ( BankMsg :: Send { to_address : sender , amount : vec ! [ tax_assed ] , } ) ; // LP burn msg let burn_msg = CosmosMsg :: Wasm ( WasmMsg :: Execute { contract_addr : info . liquidity_token . to_string ( ) , // Burn exludes fee msg : to_binary ( & Cw20ExecuteMsg :: Burn { amount : ( amount - treasury_fee ) , } ) ? , funds : vec ! [ ] , } ) ; Ok ( response . add_message ( refund_msg ) . add_message ( burn_msg ) . add_message ( treasury_fee_msg ) . add_attribute ( " " , " " ) . add_attributes ( attrs ) ) }
Attempt to withdraw deposits.
Attempt to withdraw deposits .
deps
DepsMut
env
Env
sender
String
amount
Uint128
deps
DepsMut
env
Env
sender
String
amount
Uint128