TwentyOne

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

Incorrect Handling of Aces in playersHand and dealersHand Function Leads to Miscalculated Hand Totals

Summary

In the TwentyOne contract, the playersHand and dealersHand function is responsible for calculating the total value of a player's hand in the game. However, the current implementation does not properly handle Aces, which can have a value of either 1 or 11 depending on the total hand value. This oversight results in inaccurate hand totals, potentially causing the contract to misjudge whether a player has exceeded 21 or reached the best possible hand. This could negatively affect the game logic and fairness, leading to incorrect outcomes.

Vulnerability Details

The playersHand and dealersHand functions iterates through the player's cards and calculates their total value. While it handles face cards (Jack, Queen, King) correctly, it fails to account for the dynamic value of Aces. An Ace is always counted as 1 in the current implementation, regardless of whether counting it as 11 would yield a better hand value without exceeding 21.

Current implementation:

function playersHand(address player) public view returns (uint256) {
uint256 playerTotal = 0;
for (uint256 i = 0; i < playersDeck[player].playersCards.length; i++) {
uint256 cardValue = playersDeck[player].playersCards[i] % 13;
if (cardValue == 0 || cardValue >= 10) {
playerTotal += 10;
} else {
playerTotal += cardValue;
}
}
return playerTotal;
}

The lack of proper Ace handling can lead to situations where the player's total is unnecessarily low or a valid hand is incorrectly flagged as a bust.

Example Scenario

Initial Setup:

  • A player is dealt two cards Aces and a 10.

Execution:

  • The playersHand function calculates the hand total as follows:

    • Each Ace is counted as 1.

    • The total is 1 (Ace) + 10 = 11.

Outcome:

  • The correct total should be 11 (Ace) + 10 = 21, but the function returns 11 due to improper Ace handling.

  • This could lead to incorrect decisions in the game, such as the player losing or hitting unnecessarily.

Impact

Game Logic Errors:

  • Miscalculated hand totals result in incorrect game outcomes, undermining the integrity of the game.

  • Player Dissatisfaction:

    • Players may lose confidence in the game's fairness due to incorrect handling of hands containing Aces.

  • Negative User Experience:

    • Unfair losses or misjudged game decisions caused by this bug could reduce player engagement and trust in the platform.

Tools Used

Manual Review

Recommendations

To ensure the playersHand and dealersHand function calculates accurate hand totals, implement logic to dynamically handle Aces as either 1 or 11. The function should count Aces as 1 initially and then adjust their value to 11 if doing so would not cause the player to exceed 21.

Updated implementation:

function playersHand(address player) public view returns (uint256) {
uint256 playerTotal = 0;
uint256 aceCount = 0;
for (uint256 i = 0; i < playersDeck[player].playersCards.length; i++) {
uint256 cardValue = playersDeck[player].playersCards[i] % 13;
if (cardValue == 0 || cardValue >= 10) {
playerTotal += 10;
} else if (cardValue == 1) {
aceCount += 1;
playerTotal += 1;
} else {
playerTotal += cardValue;
}
}
while (aceCount > 0 && playerTotal <= 11) {
playerTotal += 10;
aceCount -= 1;
}
return playerTotal;
}

This implementation correctly handles Aces, ensuring that they contribute optimally to the hand total without causing a bust.

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.