TwentyOne

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

Player Loses Bet on a Tie (Deviation from Standard Blackjack Rules)

Summary

The contract does not handle ties (when the player and dealer have the same hand value) according to standard blackjack rules. Instead of resulting in a "push" where the player’s wager is returned, the current logic declares the dealer as the winner, causing the player to lose their bet. This behavior deviates from the expected rules of blackjack, where a tie does not result in a loss for the player. This discrepancy could lead to player dissatisfaction and loss of trust in the game’s fairness.

Vulnerability Details

Root Cause:

  • The call function resolves the game by comparing the player’s and dealer’s hands:

    if (dealerHand > 21) {
    endGame(msg.sender, true); // Player wins
    } else if (playerHand > dealerHand) {
    endGame(msg.sender, true); // Player wins
    } else {
    endGame(msg.sender, false); // Player loses
    }
  • If the player’s hand is equal to the dealer’s hand, the game defaults to the else branch, resulting in the player losing their wager.

  • Symptoms:

    • When the player and dealer have the same total hand value (e.g., both have 20):

      • The player’s bet is forfeited, and the dealer is declared the winner.

    • There is no logic to handle a tie (push), which is standard in blackjack.

  • Deviation from Project Details:

    • The project aims to follow standard blackjack rules. In classic blackjack, a tie results in a "push," where the player’s wager is returned.

Impact

Player Financial Loss:

  • Players unfairly lose their wager in a tie scenario, which goes against the rules of blackjack.

  • Trust and Transparency Issues:

    • Players may perceive the game as unfair or rigged if ties consistently result in losses.

  • Reputation Risk:

    • The discrepancy from standard blackjack rules could harm the protocol’s reputation and deter users from participating.

Tools Used

Manual code review.

Recommendations

  1. Implement Tie Logic (Push Rule):

    • Update the call function to handle ties appropriately by returning the player’s wager in case of a tie:

      if (dealerHand > 21) {
      endGame(msg.sender, true); // Player wins
      } else if (playerHand > dealerHand) {
      endGame(msg.sender, true); // Player wins
      } else if (playerHand == dealerHand) {
      // Push logic: return the player's wager
      payable(msg.sender).transfer(1 ether);
      emit GameResult(msg.sender, "Push - Tie", playerHand, dealerHand);
      } else {
      endGame(msg.sender, false); // Player loses
      }
  2. Document Tie Behavior (If Not Changed):

    • If the contract behavior remains unchanged, explicitly state in the project documentation that a tie results in a loss for the player, deviating from standard blackjack rules. Example:

      • "In the TwentyOne protocol, ties result in the dealer winning the game, and the player’s wager is forfeited. This differs from the standard blackjack rule where ties result in a push."

  3. Emit Events for Transparency:

    • Emit detailed game result events to ensure players understand the outcome:

      event GameResult(address indexed player, string result, uint256 playerHand, uint256 dealerHand);
  4. Test Tie Scenarios:

    • Add test cases to ensure the behavior for ties aligns with the documentation or push logic:

      • Player and dealer both have 20.

      • Player and dealer both have 21 (but not blackjack).

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 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.