diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 3a23b894ec..c538f12e20 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -2955,9 +2955,12 @@ impl Pallet { }, (false, false) => { // Equivalent to (current_points / current_balance) * new_funds - balance(u256(current_points).saturating_mul(u256(new_funds))) - // We check for zero above - .div(current_balance) + balance( + u256(current_points) + .saturating_mul(u256(new_funds)) + // We check for zero above + .div(u256(current_balance)), + ) }, } } diff --git a/substrate/frame/nomination-pools/src/tests.rs b/substrate/frame/nomination-pools/src/tests.rs index 7fe1e704bb..657b50e859 100644 --- a/substrate/frame/nomination-pools/src/tests.rs +++ b/substrate/frame/nomination-pools/src/tests.rs @@ -292,6 +292,28 @@ mod bonded_pool { assert_ok!(pool.ok_to_join()); }); } + + #[test] + fn points_and_balance_conversions_are_safe() { + ExtBuilder::default().build_and_execute(|| { + let bonded_pool = BondedPool:: { + id: 123123, + inner: BondedPoolInner { + commission: Commission::default(), + member_counter: 1, + points: u128::MAX, + roles: DEFAULT_ROLES, + state: PoolState::Open, + }, + }; + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), u128::MAX); + + // Max out the points and balance of the pool and make sure the conversion works as + // expected and does not overflow. + assert_eq!(bonded_pool.balance_to_point(u128::MAX), u128::MAX); + assert_eq!(bonded_pool.points_to_balance(u128::MAX), u128::MAX); + }) + } } mod reward_pool {