function revokeSigningRole(address _account) external nonReentrant onlyOwner noneZeroAddress(_account) {
if (!s_isSigner[_account]) {
revert MultiSigTimelock__AccountIsNotASigner();
}
@>
if (s_signerCount <= 1) {
revert MultiSigTimelock__CannotRevokeLastSigner();
}
uint256 indexToRemove = type(uint256).max;
for (uint256 i = 0; i < s_signerCount; i++) {
if (s_signers[i] == _account) {
indexToRemove = i;
break;
}
}
if (indexToRemove < s_signerCount - 1) {
s_signers[indexToRemove] = s_signers[s_signerCount - 1];
}
s_signers[s_signerCount - 1] = address(0);
s_signerCount -= 1;
s_isSigner[_account] = false;
_revokeRole(SIGNING_ROLE, _account);
}
function testRevokeSigningRole() public grantSigningRoles {
multiSigTimelock.revokeSigningRole(SIGNER_TWO);
multiSigTimelock.revokeSigningRole(SIGNER_THREE);
multiSigTimelock.revokeSigningRole(SIGNER_FOUR);
multiSigTimelock.revokeSigningRole(SIGNER_FIVE);
}
If check can be added to control if number of signers are going below treshold.
//-- WHERE ERRORS DECLARED --
+ error MultiSigTimelock__CannotRevokeBelowTreshold();
function revokeSigningRole(address _account) external nonReentrant onlyOwner noneZeroAddress(_account) {
// CHECKS
if (!s_isSigner[_account]) {
revert MultiSigTimelock__AccountIsNotASigner();
}
- // Prevent revoking the first signer (would break the multisig), moreover, the first signer is the owner of the contract(wallet)
- if (s_signerCount <= 1) {
- revert MultiSigTimelock__CannotRevokeLastSigner();
- }
+ // Prevent revoking below REQUIRED_COFIRMATIOS to not lock the system.
+ if (s_signerCount <= REQUIRED_CONFIRMATIONS) {
+ revert MultiSigTimelock__CannotRevokeBelowTreshold();
+ }
// Find the index of the account in the array
uint256 indexToRemove = type(uint256).max; // Use max as "not found" indicator
for (uint256 i = 0; i < s_signerCount; i++) {
if (s_signers[i] == _account) {
indexToRemove = i;
break;
}
}
// Gas-efficient array removal: move last element to removed position
if (indexToRemove < s_signerCount - 1) {
// Move the last signer to the position of the removed signer
s_signers[indexToRemove] = s_signers[s_signerCount - 1];
}
// Clear the last position and decrement count
s_signers[s_signerCount - 1] = address(0);
s_signerCount -= 1;
s_isSigner[_account] = false;
_revokeRole(SIGNING_ROLE, _account);
}