Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maybe rewards #86

Merged
merged 5 commits into from
Jun 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 33 additions & 27 deletions contracts/provider/external-staking/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ use sylvia::types::{ExecCtx, InstantiateCtx, QueryCtx};
use crate::error::ContractError;
use crate::msg::{
AllPendingRewards, AllTxsResponse, AuthorizedEndpointResponse, ConfigResponse,
IbcChannelResponse, ListRemoteValidatorsResponse, PendingRewards, ReceiveVirtualStake,
StakeInfo, StakesResponse, TxResponse, ValidatorPendingReward,
IbcChannelResponse, ListRemoteValidatorsResponse, MaybePendingRewards, ReceiveVirtualStake,
StakeInfo, StakesResponse, TxResponse, ValidatorPendingRewards,
};
use crate::state::{Config, Distribution, Stake};
use mesh_sync::Tx;
Expand Down Expand Up @@ -776,28 +776,30 @@ impl ExternalStakingContract<'_> {
ctx: QueryCtx,
user: String,
validator: String,
) -> Result<PendingRewards, ContractError> {
) -> Result<MaybePendingRewards, ContractError> {
let user = ctx.deps.api.addr_validate(&user)?;

let stake_lock = self
.stakes
.may_load(ctx.deps.storage, (&user, &validator))?
.unwrap_or_default();
let stake = stake_lock.read()?;

let distribution = self
.distribution
.may_load(ctx.deps.storage, &validator)?
.unwrap_or_default();

let amount = Self::calculate_reward(stake, &distribution)?;
let config = self.config.load(ctx.deps.storage)?;
match stake_lock.read() {
Ok(stake) => {
let distribution = self
.distribution
.may_load(ctx.deps.storage, &validator)?
.unwrap_or_default();

let resp = PendingRewards {
amount: coin(amount.u128(), config.rewards_denom),
};
let amount = Self::calculate_reward(stake, &distribution)?;
let config = self.config.load(ctx.deps.storage)?;

Ok(resp)
Ok(MaybePendingRewards::Rewards(coin(
amount.u128(),
config.rewards_denom,
)))
}
Err(_) => Ok(MaybePendingRewards::Locked {}),
}
}

/// Returns how much rewards are to be withdrawn by particular user, iterating over all validators.
Expand All @@ -824,17 +826,21 @@ impl ExternalStakingContract<'_> {
.take(limit)
.map(|item| {
let (validator, stake_lock) = item?;
let stake = stake_lock.read()?;
let distribution = self
.distribution
.may_load(ctx.deps.storage, &validator)?
.unwrap_or_default();
let amount = Self::calculate_reward(stake, &distribution)?;
Ok::<_, ContractError>(ValidatorPendingReward::new(
validator,
amount.u128(),
&config.rewards_denom,
))
match stake_lock.read() {
Ok(stake) => {
let distribution = self
.distribution
.may_load(ctx.deps.storage, &validator)?
.unwrap_or_default();
let amount = Self::calculate_reward(stake, &distribution)?;
Ok::<_, ContractError>(ValidatorPendingRewards::new(
validator,
amount.u128(),
&config.rewards_denom,
))
}
Err(_) => Ok(ValidatorPendingRewards::new_locked(validator)),
}
})
.collect::<Result<_, _>>()?;

Expand Down
30 changes: 23 additions & 7 deletions contracts/provider/external-staking/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,27 +91,43 @@ pub struct UsersResponse {

/// Response for pending rewards query on one validator
#[cw_serde]
pub struct PendingRewards {
pub amount: Coin,
pub enum MaybePendingRewards {
maurolacy marked this conversation as resolved.
Show resolved Hide resolved
Rewards(Coin),
Locked {},
}

impl MaybePendingRewards {
/// Designed for test code, unwrap or panic if Locked
pub fn unwrap(self) -> Coin {
match self {
MaybePendingRewards::Rewards(coin) => coin,
MaybePendingRewards::Locked {} => panic!("Pending rewards are locked"),
}
}
}
/// Response for pending rewards query on all validator
#[cw_serde]
pub struct AllPendingRewards {
pub rewards: Vec<ValidatorPendingReward>,
pub rewards: Vec<ValidatorPendingRewards>,
}

#[cw_serde]
pub struct ValidatorPendingReward {
pub struct ValidatorPendingRewards {
pub validator: String,
pub amount: Coin,
pub rewards: MaybePendingRewards,
}

impl ValidatorPendingReward {
impl ValidatorPendingRewards {
pub fn new(validator: impl Into<String>, amount: u128, denom: impl Into<String>) -> Self {
Self {
amount: coin(amount, denom),
validator: validator.into(),
rewards: MaybePendingRewards::Rewards(coin(amount, denom)),
}
}
pub fn new_locked(validator: impl Into<String>) -> Self {
Self {
validator: validator.into(),
rewards: MaybePendingRewards::Locked {},
}
}
}
Expand Down
Loading