TwentyOne

First Flight #29
Beginner FriendlyGameFiFoundrySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

Winner Won't Receive Reward If the Contract Balance is Less Than 2 Ether

Summary

Vulnerability Details

In the TwentyOne::startGame function, there is no check to ensure that the contract has enough ether to pay out the winner. If the contract balance is less than 2 ether, the winner will not receive their reward.

Impact

If the contract balance is insufficient (less than 2 ether) and a player wins, they will not receive their payout.

Tools Used

The following scenario demonstrates how a winner will not receive their reward if the contract balance is insufficient:

  • Initial Contract Balance: 0 ether

  • A player initiates startGame and stakes 1 ether

  • Contract Balance: 1 ether

  • If the player wins, they will receive no payout, since the contract balance is less than 2 ether, causing the transfer to fail (← [OutOfFunds] EvmError: OutOfFunds):

Recommendations

To address this, consider adding a pending reward mapping for players to claim their prize later when the contract has sufficient funds:

+ mapping (address winner => bool hasClaimed ) public pendingReward;
function endGame(address player, bool playerWon) internal {
delete playersDeck[player].playersCards; // Clear the player's cards
delete dealersDeck[player].dealersCards; // Clear the dealer's cards
delete availableCards[player]; // Reset the deck
- if (playerWon) {
+ if (playerWon && address(this).balance >= 2 ether) {
// @audit-issue using transfer which has the gas limit of 2900
payable(player).transfer(2 ether); // Transfer the prize to the player
emit FeeWithdrawn(player, 2 ether); // Emit the prize withdrawal event
}
+ else {
+ pendingReward[player] = true
+ }
}
+ function claimPendingReward() public {
+ require(pendingReward[msg.sender], "You have no pending reward")
+ require(address(this).balance >= 2 ether, "Insufficient fund in contract balance");
+ pendingWinner[msg.sender] = false;
+ payable(msg.sender).transfer(2 ether);
+ emit FeeWithdrawn(msg.sender, 2 ether);
+ }
Updates

Lead Judging Commences

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

Insufficient balance for payouts / Lack of Contract Balance Check Before Starting Game

Support

FAQs

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