[H-2] Inconsistent Logic when counting player's and dealer's card value
Description: In the playersHand and dealersHand functions, the logic used to sum up the card value is not consistent.
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;
}
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;
}
When counting the card value for the player's hand, cards 13, 26, 39, and 52 are treated to have a value of 10 for the player's hand, but a value of 0 for the dealer's hand.
Impact: This inconsistency results in the dealer having reduced chances of drawing cards that have a value of 10, which would result there being inconsistent odd of winning each game.
Proof of Code:
Insert the following in TwentyOne.t.sol
function test_UnfairLogicForDealerAndPlayer() public pure {
uint256[] memory simulatedCards = new uint256[]();
simulatedCards[0] = 6;
simulatedCards[1] = 2;
simulatedCards[2] = 13;
simulatedCards[3] = 1;
uint256 playerTotal = 0;
for (uint256 i = 0; i < simulatedCards.length; i++) {
uint256 cardValue = simulatedCards[i] % 13;
if (cardValue == 0 || cardValue >= 10) {
playerTotal += 10;
} else {
playerTotal += cardValue;
}
}
uint256 dealerTotal = 0;
for (uint256 i = 0; i < simulatedCards.length; i++) {
uint256 cardValue = simulatedCards[i] % 13;
if (cardValue >= 10) {
dealerTotal += 10;
} else {
dealerTotal += cardValue;
}
}
assert(playerTotal != dealerTotal);
}
Recommended Mitigation: Change the card value logic for the dealer to be consistent with the player, and with a standard deck of playing cards
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) {
+ if (cardValue == 0 || cardValue >= 10) {
dealerTotal += 10;
} else {
dealerTotal += cardValue;
}
}
return dealerTotal;
}