Last Man Standing

First Flight #45
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: low
Valid

Misleading `getContractBalance()` Return Value Due to Direct ETH Transfers

Misleading getContractBalance() Return Value Due to Direct ETH Transfers

Description

This function:

/**
* @dev Returns the current balance of the contract (should match the pot plus platform fees unless payouts are pending).
*/
function getContractBalance() public view returns (uint256) {
return address(this).balance;
}

returns the total ETH balance of the contract.
The NatSpec comment claims it “should match the pot plus platform fees unless payouts are pending,” but this assumption is not guaranteed.

Since the contract implements a receive() function:

receive() external payable {} anyone can send ETH directly to the contract without using claimThrone() or any other accounting mechanism. These “stray” ETH transfers will inflate address(this).balance without updating pot or platformFeesBalance.

This creates a mismatch between the function’s documented purpose and its actual return value.

Risk

Likelihood:

  • High — Anyone can trigger this by simply sending ETH directly to the contract address

Impact:

  • UI/Frontend Misinformation: If the frontend uses getContractBalance() to display the pot size or expected payouts, users will see inflated values, potentially leading to false expectations.

  • Accounting Inconsistency: Off-chain monitoring or analytics relying on getContractBalance() will produce inaccurate data.

  • Possible Social Engineering Vector: An attacker could send a large amount of ETH to make the pot appear massive, attracting players into participating under false pretenses.

Proof of Concept

  • Attacker calls:

(payable(gameAddress)).call{value: 100 ether}("");
  • pot and platformFeesBalance remain unchanged.

  • getContractBalance() now returns previousBalance + 100 ether.

  • Any frontend/UI showing “prize pool” from this value will display misleading information.

Recommended Mitigation

Try and reflect the accountable values in doing so it does not depend on the volatility that `addess(this).balance` can often bring

function getContractBalance() public view returns (uint256) {
- return address(this).balance;
+ return pot + platformFeesBalance;
}
Updates

Appeal created

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Game::getContractBalance doesn't behave as it should

Support

FAQs

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

Give us feedback!