No Validation of Transaction Data Parameter
The proposeTransaction function accepts arbitrary bytes data without any validation. This could allow the owner to propose transactions that call functions on the recipient contract in unintended ways, potentially bypassing security measures of the recipient contract or causing unexpected behavior.
Likelihood:
The proposeTransaction function accepts arbitrary bytes data without any validation. This could allow the owner to propose transactions that call functions on the recipient contract in unintended ways, potentially bypassing security measures of the recipient contract or causing unexpected behavior.
Impact:
Malicious or accidental inclusion of harmful data could cause recipient contracts to behave unexpectedly, potentially leading to fund loss or contract compromise at the recipient.
The Risk: Arbitrary Execution
The primary vulnerability here is Unvalidated Calldata. Because the function accepts any bytes calldata data without checking its content, an attacker (or a malicious/compromised owner) can propose a payload that causes catastrophic damage.
Key Issues:
• Malicious Payloads: An attacker can craft data that calls sensitive functions like transfer(), approve(), or even selfdestruct() on other contracts held by the MultiSig.
• Delegatecall Injection: As seen in your previous example, if the MultiSig’s execution logic uses delegatecall, the data could be used to overwrite the contract's entire storage, including the owner list itself.
• The "Trojan Horse": Since it's a proposal, other owners might see the to address and assume it is safe, without realizing the data payload contains a hidden malicious command.
Function Whitelisting
This code implements Function Selector Validation, which acts as a firewall for your MultiSig.
• The Selector: The first 4 bytes of any transaction data represent the specific function being called (e.g., transfer(address,uint256)).
• The Guard: By checking s_allowedSelectors, the contract ensures that only pre-approved functions can be proposed. This prevents an owner from proposing hidden malicious calls (like a delegatecall or a storage override) that haven't been vetted.
• The Ether Exception: The selector == bytes4(0) check allows for simple Ether transfers (which have empty data) while still blocking complex, unauthorized contract interactions.
Why this is effective:
It limits the attack surface. Even if an owner's private key is compromised, the attacker cannot use the MultiSig to call "dangerous" functions (like changing the owner list or upgrading the contract) unless those specific function signatures were explicitly whitelisted by the DAO or developers beforehand.
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.