diff --git a/contracts/oraiswap_rewarder/src/clock.rs b/contracts/oraiswap_rewarder/src/clock.rs new file mode 100644 index 00000000..a85eebfc --- /dev/null +++ b/contracts/oraiswap_rewarder/src/clock.rs @@ -0,0 +1,32 @@ +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{entry_point, Addr, StdResult}; +use cosmwasm_std::{DepsMut, Env, Response}; + +use crate::contract::{distribute, read_staking_tokens}; +use crate::state::{read_config, Config}; + +#[cw_serde] +pub enum SudoMsg { + // default message for Sudo, hard-coded in the Juno module: https://github.com/CosmosContracts/juno/blob/main/x/clock/types/msgs.go#L13 + ClockEndBlock {}, +} + +// contract.rs +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn sudo(deps: DepsMut, env: Env, msg: SudoMsg) -> StdResult { + match msg { + SudoMsg::ClockEndBlock {} => { + if env.block.height % 100 != 0 { + return Ok(Response::new()); + } + // Every 10 blocks this config value increases 1 + let config: Config = read_config(deps.storage)?; + let staking_contract = deps.api.addr_humanize(&config.staking_contract)?; + let staking_tokens: Vec = read_staking_tokens(&deps.querier, staking_contract)? + .into_iter() + .map(|token| deps.api.addr_validate(&token)) + .collect::>>()?; + distribute(deps, env, staking_tokens) + } + } +} diff --git a/contracts/oraiswap_rewarder/src/contract.rs b/contracts/oraiswap_rewarder/src/contract.rs index cea5121a..b67836e6 100644 --- a/contracts/oraiswap_rewarder/src/contract.rs +++ b/contracts/oraiswap_rewarder/src/contract.rs @@ -8,7 +8,9 @@ use crate::state::{ read_config, read_last_distributed, store_config, store_last_distributed, Config, }; -use oraiswap::staking::{ExecuteMsg as StakingExecuteMsg, RewardsPerSecResponse}; +use oraiswap::staking::{ + ExecuteMsg as StakingExecuteMsg, QueryPoolInfoResponse, RewardsPerSecResponse, +}; use oraiswap::staking::{QueryMsg as StakingQueryMsg, RewardMsg}; use oraiswap::rewarder::{ @@ -116,6 +118,10 @@ pub fn distribute(deps: DepsMut, env: Env, staking_tokens: Vec) -> StdResu staking_contract.clone(), staking_token.clone(), )?; + // no need to create a new distribute msg if the reward amount is 0 + if reward_amount.is_zero() { + continue; + } // get total reward amount for a pool let distribution_amount = Uint128::from(reward_amount.u128() * (last_time_elapsed as u128)); @@ -190,10 +196,23 @@ fn _read_pool_reward_per_sec( staking_contract: Addr, staking_token: Addr, ) -> StdResult { - let res: RewardsPerSecResponse = querier.query_wasm_smart( + let res: StdResult = querier.query_wasm_smart( staking_contract, &StakingQueryMsg::RewardsPerSec { staking_token }, - )?; + ); + if let Some(res) = res.ok() { + return Ok(res.assets.iter().map(|a| a.amount).sum()); + } else { + Ok(Uint128::zero()) + } +} + +pub fn read_staking_tokens( + querier: &QuerierWrapper, + staking_contract: Addr, +) -> StdResult> { + let res: Vec = + querier.query_wasm_smart(staking_contract, &StakingQueryMsg::GetPoolsInformation {})?; - Ok(res.assets.iter().map(|a| a.amount).sum()) + Ok(res.into_iter().map(|res| res.asset_key).collect()) } diff --git a/contracts/oraiswap_rewarder/src/lib.rs b/contracts/oraiswap_rewarder/src/lib.rs index fea2cb87..259539bc 100644 --- a/contracts/oraiswap_rewarder/src/lib.rs +++ b/contracts/oraiswap_rewarder/src/lib.rs @@ -1,3 +1,4 @@ +pub mod clock; pub mod contract; pub mod state;