The executeEmergency() is only callable by the EMERGENCY_ROLE role. However if at constract construction, emergency address was is zero, then EMERGENCY_ROLE role would be enabled for everyone leading to anyone executing a transaction without scheduling
Proof of Concept
Assume the contract owner deployed the contract with the inputing emergency argument in TimelockControllerEmergency.constructor() as address(0) hoping to change it anytime.
With the logic of @openzeppelin/contracts/access/AccessControl.sol , this would enable the EMERGENCY_ROLE role open to everyone.
Bob who has no assigned role, calls executeEmergency() without restriction and can execute a transaction without any delay.
Tools Used
Manual review
Recommended Mitigation Steps
Add a require check for zero address in the constructor function.
Lines of code
https://github.com/code-423n4/2022-06-nested/blob/main/contracts/governance/TimelockControllerEmergency.sol#L295
Vulnerability details
Impact
The
executeEmergency()
is only callable by theEMERGENCY_ROLE
role. However if at constract construction,emergency
address was is zero, thenEMERGENCY_ROLE
role would be enabled for everyone leading to anyone executing a transaction without schedulingProof of Concept
emergency
argument in TimelockControllerEmergency.constructor() as address(0) hoping to change it anytime.@openzeppelin/contracts/access/AccessControl.sol
, this would enable theEMERGENCY_ROLE
role open to everyone.executeEmergency()
without restriction and can execute a transaction without any delay.Tools Used
Manual review
Recommended Mitigation Steps
Add a require check for zero address in the constructor function.