pub fn execute_claim_lottery(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    lottery_ids: Vec<u64>,
) -> Result<Response, ContractError> {
    let config = CONFIG.load(deps.storage)?;
    let state = STATE.load(deps.storage)?;

    let mut ust_to_send = Uint128::zero();
    let mut glow_to_send = Uint128::zero();

    let current_lottery = read_lottery_info(deps.storage, state.current_lottery);
    if current_lottery.rand_round != 0 {
        return Err(ContractError::LotteryAlreadyStarted {});
    }

    for lottery_id in lottery_ids.clone() {
        let lottery_info = read_lottery_info(deps.storage, lottery_id);
        if !lottery_info.awarded {
            return Err(ContractError::InvalidClaimLotteryNotAwarded(lottery_id));
        }
        //Calculate and add to to_send
        let lottery_key: U64Key = U64Key::from(lottery_id);
        let prize = PRIZES
            .may_load(deps.storage, (lottery_key.clone(), &info.sender))
            .unwrap();
        if let Some(prize) = prize {
            if prize.claimed {
                return Err(ContractError::InvalidClaimPrizeAlreadyClaimed(lottery_id));
            }

            let snapshotted_depositor_stats_info = read_depositor_stats_at_height(
                deps.storage,
                &info.sender,
                lottery_info.block_height,
            );

            let (local_ust_to_send, local_glow_to_send): (Uint128, Uint128) =
                calculate_winner_prize(
                    &deps.querier,
                    &config,
                    &prize,
                    &lottery_info,
                    &snapshotted_depositor_stats_info,
                    &info.sender,
                )?;

            ust_to_send += local_ust_to_send;
            glow_to_send += local_glow_to_send;

            PRIZES.save(
                deps.storage,
                (lottery_key, &info.sender),
                &PrizeInfo {
                    claimed: true,
                    ..prize
                },
            )?;
        }
    }

    // If ust_to_send is zero, don't send anything even if glow_to_send is positive.
    // It should never be the case that ust_to_send is 0 and glow_to_send is positive.
    if ust_to_send == Uint128::zero() {
        return Err(ContractError::InsufficientClaimableFunds {});
    }

    let mut msgs: Vec<CosmosMsg> = vec![];

    // ust_to_send calculations

    // Deduct taxes on the claim
    let net_send = deduct_tax(
        deps.as_ref(),
        coin(ust_to_send.into(), config.stable_denom.clone()),
    )?
    .amount;

    // Double-check if there is enough balance to send in the contract
    let balance = query_balance(
        deps.as_ref(),
        env.contract.address.to_string(),
        config.stable_denom.clone(),
    )?;

    if ust_to_send > balance.into() {
        return Err(ContractError::InsufficientFunds {
            to_send: ust_to_send,
            available_balance: balance,
        });
    }

    msgs.push(CosmosMsg::Bank(BankMsg::Send {
        to_address: info.sender.to_string(),
        amount: vec![Coin {
            denom: config.stable_denom,
            amount: net_send,
        }],
    }));

    // glow_to_send calculations

    if glow_to_send != Uint128::zero() {
        msgs.push(CosmosMsg::Wasm(WasmMsg::Execute {
            contract_addr: config.distributor_contract.to_string(),
            funds: vec![],
            msg: to_binary(&FaucetExecuteMsg::Spend {
                recipient: info.sender.to_string(),
                amount: glow_to_send,
            })?,
        }));
    }

    // Update storage
    STATE.save(deps.storage, &state)?;

    // Send response

    Ok(Response::new().add_messages(msgs).add_attributes(vec![
        attr("action", "claim_lottery"),
        attr("lottery_ids", format!("{:?}", lottery_ids)),
        attr("depositor", info.sender.to_string()),
        attr("redeemed_ust", net_send),
        attr("redeemed_glow", glow_to_send),
    ]))
}
// Send available UST to user from prizes won in the given lottery_id
Send available UST to user from prizes won in the given lottery_id
Send available UST to user from prizes won in the given lottery_id
pub fn execute_claim_lottery(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    lottery_ids: Vec<u64>,
) -> Result<Response, ContractError> {
    let config = CONFIG.load(deps.storage)?;
    let state = STATE.load(deps.storage)?;
    let mut ust_to_send = Uint128::zero();
    let mut glow_to_send = Uint128::zero();
    let current_lottery = read_lottery_info(deps.storage, state.current_lottery);
    if current_lottery.rand_round != 0 {
        return Err(ContractError::LotteryAlreadyStarted {});
    }
    for lottery_id in lottery_ids.clone() {
        let lottery_info = read_lottery_info(deps.storage, lottery_id);
        if !lottery_info.awarded {
            return Err(ContractError::InvalidClaimLotteryNotAwarded(lottery_id));
        }
        //Calculate and add to to_send
        let lottery_key: U64Key = U64Key::from(lottery_id);
        let prize = PRIZES
            .may_load(deps.storage, (lottery_key.clone(), &info.sender))
            .unwrap();
        if let Some(prize) = prize {
            if prize.claimed {
                return Err(ContractError::InvalidClaimPrizeAlreadyClaimed(lottery_id));
            }
            let snapshotted_depositor_stats_info = read_depositor_stats_at_height(
                deps.storage,
                &info.sender,
                lottery_info.block_height,
            );
            let (local_ust_to_send, local_glow_to_send): (Uint128, Uint128) =
                calculate_winner_prize(
                    &deps.querier,
                    &config,
                    &prize,
                    &lottery_info,
                    &snapshotted_depositor_stats_info,
                    &info.sender,
                )?;
            ust_to_send += local_ust_to_send;
            glow_to_send += local_glow_to_send;
            PRIZES.save(
                deps.storage,
                (lottery_key, &info.sender),
                &PrizeInfo {
                    claimed: true,
                    ..prize
                },
            )?;
        }
    }
    // If ust_to_send is zero, don't send anything even if glow_to_send is positive.
    // It should never be the case that ust_to_send is 0 and glow_to_send is positive.
    if ust_to_send == Uint128::zero() {
        return Err(ContractError::InsufficientClaimableFunds {});
    }
    let mut msgs: Vec<CosmosMsg> = vec![];
    // ust_to_send calculations
    // Deduct taxes on the claim
    let net_send = deduct_tax(
        deps.as_ref(),
        coin(ust_to_send.into(), config.stable_denom.clone()),
    )?
    .amount;
    // Double-check if there is enough balance to send in the contract
    let balance = query_balance(
        deps.as_ref(),
        env.contract.address.to_string(),
        config.stable_denom.clone(),
    )?;
    if ust_to_send > balance.into() {
        return Err(ContractError::InsufficientFunds {
            to_send: ust_to_send,
            available_balance: balance,
        });
    }
    msgs.push(CosmosMsg::Bank(BankMsg::Send {
        to_address: info.sender.to_string(),
        amount: vec![Coin {
            denom: config.stable_denom,
            amount: net_send,
        }],
    }));
    // glow_to_send calculations
    if glow_to_send != Uint128::zero() {
        msgs.push(CosmosMsg::Wasm(WasmMsg::Execute {
            contract_addr: config.distributor_contract.to_string(),
            funds: vec![],
            msg: to_binary(&FaucetExecuteMsg::Spend {
                recipient: info.sender.to_string(),
                amount: glow_to_send,
            })?,
        }));
    }
    // Update storage
    STATE.save(deps.storage, &state)?;
    // Send response
    Ok(Response::new().add_messages(msgs).add_attributes(vec![
        attr("action", "claim_lottery"),
        attr("lottery_ids", format!("{:?}", lottery_ids)),
        attr("depositor", info.sender.to_string()),
        attr("redeemed_ust", net_send),
        attr("redeemed_glow", glow_to_send),
    ]))
}
pub fn execute_claim_lottery ( deps : DepsMut , env : Env , info : MessageInfo , lottery_ids : Vec < u64 > , ) -> Result < Response , ContractError > { let config = CONFIG . load ( deps . storage ) ? ; let state = STATE . load ( deps . storage ) ? ; let mut ust_to_send = Uint128 :: zero ( ) ; let mut glow_to_send = Uint128 :: zero ( ) ; let current_lottery = read_lottery_info ( deps . storage , state . current_lottery ) ; if current_lottery . rand_round != 0 { return Err ( ContractError :: LotteryAlreadyStarted { } ) ; } for lottery_id in lottery_ids . clone ( ) { let lottery_info = read_lottery_info ( deps . storage , lottery_id ) ; if ! lottery_info . awarded { return Err ( ContractError :: InvalidClaimLotteryNotAwarded ( lottery_id ) ) ; } //Calculate and add to to_send let lottery_key : U64Key = U64Key :: from ( lottery_id ) ; let prize = PRIZES . may_load ( deps . storage , ( lottery_key . clone ( ) , & info . sender ) ) . unwrap ( ) ; if let Some ( prize ) = prize { if prize . claimed { return Err ( ContractError :: InvalidClaimPrizeAlreadyClaimed ( lottery_id ) ) ; } let snapshotted_depositor_stats_info = read_depositor_stats_at_height ( deps . storage , & info . sender , lottery_info . block_height , ) ; let ( local_ust_to_send , local_glow_to_send ) : ( Uint128 , Uint128 ) = calculate_winner_prize ( & deps . querier , & config , & prize , & lottery_info , & snapshotted_depositor_stats_info , & info . sender , ) ? ; ust_to_send += local_ust_to_send ; glow_to_send += local_glow_to_send ; PRIZES . save ( deps . storage , ( lottery_key , & info . sender ) , & PrizeInfo { claimed : true , .. prize } , ) ? ; } } // If ust_to_send is zero, don't send anything even if glow_to_send is positive. // It should never be the case that ust_to_send is 0 and glow_to_send is positive. if ust_to_send == Uint128 :: zero ( ) { return Err ( ContractError :: InsufficientClaimableFunds { } ) ; } let mut msgs : Vec < CosmosMsg > = vec ! [ ] ; // ust_to_send calculations // Deduct taxes on the claim let net_send = deduct_tax ( deps . as_ref ( ) , coin ( ust_to_send . into ( ) , config . stable_denom . clone ( ) ) , ) ? . amount ; // Double-check if there is enough balance to send in the contract let balance = query_balance ( deps . as_ref ( ) , env . contract . address . to_string ( ) , config . stable_denom . clone ( ) , ) ? ; if ust_to_send > balance . into ( ) { return Err ( ContractError :: InsufficientFunds { to_send : ust_to_send , available_balance : balance , } ) ; } msgs . push ( CosmosMsg :: Bank ( BankMsg :: Send { to_address : info . sender . to_string ( ) , amount : vec ! [ Coin { denom config stable_denom amount net_send } ] , } ) ) ; // glow_to_send calculations if glow_to_send != Uint128 :: zero ( ) { msgs . push ( CosmosMsg :: Wasm ( WasmMsg :: Execute { contract_addr : config . distributor_contract . to_string ( ) , funds : vec ! [ ] , msg : to_binary ( & FaucetExecuteMsg :: Spend { recipient : info . sender . to_string ( ) , amount : glow_to_send , } ) ? , } ) ) ; } // Update storage STATE . save ( deps . storage , & state ) ? ; // Send response Ok ( Response :: new ( ) . add_messages ( msgs ) . add_attributes ( vec ! [ attr ( " " " " ) attr ( " " format ( " " lottery_ids ) ) attr ( " " info sender to_string ( ) ) attr ( " " net_send ) attr ( " " glow_to_send ) ] ) ) }
Send available UST to user from prizes won in the given lottery_id
Send available UST to user from prizes won in the given lottery_id
deps
DepsMut
env
Env
info
MessageInfo
lottery_ids
Vec<u64>
deps
DepsMut
env
Env
info
MessageInfo
lottery_ids
Vec<u64>