TwentyOne

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

[H-06] Dealer's Initial Up Card Missing Prevents Strategic Player Decisions

Summary

The TwentyOne contract fails to implement a crucial Blackjack rule: the dealer's initial up card. In standard Blackjack, the dealer's face-up card is essential for player decision-making and basic strategy. The current implementation has the dealer draw cards only after the player stands, preventing players from making informed strategic decisions.

Vulnerability Details

Location: src/TwentyOne.sol

https://github.com/Cyfrin/2024-11-TwentyOne/blob/main/src/TwentyOne.sol#L89-L99

The startGame() function only deals cards to the player, with no initial dealer card:

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);
}

The dealer only draws cards after the player has finished their hand:

function call() public {
// ... dealer starts with no cards and only draws here
while (dealersHand(msg.sender) < standThreshold) {
uint256 newCard = drawCard(msg.sender);
addCardForDealer(msg.sender, newCard);
}
}

In standard Blackjack:

  • Dealer must show one face-up card at the start

  • This card is crucial for player strategy

  • Players base hit/stand decisions on dealer's up card

  • Basic strategy charts are built around dealer's visible card

Impact

  1. Strategic Impact

    • Players cannot make informed decisions without dealer's up card

    • Basic Blackjack strategy becomes impossible to implement

    • All hit/stand decisions must be made "blind"

  2. Economic Impact

    • Players cannot properly assess risk/reward

    • Optimal strategy cannot be followed

    • Every game is affected by this missing information

    • Leads to suboptimal plays and unnecessary losses

  3. Game Integrity

    • Violates fundamental Blackjack rules

    • Creates an unfair advantage for the house

    • Makes the game significantly different from standard Blackjack

Tools Used

  • Manual Code Review

  • Standard Blackjack Rule Comparison

Recommendations

Since players can view all contract storage, we recommend a simplified but probabilistically equivalent approach:

  1. Modify startGame() to Deal One Visible Dealer Card:

function startGame() public payable returns (uint256) {
address player = msg.sender;
require(msg.value >= 1 ether, "not enough ether sent");
initializeDeck(player);
// Deal to player
uint256 playerCard1 = drawCard(player);
uint256 playerCard2 = drawCard(player);
addCardForPlayer(player, playerCard1);
addCardForPlayer(player, playerCard2);
// Deal single visible card to dealer
uint256 dealerCard = drawCard(player);
addCardForDealer(player, dealerCard);
emit DealerUpCard(dealerCard);
return playersHand(player);
}
  1. Add New Event and View Function:

event DealerUpCard(uint256 card);
function getDealerUpCard(address player) public view returns (uint256) {
require(dealersDeck[player].dealersCards.length > 0, "No dealer cards");
return dealersDeck[player].dealersCards[0];
}

This approach:

  • Provides the crucial dealer up card information

  • Allows players to make informed strategic decisions

  • Maintains game fairness and standard Blackjack probabilities

  • Acknowledges blockchain's transparent nature

Updates

Lead Judging Commences

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

Dealer's Initial Up Card Missing

Support

FAQs

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