The TwentyOne contract incorrectly calculates the value of King cards (13) in the dealer's hand. Due to a logic discrepancy between playersHand() and dealersHand() functions, the King card (value 13) is calculated as 0 instead of 10 when modulo operation is applied, leading to incorrect hand totals for the dealer.
Location: src/TwentyOne.sol
https://github.com/Cyfrin/2024-11-TwentyOne/blob/main/src/TwentyOne.sol#L43-L52
The vulnerability exists in the dealersHand() function where face card values are calculated differently than in the playersHand() function. While playersHand() correctly handles both King (13) and face cards, dealersHand() fails to account for cards with value 0 after modulo operation.
Proof of Concept:
The incorrect calculation of dealer's face cards has several significant impacts:
Game Logic Breaking
Dealer's hand totals are incorrectly calculated when holding King cards
Game outcomes are unfairly skewed in favor of players when dealer holds Kings
Breaks standard Blackjack rules and expected game behavior
Economic Impact
Contract may incorrectly determine game winners
Players might win when they should lose, or vice versa
Potential loss of contract funds due to incorrect game outcomes
Trust and Fairness
Inconsistent card value calculations between player and dealer
Undermines the fairness of the game
Could be exploited by players aware of this discrepancy
Foundry Testing Framework
Manual Code Review
Custom test cases for dealer face card scenarios
Fix Card Value Calculation:
The core issue is that using modulo 13 makes Kings (13) evaluate to 0. Instead, we should handle face cards (11, 12, 13) consistently by treating them all as 10:
This fix ensures:
All face cards (Jack=11, Queen=12, King=13) are worth 10
Number cards (1-10) maintain their correct values
Consistent with standard Blackjack rules
Standardize Card Value Calculation:
Apply the same fix to both playersHand() and dealersHand() functions
Consider extracting the card value calculation into a separate pure function:
Add Comprehensive Testing:
Test all face card combinations (10, Jack, Queen, King)
Verify all face cards are valued at 10
Include edge cases with multiple face cards
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.