DatingDapp

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

Lack of Balance Check in Transaction Execution

Summary

The executeTransaction function does not check whether the contract has enough ETH before attempting to send funds. This can lead to transaction failures, wasted gas, and a potential denial-of-service (DoS) scenario for pending transactions.

Vulnerability Details

Function Affected:

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;
(bool success, ) = payable(txn.to).call{value: txn.value}("");
require(success, "Transaction failed");
emit TransactionExecuted(_txId, txn.to, txn.value);
}

Issue:

  • The contract does not check if it has enough balance before calling .call{value: txn.value}("").

  • If the contract does not have enough ETH, the transaction fails and reverts, consuming gas but not executing the payment.

  • Pending transactions could never be executed if the contract balance is depleted.

Impact

**Gas Wastage: **Users attempting to execute transactions lose gas fees if the contract does not have enough funds.

**Denial of Service (DoS) Risk: **If multiple transactions are approved but cannot be executed, they remain stuck in the contract forever.

**Funds Mismanagement: **If an owner approves a large transaction, but another transaction depletes the balance before execution, the transaction can never be completed.

Tools Used

Manuel Review

Recommendations

Modify executeTransaction to check the contract balance before sending funds:

require(address(this).balance >= txn.value, "Insufficient contract balance");

Fixed 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");
require(address(this).balance >= txn.value, "Insufficient contract balance"); // ✅ Fix added
txn.executed = true;
(bool success, ) = payable(txn.to).call{value: txn.value}("");
require(success, "Transaction failed");
emit TransactionExecuted(_txId, txn.to, txn.value);
}
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.