50284 sc insight incorrect erc7201 storage implementation in core factory contracts

Submitted on Jul 23rd 2025 at 12:17:16 UTC by @AasifUsmani for Attackathon | Plume Network

  • Report ID: #50284

  • Report Type: Smart Contract

  • Report severity: Insight

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

  • Impacts:

    • Protocol insolvency

    • Temporary freezing of funds for at least 1 hour

Description

Brief/Intro

The ArcTokenFactory and RestrictionsFactory contracts claim to implement ERC7201 namespaced storage via @custom:storage-location erc7201: annotations but use incorrect storage slot calculations that violate the ERC7201 specification. This creates potential storage collision risks and is a standards compliance issue in core Plume Chain infrastructure contracts.

Vulnerability Details

Root Cause Analysis

Both factory contracts contain identical violations of the ERC7201 standard.

  1. ArcTokenFactory.sol (simplified excerpt):

  1. RestrictionsFactory.sol (simplified excerpt):

ERC7201 Standard Requirements

According to EIP-7201, the correct storage slot calculation must be:

The ERC7201 formula ensures collision resistance through:

  • Double hashing: keccak256(abi.encode(uint256(keccak256(namespace)) - 1))

  • Byte masking: & ~bytes32(uint256(0xff)) ensures the last byte is 0x00

  • Offset subtraction: -1 prevents direct collision with the inner hash

Impact Details

Storage Collision Risks

Because the contracts use a plain keccak256(namespace) as the storage slot:

  • It can collide with storage slots used by common libraries (e.g., OpenZeppelin AccessControlUpgradeable, UUPSUpgradeable, Initializable).

  • During upgrades, overlapping slots could corrupt state leading to broken behavior or loss of funds.

System-Level Impact

These are core infrastructure contracts:

  • ArcTokenFactory manages creation and upgrades of ARC tokens.

  • RestrictionsFactory manages restriction module deployments.

Storage corruption in either can:

  • Break token creation/upgrades

  • Corrupt restriction module mappings

  • Cause system-wide degradation and require emergency migrations

Standards Compliance Issue

Contracts claim ERC7201 compliance via annotations but do not implement its slot calculation correctly. This misleads developers/auditors and breaks tooling that expects ERC7201 namespaces.

Required Actions

1

Correct storage slot calculation

Immediately correct the storage slot calculations to follow the ERC-7201 formula (double-hash + offset + byte mask) for each @custom:storage-location erc7201: namespace.

2

Align annotations with actual implementation

If ERC7201 is not being implemented, remove or correct the @custom:storage-location erc7201: annotations so documentation and code are consistent.

References

  1. ArcTokenFactory: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcTokenFactory.sol#L62

  2. RestrictionsFactory: https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/restrictions/RestrictionsFactory.sol#L43

  3. EIP - 7201 documentation and mandates: https://eips.ethereum.org/EIPS/eip-7201

Proof of Concept

PoC solidity test demonstrating slot differences (click to expand)

To run the PoC, create a new file in arc/tests/EIPTests.t.sol and copy/paste the following. Run: forge test --mt test_StorageSlotCalculationComparison -vvvv --via-ir

Was this helpful?