Summary
The getDealerCards and the dealersHand functions never return the dealer's position. This is because the dealer's hand and cards are both set and reset when a player calls TwentyOne::call. This means that all players never get any information about the dealer's position, completely usurping the rules of classic blackjack where players have partial information on the dealer's position.
Vulnerability Details
Proof of Code:
Place the below code into TwentyOneTest in TwentyOne.t.sol
function testDealerPositionFunctionsNeverReturnActualDealerPosition() public {
vm.deal(address(twentyOne), 2 ether);
vm.startPrank(player1);
twentyOne.startGame{value: 1 ether}();
uint256[] memory dealerCards = twentyOne.getDealerCards(player1);
uint256 dealersHand = twentyOne.dealersHand(player1);
uint256[] memory emptyArray;
console.log("Dealer hand: ", dealersHand);
assertEq(dealerCards, emptyArray);
assertEq(dealersHand, 0);
twentyOne.call();
dealerCards = twentyOne.getDealerCards(player1);
dealersHand = twentyOne.dealersHand(player1);
console.log("Dealer hand: ", dealersHand);
assertEq(dealerCards, emptyArray);
assertEq(dealersHand, 0);
vm.stopPrank();
}
Impact
All players end up playing an unfair game, not aligned with the rules of classic blackjack.
Tools Used
Foundry suite
Recommendations
The protocol should consider updating their documentation to clearly state that TwentyOne is a variant of classic blackjack, specifically one that doesn't give the players any information on the dealer's position. In addition, the misleading functions should be removed.
.
.
.
- 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;
- }
.
.
.
- function getDealerCards(address player) public view returns (uint256[] memory) {
- return dealersDeck[player].dealersCards;
- }