52798 sc high integer division remainder loss in batched yield distribution causes permanent fund lock
Submitted on Aug 13th 2025 at 09:17:55 UTC by @ZeroExRes for Attackathon | Plume Network
Report ID: #52798
Report Type: Smart Contract
Report severity: High
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcToken.sol
Impacts: Permanent freezing of funds
Description
Brief/Intro
The distributeYieldWithLimit() function contains a flaw where integer division remainders from each batch are permanently lost and locked in the contract, while the regular distributeYield() function correctly handles these remainders. This creates an accumulating fund loss mechanism that can result in significant monetary losses over time, with no recovery method available.
Vulnerability Details
The issue stems from different remainder handling between two yield distribution functions:
distributeYield() (Works Correctly):
// Processes all holders except last
for (uint256 i = 0; i < lastProcessedIndex; i++) {
uint256 share = (amount * holderBalance) / effectiveTotalSupply;
// ... distribute share
distributedSum += share;
}
// CRITICAL: Last holder gets ALL remainder
uint256 lastShare = amount - distributedSum; // ← Captures remainder
yToken.safeTransfer(lastHolder, lastShare);distributeYieldWithLimit() (Loses Remainder):
Impact Details
Each batched distribution loses integer division remainders from every user calculation, with no recovery mechanism available. Even though there is no significant loss for a particular user, these per-user remainders accumulate into non-trivial amounts with each distribution, creating systematic fund loss that compounds over the contract's operational lifetime.
Permanent freezing of funds: the remainders accumulated per batch are not returned to recipients nor tracked for later distribution, so funds become permanently locked in the contract balance.
Proof of Concept
Add to ArcToken.t.sol:
References
Mentioned above
If you want, I can:
Suggest concrete fixes (e.g., accumulate distributed sum per batch and forward remainder to a designated recipient or track leftover for later distribution), or
Produce a small patch diff for ArcToken.sol implementing correct remainder handling in distributeYieldWithLimit().
Was this helpful?