TwentyOne

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

Incorrect Handling of Push (Tie) Scenarios

Summary

The smart contract for the TwentyOne blackjack game improperly handles tie scenarios (pushes). Under standard blackjack rules, if the dealer and player have the same total, the game is a "push," and the player’s bet is returned. However, the contract currently treats ties as a dealer win, which is inconsistent with classic gameplay rules.

Vulnerability Details

Location: The vulnerability exists in the call() function:

else {
emit PlayerLostTheGame( "Dealer's hand is higher, dealers winning hand: ", dealerHand );
endGame(msg.sender, false);
}
  • Issue: When the player and dealer hands are equal, the dealer is declared the winner, and the player loses their bet. This violates blackjack rules.

Impact

  • Fairness Violation: Players lose their bet in cases where they should have received a push, leading to unfair gameplay.

  • User Trust: This discrepancy from standard rules could harm the credibility of the platform.

  • User Losses: Players are financially disadvantaged in a manner not aligned with classic blackjack gameplay.

Tools Used

Manual Review

Recommendations

Add tie scenario to the endGame() method, that would include 3 args. Such as :

function endGame(address player, bool playerWon, bool isPush) 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 (isPush) {
payable(player).transfer(1 ether); // Return only the initial bet
emit PlayerPayout(player, 1 ether);
} else if (playerWon) {
payable(player).transfer(2 ether); // Transfer the prize to the player
emit PlayerPayout(player, 2 ether);
}
}

And then in the call() function add a new case, and add a new event PlayerAndDealerEqualHands

if (dealerHand > 21) {
emit PlayerWonTheGame(
"Dealer went bust, players winning hand: ",
playerHand
);
endGame(msg.sender, true, false);
} else if (playerHand > dealerHand) {
emit PlayerWonTheGame(
"Dealer's hand is lower, players winning hand: ",
playerHand
);
endGame(msg.sender, true, false);
} else if (playerHand == dealerHand) {
emit PlayerPushHands(
"Push: Player and dealer have equal hands.",
playerHand
);
endGame(msg.sender, true, true); // Add a flag to return only the player's initial bet.
} else {
emit PlayerLostTheGame(
"Dealer's hand is higher, dealers winning hand: ",
dealerHand
);
endGame(msg.sender, false, false);
}
Updates

Lead Judging Commences

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

Tie case

Support

FAQs

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