MultiSig Timelock

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

19Dec2025_AuditReport9_MultiSigTimelock

Author Revealed upon completion

Root + Impact

Description

  • Signature Mapping Not Cleared After Execution

  • After a transaction is executed, the s_signatures mapping still retains the confirmation data. This wastes storage gas and could potentially cause confusion in transaction analysis. While it doesn't directly enable attacks due to the executed flag check, it represents poor state management and unnecessary gas costs for storage.

// Root cause in the codebase with @> marks to highlight the relevant section
function _executeTransaction(uint256 txnId) internal {
Transaction storage txn = s_transactions[txnId];
// ...
txn.executed = true;
// ...
// s_signatures[txnId] is never cleared!
emit TransactionExecuted(txnId, txn.to, txn.value);
}

Risk

Likelihood:

  • After executing transaction ID 0, s_signatures[0][signerAddress] still returns true for all signers who confirmed, wasting storage slots permanently.

Impact:

  • Unnecessary storage costs and potential for state analysis confusion. Each confirmation stored costs approximately 20,000 gas that could be refunded if cleared.

Proof of Concept

Clear signature mappings after execution to refund gas:

function _executeTransaction(uint256 txnId) internal {
Transaction storage txn = s_transactions[txnId];
// ...
txn.executed = true;
// ...
// s_signatures[txnId] is never cleared!
emit TransactionExecuted(txnId, txn.to, txn.value);
}

Recommended Mitigation

Clear signature mappings after execution to refund gas:

function _executeTransaction(uint256 txnId) internal {
Transaction storage txn = s_transactions[txnId];
// ... checks ...
// Clear signatures for gas refund
for (uint256 i = 0; i < s_signerCount; i++) {
address signer = s_signers[i];
if (s_signatures[txnId][signer]) {
delete s_signatures[txnId][signer];
}
}
txn.executed = true;
// ... continue execution ...
}

Support

FAQs

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

Give us feedback!