52833 sc high bypass the fix of immunefi audit imm crit 01 token creator can upgrade arctoken implementation

Submitted on Aug 13th 2025 at 14:03:53 UTC by @r1ver for Attackathon | Plume Network

  • Report ID: #52833

  • Report Type: Smart Contract

  • Report severity: High

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

  • Impacts:

    • Direct theft of any user funds, whether at-rest or in-motion, other than unclaimed yield

    • Permanent freezing of funds

    • Theft of unclaimed yield

Description

Brief/Intro

Before this Attackathon, the project had already undergone multiple audits. You can view Immunefi’s audit report at https://github.com/immunefi-team/attackathon-plume-network/blob/main/plume/audit/immunefi.pdf. In that report, the CRITICAL issue IMM-CRIT-01: “Token Creator Can Upgrade ArcToken Implementation” remains present and exploitable even after the fix.

Vulnerability Details

Based on the previous audit report, we can locate the vulnerability in arc/src/ArcTokenFactory.sol. In the createToken function, UPGRADER_ROLE is incorrectly assigned to msg.sender, i.e., the token creator. This means anyone can create their own token, and because the token creator is granted UPGRADER_ROLE, “I’m quoting from Immunefi’s audit report. the creator can upgrade the ArcToken contract at any time, bypassing the intended control of the ArcTokenFactory and potentially introduce malicious logic or vulnerabilities.” The proposed fix is to set UPGRADER_ROLE to address(this).

Example of proposed role grants (from the prior report):

However, DEFAULT_ADMIN_ROLE still belongs to msg.sender, and DEFAULT_ADMIN_ROLE is the highest-privilege role—it can configure any other role, including itself:

  • https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/access/AccessControlUpgradeable.sol#L37-#L50

  • https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/access/AccessControlUpgradeable.sol#L146-L176

The code above shows that DEFAULT_ADMIN_ROLE can arbitrarily change the UPGRADER_ROLE. Since msg.sender still holds DEFAULT_ADMIN_ROLE, they can reassign UPGRADER_ROLE to themselves.

Impact Details (quote from previous audit report)

This allows the token creator to call upgradeToAndCall on the ArcToken contract, giving them full control over the token's implementation. As a result, the creator can upgrade the ArcToken contract at any time, bypassing the intended control of the ArcTokenFactory and potentially introducing malicious logic or vulnerabilities. This undermines the security and trust assumptions of the ArcTokenFactory, as upgrades can occur without factory or governance oversight.

References

  • https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcTokenFactory.sol#L193-L200

  • https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/access/AccessControlUpgradeable.sol#L37-#L50

  • https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/master/contracts/access/AccessControlUpgradeable.sol#L146-L176

Proof of Concept

I wrote a test file in arc/test/ArcTokenFactoryUpgradeVulnerability.t.sol. You can run this test with:

Test source:

Notes in test comments:

  • The test demonstrates that although UPGRADER_ROLE may be assigned to the factory, the token creator retains DEFAULT_ADMIN_ROLE and can reassign UPGRADER_ROLE to themselves, enabling upgrades and full control.

Was this helpful?