52041 sc low in arctoken attacker can reposition to last holder and capture entire yield remainder

Submitted on Aug 7th 2025 at 14:00:24 UTC by @Paludo0x for Attackathon | Plume Network

  • Report ID: #52041

  • Report Type: Smart Contract

  • Report severity: Low

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

  • Impacts:

    • Theft of unclaimed yield

Description

Vulnerability Details

In ArcToken::distributeYield(), any rounding remainder is awarded to the last address in the on-chain holders set.

A malicious holder can deliberately transfer their entire balance to an unused wallet causing their old address to be removed and the new one appended last. By front-running a yield distribution, the attacker would sweep the full dust amount.

Impact Details

Although the amount that an attacker would gain could be low (it depends on yield token real value and decimals), the attack can be done easily by anyone who can transfer ArcTokens without restriction, and can be repeated.

Therefore the reporter defined the vulnerability as high.

1

Redirect remainder to neutral address

Redirect the rounding remainder to a neutral address (e.g., treasury or burn pool) instead of giving it to the last holder.

2

Use higher-precision arithmetic

Use higher-precision arithmetic to minimize dust and eliminate the need for remainder handling.

Proof of Concept

This is the relevant snippet of distributeYield(), where distribution to last holder is performed:

This is the overridden implementation in ArcToken of the internal function _update() which is called during common ERC20 transfers. It's clear that if ArcTokens funds are moved to a new address, this one is inserted in the holders array as the last element:

This is the implementation of EnumerableSet::add():

Was this helpful?