// Redeem dcc tokens for member reserve tokens.
Redeem dcc tokens for member reserve tokens.
Redeem dcc tokens for member reserve tokens .
fn try_redeem(
    deps: DepsMut,
    info: MessageInfo,
    amount: Uint128,
    reserve_denom: Option<String>,
) -> Result<Response<ProvenanceMsg>, ContractError> {
    // Ensure no funds were sent.
    if !info.funds.is_empty() {
        return Err(contract_err("no funds should be sent during dcc redemption"));
    }
    // Validate params
    if amount.is_zero() {
        return Err(contract_err("invalid redeem amount"));
    }
    // Read state
    let state = config_read(deps.storage).load()?;
    // Ensure message sender is a member.
    let member = members_read(deps.storage).load(info.sender.as_bytes())?;
    // Ensure reserve_denom is always the bank reserve token.
    // Note: originally we supported a specified reserve denom to support other bank reserve tokens.
    let reserve_denom = reserve_denom.unwrap_or_else(|| member.denom.clone());
    if reserve_denom != member.denom {
        return Err(contract_err("unsupported reserve denom"));
    }
    // Ensure member holds at least the requested amount of dcc tokens.
    let balance = deps.querier.query_balance(&member.id, &state.dcc_denom)?;
    if balance.amount < amount {
        return Err(contract_err("insufficient dcc token balance"));
    }
    // Ensure marker holds at least the request amount of reserve token.
    let querier = ProvenanceQuerier::new(&deps.querier);
    let member_marker = querier.get_marker_by_denom(&reserve_denom)?;
    let reserve_balance = member_marker
        .coins
        .into_iter()
        .find(|c| c.denom == reserve_denom)
        .map(|c| c.amount)
        .unwrap_or_else(Uint128::zero);
    if reserve_balance < amount {
        return Err(contract_err("insufficient reserve token balance"));
    }
    // Get dcc marker
    let dcc_marker = querier.get_marker_by_denom(&state.dcc_denom)?;
    // Escrow dcc in the marker account for burn.
    let res = Response::new()
        .add_message(transfer_marker_coins(
            amount.u128(),
            &state.dcc_denom,
            dcc_marker.address,
            info.sender.clone(),
        )?)
        // Burn the dcc tokens.
        .add_message(burn_marker_supply(amount.u128(), &state.dcc_denom)?)
        // Withdraw reserve token from marker to member.
        .add_message(withdraw_coins(
            &reserve_denom,
            amount.u128(),
            &reserve_denom,
            info.sender.clone(),
        )?)
        .add_attribute("action", "redeem")
        .add_attribute("member_id", info.sender)
        .add_attribute("denom", &state.dcc_denom)
        .add_attribute("amount", amount)
        .add_attribute("reserve_denom", &reserve_denom);
    Ok(res)
}
fn try_redeem ( deps : DepsMut , info : MessageInfo , amount : Uint128 , reserve_denom : Option < String > , ) -> Result < Response < ProvenanceMsg > , ContractError > { // Ensure no funds were sent. if ! info . funds . is_empty ( ) { return Err ( contract_err ( " " ) ) ; } // Validate params if amount . is_zero ( ) { return Err ( contract_err ( " " ) ) ; } // Read state let state = config_read ( deps . storage ) . load ( ) ? ; // Ensure message sender is a member. let member = members_read ( deps . storage ) . load ( info . sender . as_bytes ( ) ) ? ; // Ensure reserve_denom is always the bank reserve token. // Note: originally we supported a specified reserve denom to support other bank reserve tokens. let reserve_denom = reserve_denom . unwrap_or_else ( | | member . denom . clone ( ) ) ; if reserve_denom != member . denom { return Err ( contract_err ( " " ) ) ; } // Ensure member holds at least the requested amount of dcc tokens. let balance = deps . querier . query_balance ( & member . id , & state . dcc_denom ) ? ; if balance . amount < amount { return Err ( contract_err ( " " ) ) ; } // Ensure marker holds at least the request amount of reserve token. let querier = ProvenanceQuerier :: new ( & deps . querier ) ; let member_marker = querier . get_marker_by_denom ( & reserve_denom ) ? ; let reserve_balance = member_marker . coins . into_iter ( ) . find ( | c | c . denom == reserve_denom ) . map ( | c | c . amount ) . unwrap_or_else ( Uint128 :: zero ) ; if reserve_balance < amount { return Err ( contract_err ( " " ) ) ; } // Get dcc marker let dcc_marker = querier . get_marker_by_denom ( & state . dcc_denom ) ? ; // Escrow dcc in the marker account for burn. let res = Response :: new ( ) . add_message ( transfer_marker_coins ( amount . u128 ( ) , & state . dcc_denom , dcc_marker . address , info . sender . clone ( ) , ) ? ) // Burn the dcc tokens. . add_message ( burn_marker_supply ( amount . u128 ( ) , & state . dcc_denom ) ? ) // Withdraw reserve token from marker to member. . add_message ( withdraw_coins ( & reserve_denom , amount . u128 ( ) , & reserve_denom , info . sender . clone ( ) , ) ? ) . add_attribute ( " " , " " ) . add_attribute ( " " , info . sender ) . add_attribute ( " " , & state . dcc_denom ) . add_attribute ( " " , amount ) . add_attribute ( " " , & reserve_denom ) ; Ok ( res ) }
Redeem dcc tokens for member reserve tokens.
Redeem dcc tokens for member reserve tokens .
deps
DepsMut
info
MessageInfo
amount
Uint128
reserve_denom
Option<String>