51456 sc high token creator can revoke the upgrader role from the factory in order to avoid upgrades
Report ID: #51456
Report Type: Smart Contract
Report severity: High
Target: https://github.com/immunefi-team/attackathon-plume-network/blob/main/arc/src/ArcTokenFactory.sol
Impacts: Contract fails to deliver promised returns, but doesn't lose value
Brief / Intro
Vulnerability Details
When a token is created, the factory assigns multiple roles to the token creator and assigns the UPGRADER_ROLE to the factory (address(this)):
token.grantRole(token.DEFAULT_ADMIN_ROLE(), msg.sender);
token.grantRole(token.ADMIN_ROLE(), msg.sender);
token.grantRole(token.MANAGER_ROLE(), msg.sender);
token.grantRole(token.YIELD_MANAGER_ROLE(), msg.sender);
token.grantRole(token.YIELD_DISTRIBUTOR_ROLE(), msg.sender);
token.grantRole(token.MINTER_ROLE(), msg.sender);
token.grantRole(token.BURNER_ROLE(), msg.sender);
token.grantRole(token.UPGRADER_ROLE(), address(this));Because the token creator is granted DEFAULT_ADMIN_ROLE, they can revoke or grant any role, including revoking the UPGRADER_ROLE from the factory. The token enforces upgrades via UUPS and requires UPGRADER_ROLE:
The factory exposes an admin-only upgrade function that expects to be able to upgrade tokens it created:
If the token creator revokes UPGRADER_ROLE from the factory, the factory's call to UUPSUpgradeable(token).upgradeToAndCall will revert because _authorizeUpgrade will fail the onlyRole(UPGRADER_ROLE) check. Conversely, the token owner (having DEFAULT_ADMIN_ROLE) can grant themself UPGRADER_ROLE and upgrade the token implementation arbitrarily.
Impact Details
The ArcTokenFactory will be unable to upgrade tokens it created if the token creator revokes the UPGRADER_ROLE from the factory.
Token creators could upgrade their token to an arbitrary implementation by granting themselves UPGRADER_ROLE, which may break intended guarantees or introduce malicious logic.
Overall: intended upgradeability and central admin control can be lost or subverted by token creators who hold DEFAULT_ADMIN_ROLE.
Proof of Concept
User creates a token by calling createToken on ArcTokenFactory.
The factory grants the user roles including DEFAULT_ADMIN_ROLE.
The factory also grants itself the UPGRADER_ROLE to allow upgrades.
The token creator revokes every role that was granted to the ArcTokenFactory (including UPGRADER_ROLE).
The factory (admin) can no longer upgrade the token using upgradeToken because _authorizeUpgrade requires UPGRADER_ROLE.
The token creator can grant themself UPGRADER_ROLE and upgrade the token implementation to any address.
References
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcTokenFactory.sol#L144
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcTokenFactory.sol#L261
https://github.com/immunefi-team/attackathon-plume-network/blob/580cc6d61b08a728bd98f11b9a2140b84f41c802/arc/src/ArcToken.sol#L648
Was this helpful?