50477 sc high validator loses all accrued commission when reward token is removed
Submitted on Jul 25th 2025 at 08:19:56 UTC by @holydevoti0n for Attackathon | Plume Network
Report ID: #50477
Report Type: Smart Contract
Report severity: High
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/ValidatorFacet.sol
Impacts:
Permanent freezing of funds
Description
Brief/Intro
Incorrect logic causes a validator to lose all accrued commission when a reward token is removed.
Vulnerability Details
When requesting commission, the modifier _validateIsToken prevents the validator from claiming his commission for a reward token that was removed.
Relevant code:
modifier _validateIsToken(
address token
) {
@> if (!PlumeStakingStorage.layout().isRewardToken[token]) {
revert TokenDoesNotExist(token);
}
_;
}
function requestCommissionClaim(
uint16 validatorId,
address token
)
external
onlyValidatorAdmin(validatorId)
nonReentrant
_validateValidatorExists(validatorId)
@> _validateIsToken(token)
{
...
}The root cause is that the modifier should check if the token is a historical token (i.e., claimable even after removal), not whether it is currently an active reward token.
Impact
The validator loses all accrued commission for the reward token that was removed, causing permanent freezing of those funds.
Recommendation
Change the modifier to check if the token is a historical token, not the reward token.
Suggested patch:
modifier _validateIsToken(
address token
) {
- if (!PlumeStakingStorage.layout().isRewardToken[token]) {
- revert TokenDoesNotExist(token);
- }
+ if (!PlumeStakingStorage.layout().isHistoricalRewardToken[token]) {
+ revert TokenDoesNotExist(token);
+ }
_;
}Ensure that tokens removed from active rewards but for which users/validators have accrued balances remain claimable by checking a historical/legacy registry rather than the current active reward list.
Proof of Concept
Was this helpful?