TwentyOne

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

[H-3] TwentyOne::playersHand Calculation Does Not Follow Official BlackJack Rules for Ace Calculation

Summary

In BlackJack, the Ace can have a value of either 11 or 1, depending on the current hand value of the player. If the current player's hand value plus 11 is less than or equal to 21, then the Ace should be counted as 11; otherwise, it is counted as 1. This rule is not honored in the TwentyOne::playersHand function, which adds the Ace as 10 in all cases (or 1, depending if cardValue result of 0 or cardValue result of 1 is considered an Ace).

Vulnerability Details

In the TwentyOne::playersHand function, the current card value is calculated as:

uint256 cardValue = playersDeck[player].playersCards[i] % 13

where the card value could be between 0 and 12. When the card value is 0 (representing the Ace as it is the 13th card), the following code adds 10 to the player's total:

if (cardValue == 0 || cardValue >= 10) {
playerTotal += 10;
} else {
playerTotal += cardValue;
}

This does not follow BlackJack rules, as the Ace should be added as either 11 or 1, depending on the player's current hand total.

Impact

High Impact: This bug occurs 100% of the time. The TwentyOne::playersHand calculation is incorrect, which may result in players losing when they should have won, or winning when they should have lost.

Tools Used

  1. Manual Review

  2. Foundry (PoC unit tests can be provided upon request)

  3. ChatGPT

Recommendations

  1. Update the logic to properly handle the cardValue for an Ace. The revised function may look as follows:

function playersHand(address player) public view returns (uint256) {
uint256 playerTotal = 0;
uint256 numberOfAces = 0;
for (uint256 i = 0; i < playersDeck[player].playersCards.length; i++) {
uint256 cardValue = playersDeck[player].playersCards[i] % 13;
if (cardValue == 0) {
// Ace
numberOfAces += 1;
playerTotal += 11;
} else if (cardValue >= 10) {
// Face cards: Jack, Queen, King
playerTotal += 10;
} else {
playerTotal += cardValue + 1; // Offset 1 to map 1->2, 2->3, ..., 9->10
}
}
// Adjust for Aces if total exceeds 21
while (playerTotal > 21 && numberOfAces > 0) {
playerTotal -= 10;
numberOfAces -= 1;
}
return playerTotal;
}
Updates

Lead Judging Commences

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

Wrong ace value

Support

FAQs

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