TwentyOne

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

Incorrect Handling of cardValue == 0 and cardValue == 1 in dealersHand Function

Summary

The dealersHand function in the TwentyOne contract has two critical flaws:

  1. King Handling: The function does not correctly handle the King (cardValue == 0), causing it to contribute 0 to the dealer's total score instead of the correct value of 10.

  2. Dynamic Ace Handling: The function fails to dynamically adjust the value of the Ace (cardValue == 1) between 1 and 11, leading to inaccurate dealer scores when the Ace should be treated as 11 to benefit the dealer.

Vulnerability Details

Issue 1: Missing King Handling

  • Cause: The function does not include a condition to check for cardValue == 0, which corresponds to the King after the % 13 operation.

  • Impact: When the King is part of the dealer's hand, it is incorrectly assigned a value of 0, resulting in an inaccurate total score for the dealer.

Issue 2: Missing Dynamic Ace Handling

  • Cause: The function assigns a static value of 1 to Aces without accounting for the option to treat them as 11 when the total score is ≤ 21.

  • Impact: Aces are underutilized, leading to suboptimal dealer totals that deviate from standard Blackjack rules.

Code Snippet
The problematic code in the dealersHand function:

if (cardValue >= 10) {
dealerTotal += 10; // Kings (cardValue == 0) are incorrectly excluded here
} else {
dealerTotal += cardValue; // Aces are not dynamically adjusted
}

Impact

  1. Inaccurate Dealer Scores: Both the King and Ace are mishandled, which can lead to incorrect game outcomes and an unfair advantage or disadvantage for the player.

  2. Gameplay Disruption: The contract fails to follow the standard rules of Blackjack, compromising its integrity and usability.

  3. Erosion of Trust: Misleading dealer scores can result in players losing confidence in the fairness and correctness of the contract.

Tools Used

  • Manual Code Review: Identified the absence of logic for handling the King and dynamic Ace adjustment.

  • Test Scenarios: Verified behavior by simulating dealer hands with combinations of Kings and Aces.

Recommendations

Fix 1: Proper King Handling

  • Add a condition to treat cardValue == 0 as 10, ensuring that Kings contribute correctly to the dealer's total score.

Fix 2: Dynamic Ace Handling

  • Implement logic to dynamically adjust the value of Aces between 1 and 11 based on the dealer's current total score.


Fixed Code for dealersHand

function dealersHand(address player) public view returns (uint256) {
uint256 dealerTotal = 0;
uint256 aceCount = 0; // Track the number of Aces
for (uint256 i = 0; i < dealersDeck[player].dealersCards.length; i++) {
uint256 cardValue = dealersDeck[player].dealersCards[i] % 13; // Map card to 1–13
if (cardValue == 0 || cardValue >= 10) {
// Face cards and Kings
dealerTotal += 10;
} else if (cardValue == 1) {
// Count Aces and assume each as 11 initially
aceCount++;
dealerTotal += 11;
} else {
// Numeric cards (2–9)
dealerTotal += cardValue;
}
}
// Adjust Aces if total exceeds 21
while (dealerTotal > 21 && aceCount > 0) {
dealerTotal -= 10; // Convert one Ace from 11 to 1
aceCount--;
}
return dealerTotal;
}

Test Scenarios

Scenario 1: Dealer Has a King (cardValue == 0)

  • Input: Dealer's cards = [0, 7] (King and 7)

  • Current Output (Buggy): dealerTotal = 0 + 7 = 7

  • Fixed Output: dealerTotal = 10 (King) + 7 = 17

Scenario 2: Dealer Has an Ace Treated as 11

  • Input: Dealer's cards = [1, 9] (Ace and 9)

  • Current Output (Buggy): dealerTotal = 1 + 9 = 10

  • Fixed Output: dealerTotal = 11 (Ace) + 9 = 20

Scenario 3: Dealer's Ace Adjusts to 1

  • Input: Dealer's cards = [1, 10, 5] (Ace, 10, and 5)

  • Current Output (Buggy): dealerTotal = 1 + 10 + 5 = 16

  • Fixed Output: dealerTotal = 1 (Ace as 1) + 10 + 5 = 16

Scenario 4: Dealer Has Multiple Aces

  • Input: Dealer's cards = [1, 1, 9] (Two Aces and 9)

  • Current Output (Buggy): dealerTotal = 1 + 1 + 9 = 11

  • Fixed Output: dealerTotal = 11 (First Ace) + 1 (Second Ace) + 9 = 21


Conclusion

The proposed fixes ensure the following:

  1. Kings (cardValue == 0) are correctly assigned a value of 10.

  2. Aces are dynamically adjusted between 1 and 11, optimizing the dealer's score while adhering to the rules of Blackjack.

These changes improve the contract's reliability, fairness, and alignment with gameplay expectations.

Updates

Lead Judging Commences

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

Wrong ace value

Asymmetric calculation of hands is rigged in the player`s favor.

Support

FAQs

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