52500 sc high missing commission checkpoint initialization leads to retroactive commission theft of user rewards

Submitted on Aug 11th 2025 at 09:25:12 UTC by @ZeroExRes for Attackathon | Plume Network

  • Report ID: #52500

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts: Theft of unclaimed yield

Description

Brief / Intro

Validators can retroactively apply higher commission rates to historical rewards due to a missing initial commission checkpoint in addValidator(). When users claim rewards that accrued during periods with lower commission rates, the system incorrectly applies the current commission rate to the entire historical period, resulting in permanent theft of user funds.

Vulnerability Details

addValidator() in ValidatorFacet.sol creates initial reward rate checkpoints but fails to create an initial commission checkpoint:

function addValidator(...) {
    validator.commission = commission;
    
    // Creates reward checkpoints but NOT commission checkpoint
    for (uint256 i = 0; i < rewardTokens.length; i++) {
        PlumeRewardLogic.createRewardRateCheckpoint($, token, validatorId, currentGlobalRate);
    }
    // MISSING: PlumeRewardLogic.createCommissionRateCheckpoint($, validatorId, commission);
}

The function that queries historical commission rates, when it finds no commission checkpoints, falls back to the validator's current commission value:

This allows a validator to set an initial commission (or default) and later increase the commission; because no initial checkpoint exists, all historical reward calculations that probe past timestamps will see the new (higher) commission and apply it retroactively.

Illustrative exploitation scenario

1

Validator created with 0% commission

A validator is added with commission set to 0% but no commission checkpoint is recorded.

2

Users stake and rewards accumulate

Users stake with this validator and rewards accrue over time (under the expectation of 0% commission).

3

Validator increases commission

The validator increases commission to, e.g., 50% — this action creates the first commission checkpoint.

4

Users claim historical rewards but lose funds

When users later claim rewards that accrued during the earlier period, the contract queries historical commission rates but finds no checkpoint for that earlier period and falls back to the current commission (50%). The claim incorrectly takes 50% of past rewards.

Impact Details

Direct loss of user reward funds. Affects all users who staked with validators before their first commission change. The longer the delay between validator creation and the first commission change, the greater the potential theft.

Proof of Concept

Add the following test to PlumeStakingDiamond.t.sol to reproduce:

References

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


If you want, I can propose a minimal patch (code snippet) to ensure an initial commission checkpoint is created in addValidator() and adjust getEffectiveCommissionRateAt() fallback behavior to avoid using the current commission for past timestamps.

Was this helpful?