TwentyOne

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

Incorrect Card Deck Initialization in initializeDeck Function

Summary

The initializeDeck(address player) function is intended to initialize a deck of 52 cards for the player, as required by the rules of the game. However, due to an off-by-one error in the loop, the deck is initialized with only 50 cards instead of 52. This deviation from the standard 52-card deck compromises the integrity of the game logic and fairness. The issue arises from starting the loop at i = 1 and iterating up to i <= 52.

Vulnerability Details

The initializeDeck function is defined as follows:

function initializeDeck(address player) internal {
require(
availableCards[player].length == 0,
"Player's deck is already initialized"
);
for (uint256 i = 1; i <= 52; i++) {
availableCards[player].push(i);
}
}

This logic should populate the availableCards array with integers from 1 to 52, representing a standard deck of cards. However, the actual array length ends up being only 50 cards due to a miscalculation in the loop. As a result, the game operates with an incomplete deck, potentially leading to unexpected behaviors during gameplay.

Observed Behavior

A test case was written to examine the initialized deck:

function testUserLossingWithHitFunction() public {
vm.startPrank(player1);
uint256 twoCards = twentyOne.startGame{value: 1 ether}();
console.log("twoCards: ", twoCards);
vm.stopPrank();
uint256[] memory availablerCards = twentyOne.getAvailableCards(player1);
console.log("availablerCards l: ", availablerCards.length);
}

Output:

Logs:
twoCards: 14
availablerCards l: 50

The deck's length is 50 instead of the expected 52 cards, confirming the issue in initializeDeck.

Root Cause Analysis

The problem lies in the for loop:

for (uint256 i = 1; i <= 52; i++) {
availableCards[player].push(i);
}

The deck is initialized starting at i = 1, which is correct. However, due to an off-by-one error in iterating to i <= 52, only 50 cards are added instead of 52.

Impact

  1. Incomplete Deck:

    • The game operates with an incomplete deck of 50 cards instead of the standard 52-card deck.

    • This deviation can lead to unexpected outcomes in gameplay, such as fewer card combinations available for players and the dealer.

  2. Game Integrity Compromised:

    • The issue undermines the fairness and consistency of the game, violating the standard rules of twenty-one.

  3. Potential for Exploitation:

    • Savvy players might exploit the smaller deck size to calculate probabilities more effectively, gaining an unfair advantage.

Tools Used

  • Forge (Foundry): Used for deploying and testing the contract.

  • EVM Logs and Console Output: Verified the actual length of the initialized deck using debug logs.

  • Manual Code Review: Identified the off-by-one error in the loop.

Recommendations

  1. Update the Loop in initializeDeck: Replace the current loop in the initializeDeck function with the corrected version:

    for (uint256 i = 1; i <= 54; i++) {
    availableCards[player].push(i);
    }
  2. Test the Updated Logic: Write additional test cases to confirm that the deck length is exactly 52 after initialization.

    function testDeckInitializationCorrectness() public {
    twentyOne.initializeDeck(player1);
    uint256[] memory availablerCards = twentyOne.getAvailableCards(player1);
    assertEq(availablerCards.length, 52, "Deck should contain 52 cards");
    }
  3. Validate Gameplay Mechanics: Verify other game functions, such as hit() or stand(), to ensure they correctly handle the updated deck.

  4. Comprehensive Audits: Perform a full audit of game logic to identify and fix any other potential issues related to deck handling or game rules.

By addressing this issue, the game will align with the standard rules of twenty-one and provide a fair playing environment for all participants.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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