Skip to content
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions substrate/frame/nomination-pools/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pallet-nomination-pools"
version = "22.0.0"
version = "22.0.1"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
Expand All @@ -13,8 +13,12 @@ targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
# parity
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] }
scale-info = { version = "2.10.0", default-features = false, features = ["derive"] }
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [
"derive",
] }
scale-info = { version = "2.10.0", default-features = false, features = [
"derive",
] }

# FRAME
frame-support = { path = "../support", default-features = false, version = "25.0.0" }
Expand All @@ -35,8 +39,8 @@ pallet-balances = { path = "../balances" }
sp-tracing = { path = "../../primitives/tracing" }

[features]
default = [ "std" ]
fuzzing = [ "pallet-balances", "sp-tracing" ]
default = ["std"]
fuzzing = ["pallet-balances", "sp-tracing"]
std = [
"codec/std",
"frame-support/std",
Expand Down
61 changes: 43 additions & 18 deletions substrate/frame/nomination-pools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2116,7 +2116,12 @@ pub mod pallet {
bonded_pool.points,
bonded_pool.commission.current(),
)?;
let _ = Self::do_reward_payout(&who, &mut member, &mut bonded_pool, &mut reward_pool)?;
let _ = Self::do_reward_payout(
&member_account,
&mut member,
&mut bonded_pool,
&mut reward_pool,
)?;

let current_era = T::Staking::current_era();
let unbond_era = T::Staking::bonding_duration().saturating_add(current_era);
Expand Down Expand Up @@ -2879,6 +2884,11 @@ impl<T: Config> Pallet<T> {
bonded_pool: BondedPool<T>,
reward_pool: RewardPool<T>,
) {
// The pool id of a member cannot change in any case, so we use it to make sure
// "member_account" is the right one.
debug_assert_eq!(PoolMembers::<T>::get(member_account).unwrap().pool_id, member.pool_id);
debug_assert_eq!(member.pool_id, bonded_pool.id);

bonded_pool.put();
RewardPools::insert(member.pool_id, reward_pool);
PoolMembers::<T>::insert(member_account, member);
Expand Down Expand Up @@ -2942,6 +2952,7 @@ impl<T: Config> Pallet<T> {
reward_pool: &mut RewardPool<T>,
) -> Result<BalanceOf<T>, DispatchError> {
debug_assert_eq!(member.pool_id, bonded_pool.id);
debug_assert_eq!(&mut PoolMembers::<T>::get(member_account).unwrap(), member);

// a member who has no skin in the game anymore cannot claim any rewards.
ensure!(!member.active_points().is_zero(), Error::<T>::FullyUnbonding);
Expand Down Expand Up @@ -3058,18 +3069,19 @@ impl<T: Config> Pallet<T> {

fn do_bond_extra(
signer: T::AccountId,
who: T::AccountId,
member_account: T::AccountId,
extra: BondExtra<BalanceOf<T>>,
) -> DispatchResult {
if signer != who {
if signer != member_account {
ensure!(
ClaimPermissions::<T>::get(&who).can_bond_extra(),
ClaimPermissions::<T>::get(&member_account).can_bond_extra(),
Error::<T>::DoesNotHavePermission
);
ensure!(extra == BondExtra::Rewards, Error::<T>::BondExtraRestricted);
}

let (mut member, mut bonded_pool, mut reward_pool) = Self::get_member_with_pools(&who)?;
let (mut member, mut bonded_pool, mut reward_pool) =
Self::get_member_with_pools(&member_account)?;

// payout related stuff: we must claim the payouts, and updated recorded payout data
// before updating the bonded pool points, similar to that of `join` transaction.
Expand All @@ -3078,27 +3090,31 @@ impl<T: Config> Pallet<T> {
bonded_pool.points,
bonded_pool.commission.current(),
)?;
let claimed =
Self::do_reward_payout(&who, &mut member, &mut bonded_pool, &mut reward_pool)?;
let claimed = Self::do_reward_payout(
&member_account,
&mut member,
&mut bonded_pool,
&mut reward_pool,
)?;

let (points_issued, bonded) = match extra {
BondExtra::FreeBalance(amount) =>
(bonded_pool.try_bond_funds(&who, amount, BondType::Later)?, amount),
(bonded_pool.try_bond_funds(&member_account, amount, BondType::Later)?, amount),
BondExtra::Rewards =>
(bonded_pool.try_bond_funds(&who, claimed, BondType::Later)?, claimed),
(bonded_pool.try_bond_funds(&member_account, claimed, BondType::Later)?, claimed),
};

bonded_pool.ok_to_be_open()?;
member.points =
member.points.checked_add(&points_issued).ok_or(Error::<T>::OverflowRisk)?;

Self::deposit_event(Event::<T>::Bonded {
member: who.clone(),
member: member_account.clone(),
pool_id: member.pool_id,
bonded,
joined: false,
});
Self::put_member_with_pools(&who, member, bonded_pool, reward_pool);
Self::put_member_with_pools(&member_account, member, bonded_pool, reward_pool);

Ok(())
}
Expand Down Expand Up @@ -3147,18 +3163,27 @@ impl<T: Config> Pallet<T> {
Ok(())
}

fn do_claim_payout(signer: T::AccountId, who: T::AccountId) -> DispatchResult {
if signer != who {
pub(crate) fn do_claim_payout(
signer: T::AccountId,
member_account: T::AccountId,
) -> DispatchResult {
if signer != member_account {
ensure!(
ClaimPermissions::<T>::get(&who).can_claim_payout(),
ClaimPermissions::<T>::get(&member_account).can_claim_payout(),
Error::<T>::DoesNotHavePermission
);
}
let (mut member, mut bonded_pool, mut reward_pool) = Self::get_member_with_pools(&who)?;

let _ = Self::do_reward_payout(&who, &mut member, &mut bonded_pool, &mut reward_pool)?;
let (mut member, mut bonded_pool, mut reward_pool) =
Self::get_member_with_pools(&member_account)?;

let _ = Self::do_reward_payout(
&member_account,
&mut member,
&mut bonded_pool,
&mut reward_pool,
)?;

Self::put_member_with_pools(&who, member, bonded_pool, reward_pool);
Self::put_member_with_pools(&member_account, member, bonded_pool, reward_pool);
Ok(())
}

Expand Down
Loading