52915 sc low yield are transferred before eligibility check potentially leading to freezing of funds
Submitted on Aug 14th 2025 at 09:13:02 UTC by @spongebob for Attackathon | Plume Network
Report ID: #52915
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcToken.sol
Impacts: Permanent freezing of funds
Description
The distributeYield and distributeYieldWithLimit functions in the ArcToken contract contain a flaw where yield tokens are transferred from the caller to the contract before checking if any token holders are eligible to receive yield.
Reference: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L408
Behavior:
When all token holders are restricted from receiving yield (resulting in
effectiveTotalSupply == 0), the functions still execute thesafeTransferFromcall but thenemit YieldDistributed(0, ...)and return without distributing any tokens.Reference: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L425-L428
The transferred yield tokens become permanently trapped in the contract since there are no sweep or recovery functions implemented.
Root cause summary:
safeTransferFromexecutes first, pulling tokens from the caller.effectiveTotalSupplyis calculated afterward by checking yield restrictions.Reference: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L417-L423
If no holders are eligible (
effectiveTotalSupply == 0), the function returns early without distribution.Reference: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L417-L423
No recovery mechanism exists to retrieve the trapped tokens.
The same pattern exists in distributeYieldWithLimit where tokens are transferred on the first batch (startIndex == 0) before eligibility checks.
Reference: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L526-L528
Impact
Yield tokens transferred to the contract cannot be recovered through any on-chain mechanism, leading to permanent loss of yield tokens when all token holders become ineligible for yield distribution.
Proof of Concept
Confirm permanent loss
Check that yield tokens are stuck in the contract balance.
Verify no sweep/recovery functions exist in the contract to retrieve the tokens.
Funds remain inaccessible to all parties, including contract administrators.
Note: The same scenario applies to distributeYieldWithLimit() when called with startIndex == 0.
References
ArcToken.sol at lines referenced above:
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L408
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L417-L423
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L425-L428
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L526-L528
Was this helpful?