pub fn distribute<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
) -> HandleResult {
    let last_distributed = read_last_distributed(&deps.storage)?;
    if last_distributed + DISTRIBUTION_INTERVAL > env.block.time {
        return Err(StdError::generic_err(
            "Cannot distribute mirror token before interval",
        ));
    }

    let config: Config = read_config(&deps.storage)?;
    let time_elapsed = env.block.time - config.genesis_time;
    let last_time_elapsed = last_distributed - config.genesis_time;
    let mut target_distribution_amount: Uint128 = Uint128::zero();
    for s in config.distribution_schedule.iter() {
        if s.0 > time_elapsed || s.1 < last_time_elapsed {
            continue;
        }

        // min(s.1, time_elapsed) - max(s.0, last_time_elapsed)
        let time_duration =
            std::cmp::min(s.1, time_elapsed) - std::cmp::max(s.0, last_time_elapsed);

        let time_slot = s.1 - s.0;
        let distribution_amount_per_sec: Decimal = Decimal::from_ratio(s.2, time_slot);
        target_distribution_amount += distribution_amount_per_sec * Uint128(time_duration as u128);
    }

    let staking_contract = deps.api.human_address(&config.staking_contract)?;
    let mirror_token = deps.api.human_address(&config.mirror_token)?;

    let total_weight: u32 = read_total_weight(&deps.storage)?;
    let mut distribution_amount: Uint128 = Uint128::zero();
    let weights: Vec<(CanonicalAddr, u32)> = read_all_weight(&deps.storage)?;
    let rewards: Vec<(HumanAddr, Uint128)> = weights
        .iter()
        .map(|w| {
            let amount = Uint128::from(
                target_distribution_amount.u128() * (w.1 as u128) / (total_weight as u128),
            );

            if amount.is_zero() {
                return Err(StdError::generic_err("cannot distribute zero amount"));
            }

            distribution_amount += amount;
            Ok((deps.api.human_address(&w.0)?, amount))
        })
        .filter(|m| m.is_ok())
        .collect::<StdResult<Vec<(HumanAddr, Uint128)>>>()?;

    // store last distributed
    store_last_distributed(&mut deps.storage, env.block.time)?;

    const SPLIT_UNIT: usize = 10;
    let rewards_vec: Vec<Vec<(HumanAddr, Uint128)>> =
        rewards.chunks(SPLIT_UNIT).map(|v| v.to_vec()).collect();

    // mint token to self and try send minted tokens to staking contract
    Ok(HandleResponse {
        messages: rewards_vec
            .into_iter()
            .map(|rewards| {
                Ok(CosmosMsg::Wasm(WasmMsg::Execute {
                    contract_addr: mirror_token.clone(),
                    msg: to_binary(&Cw20HandleMsg::Send {
                        contract: staking_contract.clone(),
                        amount: rewards.iter().map(|v| v.1.u128()).sum::<u128>().into(),
                        msg: Some(to_binary(&StakingCw20HookMsg::DepositReward { rewards })?),
                    })?,
                    send: vec![],
                }))
            })
            .collect::<StdResult<Vec<CosmosMsg>>>()?,
        log: vec![
            log("action", "distribute"),
            log("distribution_amount", distribution_amount.to_string()),
        ],
        data: None,
    })
}
/// Distribute
/// Anyone can execute distribute operation to distribute
/// mirror inflation rewards on the staking pool
Distribute
Anyone can execute distribute operation to distribute
mirror inflation rewards on the staking pool
Distribute Anyone can execute distribute operation to distribute mirror inflation rewards on the staking pool
pub fn distribute<S: Storage, A: Api, Q: Querier>(
    deps: &mut Extern<S, A, Q>,
    env: Env,
) -> HandleResult {
    let last_distributed = read_last_distributed(&deps.storage)?;
    if last_distributed + DISTRIBUTION_INTERVAL > env.block.time {
        return Err(StdError::generic_err(
            "Cannot distribute mirror token before interval",
        ));
    }
    let config: Config = read_config(&deps.storage)?;
    let time_elapsed = env.block.time - config.genesis_time;
    let last_time_elapsed = last_distributed - config.genesis_time;
    let mut target_distribution_amount: Uint128 = Uint128::zero();
    for s in config.distribution_schedule.iter() {
        if s.0 > time_elapsed || s.1 < last_time_elapsed {
            continue;
        }
        // min(s.1, time_elapsed) - max(s.0, last_time_elapsed)
        let time_duration =
            std::cmp::min(s.1, time_elapsed) - std::cmp::max(s.0, last_time_elapsed);
        let time_slot = s.1 - s.0;
        let distribution_amount_per_sec: Decimal = Decimal::from_ratio(s.2, time_slot);
        target_distribution_amount += distribution_amount_per_sec * Uint128(time_duration as u128);
    }
    let staking_contract = deps.api.human_address(&config.staking_contract)?;
    let mirror_token = deps.api.human_address(&config.mirror_token)?;
    let total_weight: u32 = read_total_weight(&deps.storage)?;
    let mut distribution_amount: Uint128 = Uint128::zero();
    let weights: Vec<(CanonicalAddr, u32)> = read_all_weight(&deps.storage)?;
    let rewards: Vec<(HumanAddr, Uint128)> = weights
        .iter()
        .map(|w| {
            let amount = Uint128::from(
                target_distribution_amount.u128() * (w.1 as u128) / (total_weight as u128),
            );
            if amount.is_zero() {
                return Err(StdError::generic_err("cannot distribute zero amount"));
            }
            distribution_amount += amount;
            Ok((deps.api.human_address(&w.0)?, amount))
        })
        .filter(|m| m.is_ok())
        .collect::<StdResult<Vec<(HumanAddr, Uint128)>>>()?;
    // store last distributed
    store_last_distributed(&mut deps.storage, env.block.time)?;
    const SPLIT_UNIT: usize = 10;
    let rewards_vec: Vec<Vec<(HumanAddr, Uint128)>> =
        rewards.chunks(SPLIT_UNIT).map(|v| v.to_vec()).collect();
    // mint token to self and try send minted tokens to staking contract
    Ok(HandleResponse {
        messages: rewards_vec
            .into_iter()
            .map(|rewards| {
                Ok(CosmosMsg::Wasm(WasmMsg::Execute {
                    contract_addr: mirror_token.clone(),
                    msg: to_binary(&Cw20HandleMsg::Send {
                        contract: staking_contract.clone(),
                        amount: rewards.iter().map(|v| v.1.u128()).sum::<u128>().into(),
                        msg: Some(to_binary(&StakingCw20HookMsg::DepositReward { rewards })?),
                    })?,
                    send: vec![],
                }))
            })
            .collect::<StdResult<Vec<CosmosMsg>>>()?,
        log: vec![
            log("action", "distribute"),
            log("distribution_amount", distribution_amount.to_string()),
        ],
        data: None,
    })
}
pub fn distribute < S : Storage , A : Api , Q : Querier > ( deps : & mut Extern < S , A , Q > , env : Env , ) -> HandleResult { let last_distributed = read_last_distributed ( & deps . storage ) ? ; if last_distributed + DISTRIBUTION_INTERVAL > env . block . time { return Err ( StdError :: generic_err ( " " , ) ) ; } let config : Config = read_config ( & deps . storage ) ? ; let time_elapsed = env . block . time - config . genesis_time ; let last_time_elapsed = last_distributed - config . genesis_time ; let mut target_distribution_amount : Uint128 = Uint128 :: zero ( ) ; for s in config . distribution_schedule . iter ( ) { if s . 0 > time_elapsed || s . 1 < last_time_elapsed { continue ; } // min(s.1, time_elapsed) - max(s.0, last_time_elapsed) let time_duration = std :: cmp :: min ( s . 1 , time_elapsed ) - std :: cmp :: max ( s . 0 , last_time_elapsed ) ; let time_slot = s . 1 - s . 0 ; let distribution_amount_per_sec : Decimal = Decimal :: from_ratio ( s . 2 , time_slot ) ; target_distribution_amount += distribution_amount_per_sec * Uint128 ( time_duration as u128 ) ; } let staking_contract = deps . api . human_address ( & config . staking_contract ) ? ; let mirror_token = deps . api . human_address ( & config . mirror_token ) ? ; let total_weight : u32 = read_total_weight ( & deps . storage ) ? ; let mut distribution_amount : Uint128 = Uint128 :: zero ( ) ; let weights : Vec < ( CanonicalAddr , u32 ) > = read_all_weight ( & deps . storage ) ? ; let rewards : Vec < ( HumanAddr , Uint128 ) > = weights . iter ( ) . map ( | w | { let amount = Uint128 :: from ( target_distribution_amount . u128 ( ) * ( w . 1 as u128 ) / ( total_weight as u128 ) , ) ; if amount . is_zero ( ) { return Err ( StdError :: generic_err ( " " ) ) ; } distribution_amount += amount ; Ok ( ( deps . api . human_address ( & w . 0 ) ? , amount ) ) } ) . filter ( | m | m . is_ok ( ) ) . collect :: < StdResult < Vec < ( HumanAddr , Uint128 ) > > > ( ) ? ; // store last distributed store_last_distributed ( & mut deps . storage , env . block . time ) ? ; const SPLIT_UNIT : usize = 10 ; let rewards_vec : Vec < Vec < ( HumanAddr , Uint128 ) > > = rewards . chunks ( SPLIT_UNIT ) . map ( | v | v . to_vec ( ) ) . collect ( ) ; // mint token to self and try send minted tokens to staking contract Ok ( HandleResponse { messages : rewards_vec . into_iter ( ) . map ( | rewards | { Ok ( CosmosMsg :: Wasm ( WasmMsg :: Execute { contract_addr : mirror_token . clone ( ) , msg : to_binary ( & Cw20HandleMsg :: Send { contract : staking_contract . clone ( ) , amount : rewards . iter ( ) . map ( | v | v . 1 . u128 ( ) ) . sum :: < u128 > ( ) . into ( ) , msg : Some ( to_binary ( & StakingCw20HookMsg :: DepositReward { rewards } ) ? ) , } ) ? , send : vec ! [ ] , } ) ) } ) . collect :: < StdResult < Vec < CosmosMsg > > > ( ) ? , log : vec ! [ log ( " " " " ) log ( " " distribution_amount to_string ( ) ) ] , data : None , } ) }
Distribute
Anyone can execute distribute operation to distribute
mirror inflation rewards on the staking pool
Distribute Anyone can execute distribute operation to distribute mirror inflation rewards on the staking pool
deps
&mut Extern<S, A, Q>
env
Env