Skip to content

Commit 0b0d082

Browse files
authored
Pallet inflation safety additions (#1146)
* Safe division * Sanity checks
1 parent 56ebeef commit 0b0d082

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

pallets/inflation/src/lib.rs

+44-10
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,10 @@ use frame_support::{
109109
traits::{Currency, GetStorageVersion, OnRuntimeUpgrade},
110110
};
111111
use frame_system::{ensure_root, pallet_prelude::*};
112-
use sp_runtime::{traits::CheckedAdd, Perquintill};
112+
use sp_runtime::{
113+
traits::{CheckedAdd, Zero},
114+
Perquintill,
115+
};
113116
use sp_std::marker::PhantomData;
114117

115118
pub mod weights;
@@ -315,6 +318,7 @@ pub mod pallet {
315318
) -> DispatchResult {
316319
ensure_root(origin)?;
317320

321+
config.sanity_check();
318322
ActiveInflationConfig::<T>::put(config.clone());
319323

320324
Self::deposit_event(Event::<T>::InflationConfigurationForceChanged { config });
@@ -370,27 +374,28 @@ pub mod pallet {
370374
Balance::from(T::CycleConfiguration::periods_per_cycle().max(1));
371375

372376
// 3.1. Collator & Treasury rewards per block
373-
let collator_reward_per_block = collators_emission / blocks_per_cycle;
374-
let treasury_reward_per_block = treasury_emission / blocks_per_cycle;
377+
let collator_reward_per_block = collators_emission.saturating_div(blocks_per_cycle);
378+
let treasury_reward_per_block = treasury_emission.saturating_div(blocks_per_cycle);
375379

376380
// 3.2. dApp reward pool per era
377-
let dapp_reward_pool_per_era = dapps_emission / build_and_earn_eras_per_cycle;
381+
let dapp_reward_pool_per_era =
382+
dapps_emission.saturating_div(build_and_earn_eras_per_cycle);
378383

379384
// 3.3. Staking reward pools per era
380385
let base_staker_reward_pool_per_era =
381-
base_stakers_emission / build_and_earn_eras_per_cycle;
386+
base_stakers_emission.saturating_div(build_and_earn_eras_per_cycle);
382387
let adjustable_staker_reward_pool_per_era =
383-
adjustable_stakers_emission / build_and_earn_eras_per_cycle;
388+
adjustable_stakers_emission.saturating_div(build_and_earn_eras_per_cycle);
384389

385390
// 3.4. Bonus reward pool per period
386-
let bonus_reward_pool_per_period = bonus_emission / periods_per_cycle;
391+
let bonus_reward_pool_per_period = bonus_emission.saturating_div(periods_per_cycle);
387392

388393
// 4. Block at which the inflation must be recalculated.
389394
let recalculation_era =
390395
next_era.saturating_add(T::CycleConfiguration::eras_per_cycle());
391396

392-
// 5. Return calculated values
393-
InflationConfiguration {
397+
// 5. Prepare config & do sanity check of its values.
398+
let new_inflation_config = InflationConfiguration {
394399
recalculation_era,
395400
issuance_safety_cap,
396401
collator_reward_per_block,
@@ -400,7 +405,10 @@ pub mod pallet {
400405
adjustable_staker_reward_pool_per_era,
401406
bonus_reward_pool_per_period,
402407
ideal_staking_rate: params.ideal_staking_rate,
403-
}
408+
};
409+
new_inflation_config.sanity_check();
410+
411+
new_inflation_config
404412
}
405413

406414
/// Check if payout cap limit would be reached after payout.
@@ -514,6 +522,32 @@ pub struct InflationConfiguration {
514522
pub ideal_staking_rate: Perquintill,
515523
}
516524

525+
impl InflationConfiguration {
526+
/// Sanity check that does rudimentary checks on the configuration and prints warnings if something is unexpected.
527+
///
528+
/// There are no strict checks, since the configuration values aren't strictly bounded like those of the parameters.
529+
pub fn sanity_check(&self) {
530+
if self.collator_reward_per_block.is_zero() {
531+
log::warn!("Collator reward per block is zero. If this is not expected, please report this to Astar team.");
532+
}
533+
if self.treasury_reward_per_block.is_zero() {
534+
log::warn!("Treasury reward per block is zero. If this is not expected, please report this to Astar team.");
535+
}
536+
if self.dapp_reward_pool_per_era.is_zero() {
537+
log::warn!("dApp reward pool per era is zero. If this is not expected, please report this to Astar team.");
538+
}
539+
if self.base_staker_reward_pool_per_era.is_zero() {
540+
log::warn!("Base staker reward pool per era is zero. If this is not expected, please report this to Astar team.");
541+
}
542+
if self.adjustable_staker_reward_pool_per_era.is_zero() {
543+
log::warn!("Adjustable staker reward pool per era is zero. If this is not expected, please report this to Astar team.");
544+
}
545+
if self.bonus_reward_pool_per_period.is_zero() {
546+
log::warn!("Bonus reward pool per period is zero. If this is not expected, please report this to Astar team.");
547+
}
548+
}
549+
}
550+
517551
/// Inflation parameters.
518552
///
519553
/// The parts of the inflation that go towards different purposes must add up to exactly 100%.

0 commit comments

Comments
 (0)