diff --git a/common/cosmwasm-smart-contracts/contracts-common/src/types.rs b/common/cosmwasm-smart-contracts/contracts-common/src/types.rs index 4dca6b173b..46a6b174c6 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/src/types.rs +++ b/common/cosmwasm-smart-contracts/contracts-common/src/types.rs @@ -71,6 +71,16 @@ impl Percent { // we know the cast from u128 to u8 is a safe one since the internal value must be within 0 - 1 range truncate_decimal(hundred * self.0).u128() as u8 } + + pub fn pow(&self, exp: u32) -> Self { + match self.0.checked_pow(exp) { + Ok(res) => Percent(res), + Err(overflow) => { + // since the percent is meant to always be strictly less than 1, this should NEVER hapen + panic!("the percent invariant has been broken. the exponentiation result has overflown: {overflow}"); + } + } + } } impl Display for Percent { diff --git a/nym-api/src/epoch_operations/rewarded_set_assignment.rs b/nym-api/src/epoch_operations/rewarded_set_assignment.rs index 12bc33eaae..aa382f5414 100644 --- a/nym-api/src/epoch_operations/rewarded_set_assignment.rs +++ b/nym-api/src/epoch_operations/rewarded_set_assignment.rs @@ -24,7 +24,7 @@ struct MixnodeWithStakeAndPerformance { impl MixnodeWithStakeAndPerformance { fn to_selection_weight(&self) -> f64 { - let scaled_stake = self.total_stake * self.performance; + let scaled_stake = self.total_stake * self.performance.pow(20); stake_to_f64(scaled_stake) } }