In the distributeYield function the contract first transfers the tokens into the ArcToken contract and only afterwards checks if there are any legitimate (unrestricted) users. If none exist, the function returns after the transfer and the funds remain stuck in the contract.
Vulnerability Details
distributeYield performs the incoming token transfer first (via safeTransferFrom) and then checks whether there are any holders eligible to receive yield. If there are no eligible holders (effective supply is zero), the function emits YieldDistributed(0, yieldTokenAddr) and returns, leaving the transferred tokens held by the contract with no mechanism to extract them.
Impact Details
Yield tokens can become permanently or temporarily stuck in the contract, effectively lost to users.
Proof of Concept
distributeYield function (excerpt)
As shown above, the transfer into the contract happens before checking effectiveTotalSupply. If effectiveTotalSupply == 0 the function returns and the tokens remain in the contract.
The related function distributionYieldWithLimit applies the effective supply check before transferring tokens (i.e., it avoids this issue):
Vulnerable function location: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L408
Related correct implementation: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L518