DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

No Validation for Insufficient Balance in MultiSigWallet Contract

Summary

The MultiSigWallet contract lacks proper balance validation before executing transactions. When an approved transaction is executed, the contract attempts to send ETH without first verifying if it has sufficient funds. This can lead to failed transactions and potential denial of service conditions.

Vulnerability Details

The MultiSigWallet contract implements a 2-of-2 multisig wallet where both owners must approve transactions before execution. However, the contract's executeTransaction function attempts to send ETH without first validating if the contract has sufficient balance to cover the transaction.

Vulnerable Code

function executeTransaction(uint256 _txId) external onlyOwners {
require(_txId < transactions.length, "Invalid transaction ID");
Transaction storage txn = transactions[_txId];
require(!txn.executed, "Transaction already executed");
require(txn.approvedByOwner1 && txn.approvedByOwner2, "Not enough approvals");
txn.executed = true;
// No balance check before attempting transfer
(bool success,) = payable(txn.to).call{value: txn.value}("");
require(success, "Transaction failed");
emit TransactionExecuted(_txId, txn.to, txn.value);
}

The vulnerability exists in the following flow:

  1. Owner submits a transaction for a specific ETH amount

  2. Both owners approve the transaction

  3. executeTransaction is called without balance validation

  4. If contract balance is insufficient, the transaction reverts after approvals

  5. The transaction remains in a "approved but unexecutable" state

Severity

Medium - While no funds can be lost, core functionality can be disrupted

Impact

  • Transactions approved by both owners can fail during execution

  • Gas is wasted on failed transaction attempts

  • Contract functionality can be blocked if transactions are queued with amounts exceeding the wallet's balance

  • Owners must manually track the wallet's balance to ensure transaction viability

  • The transaction remains in a "approved but unexecutable" state

Tools Used

Manual review

Foundry for POC

Recommendations

  • Add balance validation before execution:

function executeTransaction(uint256 _txId) external onlyOwners {
require(_txId < transactions.length, "Invalid transaction ID");
Transaction storage txn = transactions[_txId];
require(!txn.executed, "Transaction already executed");
require(txn.approvedByOwner1 && txn.approvedByOwner2, "Not enough approvals");
// Add balance check
require(
address(this).balance >= txn.value,
"Insufficient contract balance"
);
txn.executed = true;
(bool success,) = payable(txn.to).call{value: txn.value}("");
require(success, "Transaction failed");
emit TransactionExecuted(_txId, txn.to, txn.value);
}
  • Add a view function to check transaction executability:

function isTransactionExecutable(uint256 _txId)
public
view
returns (bool)
{
if (_txId >= transactions.length) return false;
Transaction storage txn = transactions[_txId];
return (
!txn.executed &&
txn.approvedByOwner1 &&
txn.approvedByOwner2 &&
address(this).balance >= txn.value
);
}
  • Consider adding balance validation at submission:

function submitTransaction(address _to, uint256 _value) external onlyOwners {
require(_value <= address(this).balance, "Amount exceeds balance");
// ... rest of function
}
Updates

Appeal created

n0kto Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Users mistake, only impacting themselves.

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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