58607 sc low incorrect access control in admin ownership transfer allows only current admin to accept ownership instead of pending admin
Submitted on Nov 3rd 2025 at 14:48:38 UTC by @dobrevaleri for Audit Comp | Alchemix V3
Report ID: #58607
Report Type: Smart Contract
Report severity: Low
Target: https://github.com/alchemix-finance/v3-poc/blob/immunefi_audit/src/AlchemistCurator.sol
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
The AlchemistCurator::acceptAdminOwnership() function uses the onlyAdmin modifier, which restricts access to the current admin instead of the pending admin. This breaks the two-step admin transfer pattern and makes it impossible for a pending admin to accept ownership.
Vulnerability Details
The AlchemistCurator contract implements a two-step admin ownership transfer mechanism where:
The current admin calls
transferAdminOwnerShip()to set a pending adminThe pending admin should call
acceptAdminOwnership()to finalize the transfer
However, the implementation is flawed:
The acceptAdminOwnership() function uses the onlyAdmin modifier, which requires msg.sender == admin (from PermissionedProxy). This means only the current admin can call this function, not the pending admin.
The correct implementation can be seen in other contracts like Transmuter and AlchemistV3:
This vulnerability breaks the guarantee of two-step admin transfers, which is designed to prevent accidental admin changes by requiring explicit acceptance from the new admin.
Impact Details
No pending admin can ever accept ownership since they lack the current admin privileges required by the onlyAdmin modifier.
References
https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/AlchemistCurator.sol#L31-L35
https://github.com/alchemix-finance/v3-poc/blob/a192ab313c81ba3ab621d9ca1ee000110fbdd1e9/src/Transmuter.sol#L94-L106
Proof of Concept
Proof of Concept
Was this helpful?