TwentyOne

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

Dynamic Ace Value Miscalculation in playersHand Function

Summary

The playersHand function in the TwentyOne contract does not handle Ace cards (cardValue = 1) correctly. It fails to dynamically adjust the value of the Ace between 1 and 11 based on the current total score. This leads to inaccurate hand totals, which can affect game outcomes.

Vulnerability Details

  • Location: The issue occurs in the playersHand function when iterating through the player's cards and calculating the total hand value.

  • Cause: Ace cards are always treated as having a value of 1. There is no logic to assign the value 11 to an Ace when it benefits the player (i.e., when the total score does not exceed 21).

  • Code Snippet:

    if (cardValue == 0 || cardValue >= 10) {
    playerTotal += 10;
    } else {
    playerTotal += cardValue;
    }
    • The code lacks a mechanism to dynamically adjust Ace values (1 or 11).

    • No consideration for reducing Ace values from 11 to 1 if the total score exceeds 21.

Impact

  1. Gameplay Disruption: Players may lose unfairly because their hand totals are miscalculated.

  2. Deviation from Rules: The contract does not align with the standard rules of Blackjack, where Aces are dynamic in value.

  3. Player Confidence: Misleading results can erode trust in the game's fairness and the contract's reliability.

Tools Used

  • Manual Code Review: Identified the lack of Ace handling logic.

  • Testing Scenarios: Simulated hand calculations with combinations including Aces to observe incorrect behavior.

Recommendations

Dynamic Ace Handling: Implement logic to adjust Ace values between 1 and 11 based on the total score:

  • Initially assign 11 to an Ace.

  • Reduce the Ace value to 1 only if the total score exceeds 21.

  1. Refactored Code:

function playersHand(address player) public view returns (uint256) {\
uint256 playerTotal = 0;\
uint256 aceCount = 0; // Track the number of Aces
for (uint256 i = 0; i < playersDeck[player].playersCards.length; i++) {
uint256 cardValue = playersDeck[player].playersCards[i] % 13;
if (cardValue == 0 || cardValue >= 10) {
playerTotal += 10; // Face cards are worth 10
} else if (cardValue == 1) {
aceCount++;
playerTotal += 11; // Initially treat Ace as 11
} else {
playerTotal += cardValue; // Numeric cards retain their value
}
}
// Adjust Aces if total exceeds 21
while (playerTotal > 21 && aceCount > 0) {
playerTotal -= 10; // Convert one Ace from 11 to 1
aceCount--;
}
return playerTotal;
}
  1. Testing Scenarios:

    • Input: Player's hand = [1, 10, 9].

    • Expected Output: Total = 1 (Ace) + 10 + 9 = 20 (Ace is treated as 1).

    • Input: Player's hand = [1, 8].

    • Expected Output: Total = 11 (Ace) + 8 = 19 (Ace is treated as 11).

  2. Automated Testing: Add unit tests to cover all scenarios involving Aces to ensure correctness.

By addressing this issue, the playersHand function will accurately calculate scores, aligning the contract's behavior with the expected rules of Blackjack.

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.