51519 sc low unstake does not validate users remaing stake
Submitted on Aug 3rd 2025 at 16:53:12 UTC by @funkornaut for Attackathon | Plume Network
Report ID: #51519
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/StakingFacet.sol
Description
Brief / Intro
Stakers can end up with a staked balance that is less than minStakeAmount after calling unstake.
Vulnerability Details
Staking requires users to stake at least a minStakeAmount. Users can unstake a specific amount via:
function unstake(uint16 validatorId, uint256 amount)Within the internal _unstake(uint16 validatorId, uint256 amount) implementation there is no validation ensuring the staker's remaining stake is at least minStakeAmount. As a result, a user who originally met the minimum can partially unstake and remain with a balance below the minimum.
Impact Details
Possible reward calculation truncation: The reward computation multiplies the (now tiny) user stake with a per-token reward delta and divides by a precision constant:
uint256 grossRewardForSegment = (userStakedAmount * rewardPerTokenDeltaForUserInSegment) / PlumeStakingStorage.REWARD_PRECISION;For extremely small userStakedAmount values, the multiplication may be smaller than REWARD_PRECISION, causing truncation to 0 and permanent loss of accumulated rewards.
State inconsistency and future protocol risks:
Validator relationship tracking: Users with tiny stakes remain in validator staker lists indefinitely.
Economic model violation:
minStakeAmountexists to ensure meaningful participation; leaving sub-minimum stakes undermines intended reward behavior.Potential DoS vector: Attackers could create many tiny stakes across validators. While current code may not iterate these arrays in harmful ways, future changes that iterate them could be vulnerable to gas-limit attacks.
References
https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/StakingFacet.sol?utm_source=immunefi#L366-L390
https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/lib/PlumeRewardLogic.sol#L339-#L341
Proof of Concept
Was this helpful?