TwentyOne

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

H01 - the implementation of the `call` function goes against standard blackjack rule

Summary

In the call function of the TwentyOne.sol contract, a standThreshold variable was used to determine if the dealer takes a "hit" or "stand". But the standard blackjack rule is the the dealer takes a hit if their hand is any value lower than 17 and they take a stand if their hand is 17 or higher.

Vulnerability Details

function call() public {
require(
playersDeck[msg.sender].playersCards.length > 0,
"Game not started"
);
uint256 playerHand = playersHand(msg.sender);
// Calculate the dealer's threshold for stopping (between 17 and 21)
uint256 standThreshold = (uint256(
keccak256(
abi.encodePacked(block.timestamp, msg.sender, block.prevrandao)
)
) % 5) + 17;
// Dealer draws cards until their hand reaches or exceeds the threshold
while (dealersHand(msg.sender) < standThreshold) {
uint256 newCard = drawCard(msg.sender);
addCardForDealer(msg.sender, newCard);
}
uint256 dealerHand = dealersHand(msg.sender);

It could be seen that there was an attempt to generate a random number between 17 and 21 and use that variable as the standThreshold but there is zero need for this variable as it does nothing but antagonise the rule of the blackjack game

Impact

It puts the players at risk of losing when they should be winning. The standThreshold gives the dealer the ability to hit when they should stand. This could take their hand above the players' and help them win. It deviates from the rule of blackjack with the introduction of standThreshold.

Tools Used

Manual review, ChatGPT

Recommendations

The call function should be modified so that the standThreshold variable ceases to exist and it should be changed to 17 where the variable was used in the function.

function call() public {
require(
playersDeck[msg.sender].playersCards.length > 0,
"Game not started"
);
uint256 playerHand = playersHand(msg.sender);
// Dealer draws cards until their hand reaches or exceeds the threshold
while (dealersHand(msg.sender) < 17) {
uint256 newCard = drawCard(msg.sender);
addCardForDealer(msg.sender, newCard);
}
uint256 dealerHand = dealersHand(msg.sender);
Updates

Lead Judging Commences

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

The Dealer's Play - Dealer must stand on 17

Support

FAQs

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