For the complete documentation index, see llms.txt. This page is also available as Markdown.

53072 sc high ceil vs floor rounding mismatch causes systematic underpayment and unclaimed yield leakage

Submitted on Aug 14th 2025 at 18:52:35 UTC by @r1ver for Attackathon | Plume Network

  • Report ID: #53072

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts: Theft of unclaimed yield

Description

Brief / Intro

In plume/src/lib/PlumeRewardLogic.sol, per-user commission uses ceiling division while validator commission accrues with floor division, so user deductions can exceed validator accrual; the excess isn’t credited to anyone, causing systematic underpayment and unclaimed-yield leakage.

Vulnerability Details

In plume/src/lib/PlumeRewardLogic.sol, updateRewardPerTokenForValidator calculates validator commission accrual using floor division:

PlumeRewardLogic.sol (validator floor example)
// Use regular division (floor) for validator's accrued commission
uint256 commissionDeltaForValidator = (
    grossRewardForValidatorThisSegment * commissionRateForSegment
) / PlumeStakingStorage.REWARD_PRECISION;

But per-user commission deduction in _calculateRewardsCore uses ceiling division:

Because Solidity lacks decimals and any non-integer division rounds, applying ceil per user per time-segment makes the sum of user-side commissions often exceed the validator’s floor-accrued commission. The difference is neither credited to validators nor returned to users, creating unclaimed-yield leakage and systematic underpayment that grows with more users, more segments, and more rate changes.

Impact Details

Users are systematically underpaid because per-user ceil commission can exceed validator floor-accrued commission, and the excess is not credited to anyone, causing accumulating unclaimed-yield leakage and breaking the accounting invariant (user_net + validator_commission < gross), which undermines auditability.

Proof of Concept

A test demonstrating the mismatch:

Run it with: forge test RoundingMismatchPOC -vvv

References

  • https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/lib/PlumeRewardLogic.sol#L184-L187

  • https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/src/lib/PlumeRewardLogic.sol#L346-L355

Notes / Remediation Suggestions (observational)

  • Ensure the same rounding convention is used for both the per-user deduction and the validator accrual (preferably use floor consistently or accumulate the rounding remainders and attribute them deterministically).

  • Alternatively, compute commission at the validator-level from the summed gross amounts before applying rounding, or aggregate per-segment remainder adjustments into a dedicated accounting bucket that is credited to validators or distributed back to users to preserve the invariant.

Was this helpful?