Skip to content

Commit 19597cc

Browse files
authored
fix some calculation which use FixedU128 as multiper (#542)
1 parent 66939a4 commit 19597cc

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

rewards/src/lib.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use codec::{FullCodec, HasCompact};
88
use frame_support::{pallet_prelude::*, traits::MaxEncodedLen};
99
use orml_traits::RewardHandler;
1010
use sp_runtime::{
11-
traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Member, Saturating, Zero},
11+
traits::{AtLeast32BitUnsigned, Bounded, MaybeSerializeDeserialize, Member, Saturating, Zero},
1212
FixedPointNumber, FixedPointOperand, FixedU128, RuntimeDebug,
1313
};
1414
use sp_std::{
@@ -102,8 +102,13 @@ impl<T: Config> Pallet<T> {
102102
}
103103

104104
Pools::<T>::mutate(pool, |pool_info| {
105-
let proportion = FixedU128::checked_from_rational(add_amount, pool_info.total_shares).unwrap_or_default();
106-
let reward_inflation = proportion.saturating_mul_int(pool_info.total_rewards);
105+
let reward_inflation = if pool_info.total_shares.is_zero() {
106+
Zero::zero()
107+
} else {
108+
let proportion = FixedU128::checked_from_rational(add_amount, pool_info.total_shares)
109+
.unwrap_or_else(FixedU128::max_value);
110+
proportion.saturating_mul_int(pool_info.total_rewards)
111+
};
107112

108113
pool_info.total_shares = pool_info.total_shares.saturating_add(add_amount);
109114
pool_info.total_rewards = pool_info.total_rewards.saturating_add(reward_inflation);
@@ -132,7 +137,8 @@ impl<T: Config> Pallet<T> {
132137
}
133138

134139
Pools::<T>::mutate(pool, |pool_info| {
135-
let proportion = FixedU128::checked_from_rational(remove_amount, *share).unwrap_or_default();
140+
let proportion = FixedU128::checked_from_rational(remove_amount, *share)
141+
.expect("share is gte remove_amount and not zero which checked before; qed");
136142
let withdrawn_rewards_to_remove = proportion.saturating_mul_int(*withdrawn_rewards);
137143

138144
pool_info.total_shares = pool_info.total_shares.saturating_sub(remove_amount);

rewards/src/tests.rs

+15
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,21 @@ fn add_share_should_work() {
7575
}
7676
);
7777
assert_eq!(RewardsModule::share_and_withdrawn_reward(DOT_POOL, ALICE), (250, 7500));
78+
79+
// overflow occurs when saturating calculation
80+
RewardsModule::add_share(&ALICE, &DOT_POOL, u64::MAX);
81+
assert_eq!(
82+
RewardsModule::pools(DOT_POOL),
83+
PoolInfo {
84+
total_shares: u64::MAX,
85+
total_rewards: u64::MAX,
86+
total_withdrawn_rewards: u64::MAX,
87+
}
88+
);
89+
assert_eq!(
90+
RewardsModule::share_and_withdrawn_reward(DOT_POOL, ALICE),
91+
(u64::MAX, u64::MAX)
92+
);
7893
});
7994
}
8095

0 commit comments

Comments
 (0)