MultiSig Timelock

First Flight #55
Beginner FriendlyWallet
100 EXP
Submission Details
Impact: high
Likelihood: medium

Signer Reduction Causes Governance Lock (Deadlock)

Author Revealed upon completion

Root + Impact

Description

  • Normal Behavior

    The multisig timelock is designed to require a fixed number of confirmations (REQUIRED_CONFIRMATIONS) from active signers before a transaction can be executed.

    Under normal conditions, the number of active signers should always be sufficient to reach the required confirmation threshold, ensuring that governance actions remain executable.


  • Issue

    When signers are revoked via revokeSigningRole, the total number of active signers (s_signerCount) can drop below REQUIRED_CONFIRMATIONS.

    However, the required confirmation threshold is not updated accordingly. As a result, no future transaction can ever collect enough confirmations, permanently locking governance functionality.

// Root cause: REQUIRED_CONFIRMATIONS is static and does not adapt to signer reduction
function revokeSigningRole(address signer) external onlyOwner {
_revokeRole(SIGNING_ROLE, signer);
s_signerCount--;
// @> REQUIRED_CONFIRMATIONS remains unchanged
}

Risk

Likelihood:

  • Occurs whenever the owner removes one or more signers without coordinating threshold updates

  • Likely during operational signer rotation, key compromise response, or DAO governance changes

Impact:

  • Permanent denial of service for all governance actions

  • Funds and protocol configuration become irreversibly locked

Proof of Concept

function test_GovernanceLock_WhenSignerReduced() public {
uint256 txId = timelock.proposeTransaction(
address(0xBEEF),
1 ether,
""
);
vm.prank(s1);
timelock.confirmTransaction(txId);
vm.prank(s2);
timelock.confirmTransaction(txId);
// Remove a signer, reducing total signers below REQUIRED_CONFIRMATIONS
timelock.revokeSigningRole(s3);
// Remaining signers can no longer reach the threshold
vm.prank(s1);
vm.expectRevert();
timelock.executeTransaction(txId);
}

Explanation:
This PoC demonstrates that once the signer count is reduced below the required confirmation threshold, no transaction—regardless of how many confirmations it previously received—can ever be executed. This results in a permanent denial of service for the multisig governance.

Recommended Mitigation

function revokeSigningRole(address signer) external onlyOwner {
_revokeRole(SIGNING_ROLE, signer);
s_signerCount--;
+ if (REQUIRED_CONFIRMATIONS > s_signerCount) {
+ REQUIRED_CONFIRMATIONS = s_signerCount;
+ }
}

Explanation:
This mitigation enforces a critical governance invariant by ensuring that the multisig always retains enough active signers to meet the execution threshold. Preventing signer count from dropping below REQUIRED_CONFIRMATIONS eliminates the risk of permanently locking governance.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!