49616 sc high user can steal rewards

Submitted on Jul 17th 2025 at 18:55:47 UTC by @shadowHunter for Attackathon | Plume Network

  • Report ID: #49616

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/facets/StakingFacet.sol

  • Impacts:

    • Theft of unclaimed yield

Description

Brief / Intro

It appears that on a fresh stake, $.userValidatorRewardPerTokenPaidTimestamp is only updated for active reward tokens and not for historical (previously removed) reward tokens. This creates a window where a user can receive unauthorized rewards.

Vulnerability Details

1

Scenario step

Reward token PUSD existed and is removed at timestamp X.

2

Scenario step

Post removal, User A stakes 10e18 tokens.

3

Scenario step

User A immediately unstakes 10e18 tokens. User A has 0 staked tokens.

4

Scenario step

Later, PUSD is added again at timestamp X+1.

5

Scenario step

User B stakes while PUSD is active.

6

Scenario step

At X+500 seconds User B stakes again and PUSD is removed.

7

Scenario step

User A stakes a very large amount at X+500 seconds. Since PUSD is not an active token, its userValidatorRewardPerTokenPaidTimestamp remains X (the old timestamp).

8

Scenario step

User A immediately claims and receives rewards for the full 500 seconds (from X to X+500) even though they shouldn't be entitled to them.

Impact Details

User can steal rewards.

Recommendation

Update _initializeRewardStateForNewStake to iterate all historical reward tokens instead of just $.rewardTokens to ensure state is updated properly for all reward tokens (including ones that were previously removed).

Proof of Concept

PoC test (forge) and failing assertion

Command used:

Test code:

Test output (failing assertion):

Was this helpful?