TwentyOne

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

Incorrect Handling of Ace Values in `playersHand` and `dealersHand` Functions

Summary

The playersHand and dealersHand functions both incorrectly handle Aces, which are represented by cardValue == 0. Aces in Blackjack should be valued as either 1 or 11, depending on the current hand total. However, the current implementation fails to account for this flexibility, leading to incorrect hand totals.

Vulnerability Details

In the playersHand function, Aces are incorrectly valued as 10, which does not reflect their potential value of 1 or 11.

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

In the dealersHand function, Aces are effectively treated as 0, resulting in their value being lost in the calculation.

function dealersHand(address player) public view returns (uint256) {
uint256 dealerTotal = 0;
for (uint256 i = 0; i < dealersDeck[player].dealersCards.length; i++) {
uint256 cardValue = dealersDeck[player].dealersCards[i] % 13;
if (cardValue >= 10) {
dealerTotal += 10;
} else {
dealerTotal += cardValue;
}
}
return dealerTotal;
}

Impact

The incorrect handling of Ace values in both the players' and dealers' hands can potentially result in incorrect game outcomes and unfair payouts.

Tools Used

Manual review.

Recommended Mitigation

Implement logic in both playersHand and dealersHand functions to dynamically assign Aces a value of 1 or 11 based on the current hand total. This can be achieved by initially treating Aces as 11 and then adjusting the total if it exceeds 21 by converting to 1.

function calculateHand(uint256[] memory cards) internal pure returns (uint256) {
uint256 total = 0;
uint256 aceCount = 0;
for (uint256 i = 0; i < cards.length; i++) {
uint256 cardValue = cards[i] % 13;
if (cardValue == 0) {
total += 11;
aceCount++;
} else if (cardValue >= 10) {
total += 10;
} else {
total += cardValue;
}
}
while (total > 21 && aceCount > 0) {
total -= 10;
aceCount--;
}
return total;
}
function playersHand(address player) public view returns (uint256) {
return calculateHand(playersDeck[player].playersCards);
}
function dealersHand(address player) public view returns (uint256) {
return calculateHand(dealersDeck[player].dealersCards);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 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.