50425 sc high active non slashed validators cannot claim rewards when a reward token is disabled
Submitted on Jul 24th 2025 at 13:30:05 UTC by @oxrex for Attackathon | Plume Network
Report ID: #50425
Report Type: Smart Contract
Report severity: High
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/ValidatorFacet.sol
Impacts:
Temporary freezing of funds for at least 24 hours
Description
Brief/Intro
When a reward token is disabled, the intent is to allow validators as well as users to claim the accrued rewards up until the timestamp the disabled token became disabled. However, for validators there exists an edge case that is not handled correctly.
Vulnerability Details
When a reward token is disabled, no further requestCommissionClaim() function call will be possible for all validators because the function uses the modifier _validateIsToken which ensures the isRewardToken[token] bool for the reward token in question must be true, otherwise it reverts. Since, during deactivation of a reward token, the contract:
It will now not be possible for validators to request commission claim for the accrued commissions because requestCommissionClaim will revert with the message: TokenDoesNotExist.
Relevant snippet from ValidatorFacet.sol:
Relevant snippet from RewardsFacet.sol showing token removal flow:
Impact Details
When the reward token is deactivated, accrued rewards that were calculated and updated for each of the validators cannot be requested, and calling forceSettleValidatorCommission() does not fix it because that function only accrues rewards for the validators without actually sending out the rewards.
Users are able to claim accrued rewards for the tokens, but validators cannot — even though they are still active / not slashed and should be able to claim the accrued commission for the period up to deactivation.
Suggested fix (described by reporter): allow validators to request claim for accrued rewards up to the timestamp the token was deactivated. Concretely, modify the request logic to allow requests when the validator is active, not slashed, the reward token is deactivated, and validatorAccruedCommission[validatorId][token] != 0.
References
https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/ValidatorFacet.sol?utm_source=immunefi#L126-L133
https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/ValidatorFacet.sol?utm_source=immunefi#L508
Proof of Concept
Add the PoC test below in the PlumeStakingDiamondTest test file and run the test with verbosity of 3 (-vvv). You can comment in the vm.expectRevert(); to actually see the test failing in the console if desired.
Was this helpful?