frequency
frequency copied to clipboard
[Capacity] `MinimumStakingAmount` is not enforced if a stake already exists for a different provider
Summary
A user can stake to multiple providers, but the minimum staking amount is enforced only for the first staking action that the user submits.
Issue details
During the staking process, both for the stake
and provider_boost
extrinsics, a minimum staking amount should be enforced by the Runtime::MinimumStakingAmount
parameter.
The current implementation of ensure_can_stake verifies if the amount that the account is staking in total (the current active staking and the new staking amount) is greater than the MinimumStakingAmount
:
let new_active_staking_amount = staking_details
.active
.checked_add(&stakable_amount)
.ok_or(ArithmeticError::Overflow)?;
ensure!(
new_active_staking_amount >= T::MinimumStakingAmount::get(),
Error::<T>::StakingAmountBelowMinimum
);
This implies that the user has to stake the MinimumStakingAmount
only when they first submit a stake for a provider, all the subsequent staking requests being accepted even with the amount of 1.
Risk
The current implementation does not follow the intended use-case, as described in the design documentation.
An attacker could stake the minimum required amount to a provider, and then stake 1 token to each of the other available providers, underpaying for the storage that they use. This can cause a storage bloating, slowing down the network in the long run.
Mitigation
The ensure_can_stake
function should verify that the stakable_amount
is greater than MinimumStakingAmount
, instead of verifying the new_active_staking_amount
.