The MultiSigTimelock contract inherits OpenZeppelin's AccessControl but does not override the renounceRole function. Any account holding the SIGNING_ROLE can call renounceRole on its own to abandon the signer identity, which causes an inconsistency between the contract's internal signer array and the AccessControl role system state. The contract's custom grantSigningRole function checks the s_isSigner mapping, preventing the administrator from re-granting permissions to accounts that have renounced their roles.
Likelihood:
Signers accidentally or maliciously call renounceRole(SIGNING_ROLE, self)
Automated scripts incorrectly invoke the role renunciation function
Attackers proactively renounce the role after compromising a signer's account
Impact:
The signer is removed from the AccessControl system, but the contract's internal s_isSigner mapping remains true
Administrators cannot re-grant permissions because grantSigningRole will revert due to s_isSigner[_account] == true
The contract enters an inconsistent state: the signer exists in the array but has no actual signing permissions
May cause miscalculations of the required number of signatures, rendering the multi-signature wallet inoperable
Add the test_revokeSigningRole_ByAccessControl function to test/unit/MultiSigTimelockTest.t.sol as follows:
Run in the console: forge test --mt test_revokeSigningRole_ByAccessControl -vv
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.
The contest is complete and the rewards are being distributed.