Skip to content

Commit 850cb3e

Browse files
committed
Make sure reward pool never gets dusted
1 parent d739887 commit 850cb3e

File tree

1 file changed

+36
-13
lines changed
  • frame/nomination-pools/src

1 file changed

+36
-13
lines changed

frame/nomination-pools/src/lib.rs

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,8 @@ pub mod pallet {
10361036
DoesNotHavePermission,
10371037
/// Metadata exceeds [`T::MaxMetadataLen`]
10381038
MetadataExceedsMaxLen,
1039-
/// Some error occurred that should never happen. This should be reported to the maintainers.
1039+
/// Some error occurred that should never happen. This should be reported to the
1040+
/// maintainers.
10401041
DefensiveError,
10411042
}
10421043

@@ -1327,9 +1328,9 @@ pub mod pallet {
13271328
// Kill accounts from storage by making their balance go below ED. We assume that
13281329
// the accounts have no references that would prevent destruction once we get to
13291330
// this point.
1330-
debug_assert_eq!(
1331-
T::Currency::free_balance(&bonded_pool.reward_account()),
1332-
Zero::zero()
1331+
debug_assert!(
1332+
T::Currency::free_balance(&bonded_pool.reward_account()) >=
1333+
T::Currency::minimum_balance()
13331334
);
13341335
debug_assert_eq!(
13351336
T::Currency::free_balance(&bonded_pool.bonded_account()),
@@ -1366,6 +1367,12 @@ pub mod pallet {
13661367
/// * `root` - The account to set as [`BondedPool::root`].
13671368
/// * `nominator` - The account to set as the [`BondedPool::nominator`].
13681369
/// * `state_toggler` - The account to set as the [`BondedPool::state_toggler`].
1370+
///
1371+
/// # Notes
1372+
///
1373+
/// The caller will transfer `amount` to the bonded account and existential deposit to the
1374+
/// reward account. While the former is returned when the caller withdraws unbonded funds,
1375+
/// the latter is not guaranteed to be returned.
13691376
// TODO: The creator needs to transfer ED to the pool account and then have their delegators
13701377
// `reward_pool_total_earnings` ever set to the balance of the reward pool. This will make
13711378
// an invariant that the reward pool account will always have ED until destroyed.
@@ -1395,8 +1402,12 @@ pub mod pallet {
13951402
Error::<T>::MaxPools
13961403
);
13971404
ensure!(!Delegators::<T>::contains_key(&who), Error::<T>::AccountBelongsToOtherPool);
1405+
ensure!(
1406+
T::Currency::free_balance(&who) >=
1407+
amount.saturating_add(T::Currency::minimum_balance()),
1408+
Error::<T>::MinimumBondNotMet
1409+
);
13981410

1399-
// TODO: transfer ED to reward pool and update reward pool total earnings and balance.
14001411
let pool_id = LastPoolId::<T>::mutate(|id| {
14011412
*id += 1;
14021413
*id
@@ -1408,6 +1419,25 @@ pub mod pallet {
14081419

14091420
let points = bonded_pool.try_bond_delegator(&who, amount, PoolBond::Create)?;
14101421

1422+
// The depositor transfers ED to the pool account and then have their delegator
1423+
// `reward_pool_total_earnings` ever set to the balance of the reward pool. This will
1424+
// ensure the invariant that the reward pool account will not be dusted until the pool
1425+
// is destroyed.
1426+
T::Currency::transfer(
1427+
&who,
1428+
&bonded_pool.reward_account(),
1429+
T::Currency::minimum_balance(),
1430+
ExistenceRequirement::AllowDeath,
1431+
)?;
1432+
let mut reward_pool = RewardPool::<T> {
1433+
balance: Zero::zero(),
1434+
points: U256::zero(),
1435+
total_earnings: Zero::zero(),
1436+
};
1437+
// Make sure the reward pool has correct balance and earnings so the first payout claim
1438+
// does not wipe the ED. This must be done after the transfer
1439+
reward_pool.update_total_earnings_and_balance(bonded_pool.id);
1440+
14111441
Delegators::<T>::insert(
14121442
who.clone(),
14131443
Delegator::<T> {
@@ -1417,14 +1447,7 @@ pub mod pallet {
14171447
unbonding_era: None,
14181448
},
14191449
);
1420-
RewardPools::<T>::insert(
1421-
pool_id,
1422-
RewardPool::<T> {
1423-
balance: Zero::zero(),
1424-
points: U256::zero(),
1425-
total_earnings: Zero::zero(),
1426-
},
1427-
);
1450+
RewardPools::<T>::insert(pool_id, reward_pool);
14281451
ReversePoolIdLookup::<T>::insert(bonded_pool.bonded_account(), pool_id);
14291452
Self::deposit_event(Event::<T>::Created { depositor: who, pool_id });
14301453
bonded_pool.put();

0 commit comments

Comments
 (0)