Skip to content

Commit

Permalink
Merge pull request #2696 from subspace/treasury_fix
Browse files Browse the repository at this point in the history
Staking - 1: Accumulate and then mint funds in to treasury when they cross minimum balance
  • Loading branch information
vedhavyas authored Apr 23, 2024
2 parents e914134 + 8cfd386 commit 5a8d0f5
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
4 changes: 2 additions & 2 deletions crates/pallet-domains/src/bundle_storage_fund.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Bundle storage fund
use crate::staking::NewDeposit;
use crate::staking_epoch::mint_into_treasury;
use crate::{BalanceOf, Config, Event, HoldIdentifier, Operators, Pallet};
use codec::{Decode, Encode};
use frame_support::traits::fungible::{Inspect, Mutate, MutateHold};
Expand Down Expand Up @@ -124,8 +125,7 @@ pub fn refund_storage_fee<T: Config>(

// Drop any dust and deregistered/slashed operator's bundle storage fee to the treasury
if !remaining_fee.is_zero() {
T::Currency::mint_into(&T::TreasuryAccount::get(), remaining_fee)
.map_err(|_| Error::MintBalance)?;
mint_into_treasury::<T>(remaining_fee).ok_or(Error::MintBalance)?;
}

Ok(())
Expand Down
5 changes: 5 additions & 0 deletions crates/pallet-domains/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,11 @@ mod pallet {
pub(super) type PermissionedActionAllowedBy<T: Config> =
StorageValue<_, sp_domains::PermissionedActionAllowedBy<T::AccountId>, OptionQuery>;

/// Accumulate treasury funds temporarily until the funds are above Existential despoit.
/// We do this to ensure minting small amounts into treasury would not fail.
#[pallet::storage]
pub(super) type AccumulatedTreasuryFunds<T> = StorageValue<_, BalanceOf<T>, ValueQuery>;

#[derive(TypeInfo, Encode, Decode, PalletError, Debug, PartialEq)]
pub enum BundleError {
/// Can not find the operator for given operator id.
Expand Down
6 changes: 3 additions & 3 deletions crates/pallet-domains/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::pallet::{
NominatorCount, OperatorIdOwner, OperatorSigningKey, Operators, PendingOperatorSwitches,
PendingSlashes, PendingStakingOperationCount, Withdrawals,
};
use crate::staking_epoch::mint_funds;
use crate::staking_epoch::{mint_funds, mint_into_treasury};
use crate::{
BalanceOf, Config, DomainBlockNumberFor, Event, HoldIdentifier, NominatorId,
OperatorEpochSharePrice, Pallet, ReceiptHashFor, SlashedReason,
Expand Down Expand Up @@ -1181,7 +1181,7 @@ pub(crate) fn do_unlock_operator<T: Config>(operator_id: OperatorId) -> Result<u
.map_err(Error::BundleStorageFund)?;

// transfer any remaining amount to treasury
mint_funds::<T>(&T::TreasuryAccount::get(), total_stake)?;
mint_into_treasury::<T>(total_stake).ok_or(Error::MintBalance)?;

// remove OperatorOwner Details
OperatorIdOwner::<T>::remove(operator_id);
Expand Down Expand Up @@ -1234,7 +1234,7 @@ pub(crate) fn do_reward_operators<T: Config>(
.ok_or(Error::BalanceUnderflow)?;
}

mint_funds::<T>(&T::TreasuryAccount::get(), rewards)
mint_into_treasury::<T>(rewards).ok_or(Error::MintBalance)
})
}

Expand Down
35 changes: 29 additions & 6 deletions crates/pallet-domains/src/staking_epoch.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//! Staking epoch transition for domain
use crate::bundle_storage_fund::deposit_reserve_for_storage_fund;
use crate::pallet::{
Deposits, DomainStakingSummary, LastEpochStakingDistribution, OperatorIdOwner, Operators,
PendingOperatorSwitches, PendingSlashes, PendingStakingOperationCount, Withdrawals,
AccumulatedTreasuryFunds, Deposits, DomainStakingSummary, LastEpochStakingDistribution,
OperatorIdOwner, Operators, PendingOperatorSwitches, PendingSlashes,
PendingStakingOperationCount, Withdrawals,
};
use crate::staking::{
do_convert_previous_epoch_deposits, do_convert_previous_epoch_withdrawal, DomainEpoch,
Expand All @@ -13,8 +14,10 @@ use crate::{
OperatorEpochSharePrice, Pallet,
};
use codec::{Decode, Encode};
use frame_support::traits::fungible::{InspectHold, Mutate, MutateHold};
use frame_support::traits::tokens::{Fortitude, Precision, Restriction};
use frame_support::traits::fungible::{Inspect, InspectHold, Mutate, MutateHold};
use frame_support::traits::tokens::{
DepositConsequence, Fortitude, Precision, Provenance, Restriction,
};
use frame_support::PalletError;
use scale_info::TypeInfo;
use sp_core::Get;
Expand Down Expand Up @@ -365,6 +368,25 @@ pub(crate) fn mint_funds<T: Config>(
Ok(())
}

pub(crate) fn mint_into_treasury<T: Config>(amount: BalanceOf<T>) -> Option<()> {
let existing_funds = AccumulatedTreasuryFunds::<T>::get();
let total_funds = existing_funds.checked_add(&amount)?;
if total_funds.is_zero() {
return Some(());
}

match T::Currency::can_deposit(&T::TreasuryAccount::get(), total_funds, Provenance::Minted) {
// Deposit is possible, so we mint the funds into treasury.
DepositConsequence::Success => {
T::Currency::mint_into(&T::TreasuryAccount::get(), total_funds).ok()?;
AccumulatedTreasuryFunds::<T>::kill();
}
// Deposit cannot be done to treasury, so hold the funds until we can.
_ => AccumulatedTreasuryFunds::<T>::set(total_funds),
}
Some(())
}

pub(crate) fn do_finalize_slashed_operators<T: Config>(
domain_id: DomainId,
) -> Result<u32, TransitionError> {
Expand Down Expand Up @@ -461,7 +483,8 @@ pub(crate) fn do_finalize_slashed_operators<T: Config>(
.ok_or(TransitionError::BalanceOverflow)?
.checked_sub(&amount_to_slash_in_holding)
.ok_or(TransitionError::BalanceUnderflow)?;
mint_funds::<T>(&T::TreasuryAccount::get(), nominator_reward)?;
mint_into_treasury::<T>(nominator_reward)
.ok_or(TransitionError::MintBalance)?;

total_stake = total_stake.saturating_sub(nominator_staked_amount);

Expand Down Expand Up @@ -507,7 +530,7 @@ pub(crate) fn do_finalize_slashed_operators<T: Config>(
)?;

// mint any gains to treasury account
mint_funds::<T>(&T::TreasuryAccount::get(), total_stake)?;
mint_into_treasury::<T>(total_stake).ok_or(TransitionError::MintBalance)?;

// Transfer all the storage fund to treasury
bundle_storage_fund::transfer_all_to_treasury::<T>(operator_id)
Expand Down

0 comments on commit 5a8d0f5

Please sign in to comment.