MultiSig Timelock

First Flight #55
Beginner FriendlyWallet
100 EXP
View results
Submission Details
Impact: low
Likelihood: high
Invalid

Missing Proposer Address in `TransactionProposed` Event

Root + Impact

The event definition and emission doesnot have the proposer field. The design focuses on transaction metadata but fails to capture the identity of the caller.Malicious or erroneous proposals cannot be traced back to the responsible signer via logs.

Description

The MultiSigTimelock::_proposeTransaction function emits the TransactionProposed event when a new transaction is created. However, the event currently logs only the transactionId, to, and value fields. It does not include the proposer’s address (msg.sender). This omission prevents stakeholders from knowing who initiated a proposal, reducing transparency in the multisig governance process.

function _proposeTransaction(address to, uint256 value, bytes memory data) internal returns (uint256) {
uint256 transactionId = s_transactionCount;
s_transactions[transactionId] = Transaction({
to: to, value: value, data: data, confirmations: 0, proposedAt: block.timestamp, executed: false
});
s_transactionCount++;
@> emit TransactionProposed(transactionId, to, value);
return transactionId;
}

Risk

Likelihood:

  • Every transaction proposal will emit an event without proposer identity.

Impact:

  • Loss of accountability and transparency in governance.

Proof of Concept

Recommended Mitigation

Add proposer address to the event

Modify _proposeTransaction() to log msg.sender

//The event should be like this
- event TransactionProposed(uint256 indexed transactionId, address indexed to, uint256 value);
+ event TransactionProposed(uint256 indexed transactionId, address indexed to, uint256 value, address indexed proposer);
//Then function modification
function _proposeTransaction(address to, uint256 value, bytes memory data) internal returns (uint256) {
uint256 transactionId = s_transactionCount;
s_transactions[transactionId] = Transaction({
to: to, value: value, data: data, confirmations: 0, proposedAt: block.timestamp, executed: false
});
s_transactionCount++;
- emit TransactionProposed(transactionId, to, value);
+ emit TransactionProposed(transactionId, to, value, msg.sender);
return transactionId;
}
Updates

Lead Judging Commences

kelechikizito Lead Judge 4 days ago
Submission Judgement Published
Invalidated
Reason: Too generic

Support

FAQs

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

Give us feedback!