Skip to content

Commit

Permalink
Replace MinimumStake to MinimumTotalStake in creator-staking pallet
Browse files Browse the repository at this point in the history
  • Loading branch information
F3Joule committed Feb 1, 2024
1 parent b5937cf commit 89d7513
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 27 deletions.
46 changes: 30 additions & 16 deletions pallets/creator-staking/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,22 @@ impl<T: Config> Pallet<T> {
/// If the stake operation was successful, the given structs are properly modified.
/// If not, an error is returned and the structs are left in an undefined state.
pub(crate) fn stake_to_creator(
backer: &T::AccountId,
backer_stakes: &mut StakesInfoOf<T>,
staking_info: &mut CreatorStakeInfo<BalanceOf<T>>,
creator_stake_info: &mut CreatorStakeInfo<BalanceOf<T>>,
amount: BalanceOf<T>,
current_era: EraIndex,
) -> Result<(), DispatchError> {
let current_stake = backer_stakes.current_stake();
let current_era = Self::current_era();
let staked_before = backer_stakes.current_stake();

// FIXME: this check is not needed if we ensure that backer_stakes is always empty
ensure!(
!current_stake.is_zero() ||
staking_info.backers_count < T::MaxNumberOfBackersPerCreator::get(),
!staked_before.is_zero() ||
creator_stake_info.backers_count < T::MaxNumberOfBackersPerCreator::get(),
Error::<T>::MaxNumberOfBackersExceeded
);
if current_stake.is_zero() {
staking_info.backers_count = staking_info.backers_count.saturating_add(1);
if staked_before.is_zero() {
creator_stake_info.backers_count = creator_stake_info.backers_count.saturating_add(1);
}

backer_stakes
Expand All @@ -119,21 +120,25 @@ impl<T: Config> Pallet<T> {

Self::ensure_can_add_stake_item(backer_stakes)?;

let total_stake = Self::total_staked_amount(&backer)
.saturating_sub(staked_before)
.saturating_add(backer_stakes.current_stake());

ensure!(
backer_stakes.current_stake() >= T::MinimumStake::get(),
total_stake >= T::MinimumTotalStake::get(),
Error::<T>::InsufficientStakingAmount,
);

// Increment the backer's total deposit for a particular creator.
staking_info.total_staked = staking_info.total_staked.saturating_add(amount);
creator_stake_info.total_staked = creator_stake_info.total_staked.saturating_add(amount);

Ok(())
}

/// A utility method used to unstake a specified amount from an arbitrary creator.
///
/// The amount unstaked can be different in case the staked amount would fall bellow
/// `MinimumStake`. In that case, the entire staked amount will be unstaked.
/// `MinimumTotalStake`. In that case, the entire staked amount will be unstaked.
///
/// `StakesInfoOf` and `CreatorStakeInfo` are provided and all checks are made to ensure that
/// it's possible to complete the unstake operation.
Expand All @@ -151,18 +156,20 @@ impl<T: Config> Pallet<T> {
/// unstaked value is returned. If not, an error is returned and the structs are left in
/// an undefined state.
pub(crate) fn calculate_and_apply_stake_decrease(
backer: &T::AccountId,
backer_stakes: &mut StakesInfoOf<T>,
stake_info: &mut CreatorStakeInfo<BalanceOf<T>>,
desired_amount: BalanceOf<T>,
current_era: EraIndex,
) -> Result<BalanceOf<T>, DispatchError> {
let current_era = Self::current_era();
let staked_value = backer_stakes.current_stake();
ensure!(staked_value > Zero::zero(), Error::<T>::NotStakedCreator);

let remaining = staked_value.saturating_sub(desired_amount);
let total_stake = Self::total_staked_amount(&backer);
let remaining = total_stake.saturating_sub(desired_amount);

// If the remaining amount is less than the minimum staking amount, unstake the entire amount.
let amount_to_decrease = if remaining < T::MinimumStake::get() {
// If the remaining amount is less than the minimum total stake, unstake the entire amount.
let amount_to_decrease = if remaining < T::MinimumTotalStake::get() {
stake_info.backers_count = stake_info.backers_count.saturating_sub(1);
staked_value
} else {
Expand All @@ -189,9 +196,9 @@ impl<T: Config> Pallet<T> {
pub(crate) fn update_backer_locks(backer: &T::AccountId, backer_locks: BackerLocksOf<T>) {
if backer_locks.is_empty() {
BackerLocksByAccount::<T>::remove(backer);
T::Currency::remove_lock(STAKING_ID, backer);
T::Currency::remove_lock(STAKING_LOCKS_ID, backer);
} else {
T::Currency::set_lock(STAKING_ID, backer, backer_locks.total_locked, WithdrawReasons::all());
T::Currency::set_lock(STAKING_LOCKS_ID, backer, backer_locks.total_locked, WithdrawReasons::all());
BackerLocksByAccount::<T>::insert(backer, backer_locks);
}
}
Expand Down Expand Up @@ -227,6 +234,13 @@ impl<T: Config> Pallet<T> {
T::PalletId::get().into_account_truncating()
}

pub(crate) fn total_staked_amount(backer: &T::AccountId) -> BalanceOf<T> {
let backer_locks = BackerLocksByAccount::<T>::get(&backer);

backer_locks.total_locked
.saturating_sub(backer_locks.unbonding_info.sum())
}

/// The block rewards are accumulated in this pallet's account during each era.
/// This function takes a snapshot of the pallet's balance accrued during the current era
/// and stores it for future distribution.
Expand Down
17 changes: 8 additions & 9 deletions pallets/creator-staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub mod pallet {

/// An identifier for the locks made in this pallet.
/// Used to determine the locks in this pallet so that they can be replaced or removed.
pub(crate) const STAKING_ID: LockIdentifier = *b"crestake";
pub(crate) const STAKING_LOCKS_ID: LockIdentifier = *b"crestake";

#[pallet::config]
pub trait Config: frame_system::Config + pallet_permissions::Config {
Expand Down Expand Up @@ -68,11 +68,10 @@ pub mod pallet {
#[pallet::constant]
type CreatorRegistrationDeposit: Get<BalanceOf<Self>>;

/// The minimum amount that can be staked to the creator.
/// User can stake less if they already have the minimum staking amount staked to that
/// particular creator.
/// The minimum amount that should be staked in the creator staking system.
/// User can stake less if they already have the minimum stake staked in the system.
#[pallet::constant]
type MinimumStake: Get<BalanceOf<Self>>;
type MinimumTotalStake: Get<BalanceOf<Self>>;

// TODO: make it MinimumRemainingRatio
// (e.g. 0.1 = 10%, so that account can lock only 90% of its balance)
Expand Down Expand Up @@ -409,10 +408,10 @@ pub mod pallet {
Self::creator_stake_info(creator_id, current_era).unwrap_or_default();

Self::stake_to_creator(
&backer,
&mut backer_stakes,
&mut staking_info,
amount_to_stake,
current_era,
)?;

backer_locks.total_locked = backer_locks.total_locked.saturating_add(amount_to_stake);
Expand Down Expand Up @@ -465,7 +464,7 @@ pub mod pallet {
Self::creator_stake_info(creator_id, current_era).unwrap_or_default();

let amount_to_unstake =
Self::calculate_and_apply_stake_decrease(&mut backer_stakes, &mut stake_info, amount, current_era)?;
Self::calculate_and_apply_stake_decrease(&backer, &mut backer_stakes, &mut stake_info, amount)?;

// Update the chunks and write them to storage
let mut backer_locks = Self::backer_locks(&backer);
Expand Down Expand Up @@ -621,10 +620,10 @@ pub mod pallet {

// Backer stake is decreased in `calculate_and_apply_stake_decrease`
let stake_amount_to_move = Self::calculate_and_apply_stake_decrease(
&backer,
&mut backer_stakes_by_source_creator,
&mut source_creator_info,
amount,
current_era,
)?;

// Validate and update target creator related data
Expand All @@ -633,10 +632,10 @@ pub mod pallet {
Self::creator_stake_info(to_creator_id, current_era).unwrap_or_default();

Self::stake_to_creator(
&backer,
&mut backer_stakes_by_target_creator,
&mut target_creator_info,
stake_amount_to_move,
current_era,
)?;

CreatorStakeInfoByEra::<T>::insert(from_creator_id, current_era, source_creator_info);
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,7 +817,7 @@ parameter_types! {

pub const CreatorStakingPalletId: PalletId = PalletId(*b"df/crtst");
pub const CreatorRegistrationDeposit: Balance = 10 * UNIT;
pub const MinimumStake: Balance = 2000 * UNIT;
pub const MinimumTotalStake: Balance = 2000 * UNIT;
pub const MinimumRemainingFreeBalance: Balance = 10 * UNIT;

pub const InitialRewardPerBlock: Balance = 6 * UNIT;
Expand All @@ -833,7 +833,7 @@ impl pallet_creator_staking::Config for Runtime {
type SpacesInterface = Spaces;
type SpacePermissionsProvider = Spaces;
type CreatorRegistrationDeposit = CreatorRegistrationDeposit;
type MinimumStake = MinimumStake;
type MinimumTotalStake = MinimumTotalStake;
type MinimumRemainingFreeBalance = MinimumRemainingFreeBalance;
type MaxNumberOfBackersPerCreator = ConstU32<8000>;
type MaxEraStakeItems = ConstU32<10>;
Expand Down

0 comments on commit 89d7513

Please sign in to comment.