52424 sc high there is a retroactive commission miscalculation in plumerewardlogic

Submitted on Aug 10th 2025 at 14:57:27 UTC by @XDZIBECX for Attackathon | Plume Network

  • Report ID: #52424

  • Report Type: Smart Contract

  • Report severity: High

  • Target: attackathon-plume-network/plume/src/lib /PlumeRewardLogic.sol

  • Impacts:

    • Contract fails to deliver promised returns, but doesn't lose value

Description

Brief / Intro

In the library, if a validator commission is updated at time T without any earlier commission checkpoint, the historical reward calculation can apply the new commission to the past time. This happens because the commission lookup falls back to the validator’s current commission when no prior checkpoint exists. As a result, historical segments can be charged the new commission retroactively, causing mispayments: users receive incorrect net rewards and validators accrue incorrect commission amounts. No function is immediately at risk of being reentrancy-exploited; the issue is incorrect accounting.

Vulnerability Details

Relevant code that demonstrates the problematic fallback:

PlumeRewardLogic.sol — getEffectiveCommissionRateAt

```solidity function getEffectiveCommissionRateAt( PlumeStakingStorage.Layout storage $, uint16 validatorId, uint256 timestamp ) internal view returns (uint256) { PlumeStakingStorage.RateCheckpoint[] storage checkpoints = $.validatorCommissionCheckpoints[validatorId]; uint256 chkCount = checkpoints.length;

}

The update path sets the new commission first and then creates a checkpoint at the same timestamp:

Because the validator’s commission field is updated before creating the checkpoint, any historical lookup that finds no earlier checkpoint will fall back to the updated validator.commission and apply the new rate to prior segments.

Impact Details

  • Contract fails to deliver promised returns.

  • Consequences:

    • Users can be overcharged (receive less net reward) if a commission increase applies retroactively, or undercharged if commission decreased.

    • Validators’ accrued commission can diverge from intended amounts, causing accounting mismatches between what users were charged and validator accruals.

References

  • https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/plume/src/lib/PlumeRewardLogic.sol#L608C1-L625C1

  • https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/plume/src/lib/PlumeRewardLogic.sol#L339C4-L350C18

  • https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/plume/src/facets/ValidatorFacet.sol#L317C1-L353C1

Proof of Concept

Solidity test cases demonstrating the miscalculation (expand to view)

Notes for Remediation (non-exhaustive / hints)

  • Ensure that historical lookups never fall back to the current validator.commission for timestamps earlier than the time that current value became effective.

  • Possible fixes:

    • When creating a new commission checkpoint, create it before updating validator.commission, or

    • Modify getEffectiveCommissionRateAt to treat the absence of an earlier checkpoint as "no commission available" (e.g., revert or use an explicit genesis/default checkpoint), or

    • During commission updates, ensure the chronological ordering of state changes and checkpoint writes guarantees that historical lookups for earlier timestamps will not observe the updated commission.

  • Tests should cover same-timestamp changes (both orders) and verify accruals match expected segment-by-segment accounting.

Was this helpful?