TwentyOne

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

startGame() function does not check that the contract itself has sufficient ETH to pay out player's winnings

Summary

When a player starts the game, the startGame() does not require the TwentyOne contract to have at least 2 ETH to be able to transfer to the player in the event that the player wins.

Player will not receive the winnings of 2 ETH even if they won. The player will also lose the 1ETH they have sent when they start the game.

Vulnerability Details

In the startGame() function, it only checks that player has sent at least 1 ETH, but does not check that the contract has enough ETH to fund the winnings.

function startGame() public payable returns (uint256) {
address player = msg.sender;
require(msg.value >= 1 ether, "not enough ether sent");
initializeDeck(player);
uint256 card1 = drawCard(player);
uint256 card2 = drawCard(player);
addCardForPlayer(player, card1);
addCardForPlayer(player, card2);
return playersHand(player);
}

Once the player is satisfied with their playersHand, the call() function will be called to determine the winner. In this function call, the transfer will revert when the TwentyOne contract has insufficient funds. However, as this function is called separately from when the 1ETH was sent by the player to start the game, the player would then also not have that 1ETH reverted and refunded back to them.

Player will not be able to receive any winnings, and will also lose 1ETH that they sent to start the game.

Assuming the address(TwentyOne).balance starts at 0, the first 2 players who win will have their 1ETH locked in the contract and not get winnings unrightfully. If player 3 wins, there is enough ETH to pay out to this winner.

However, since there is no other exit function other than endGame(), it is not possible for any other entity, even the TwentyOne contract owner, to retrieve this 2ETH sent by the first 2 players to return it back to them.

Additionally, at any time the contract balance falls back to less than 2ETH along the way, players who win will also have their 1 ETH locked in the contract.

Impact

Loss of funds for player.

Tools Used

Manual Review

Recommendations

Consider checking that the TwentyOne contract has sufficient funds in startGame() function.

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.