TwentyOne

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

`getDealerCards` and `dealersHand` Functions are Useless (Immediate Reset After call)

Summary

The getter functions getDealerCards and dealersHand become ineffective because the dealer’s cards and hand are reset immediately during the execution of the call function. This prevents users from querying the dealer’s cards or hand after the game concludes, making these functions practically useless in their current state.

Vulnerability Details

The dealer’s cards are stored in the dealersDeck mapping and their hand is computed dynamically using the dealersHand function. However, these values are deleted when the endGame function is invoked at the end of the call function:

The dealer’s cards are stored in the dealersDeck mapping and their hand is computed dynamically using the dealersHand function. However, these values are deleted when the endGame function is invoked at the end of the call function:

This reset occurs before the call function completes, leaving no opportunity for users to retrieve the dealer's final hand via the getter functions. As a result:

  1. getDealerCards: Always returns an empty array after call concludes.

  2. dealersHand: Always returns 0 after call concludes.

Impact

Transparency Issue: Users cannot verify the dealer’s cards or hand value after the game ends, undermining trust in the game's fairness.

  • Useless Getter Functions: The getDealerCards and dealersHand functions have no meaningful use after the game ends, making them misleading in their current implementation.

  • Lost Debugging Insights: Developers and auditors lose access to the dealer's final state, which could assist in debugging or validating game integrity.

Tools Used

  • Manual code review.

Recommendations

  • Emit Dealer's Cards and Hand in an Event:
    Log the dealer’s final hand and cards before resetting the state. This preserves the data in transaction logs for future reference:

event DealerFinalState(address indexed player, uint256[] dealerCards, uint256 dealerHand);
emit DealerFinalState(player, dealersDeck[player].dealersCards, dealersHand(player));
  • Delay Reset with a Buffer Period:
    Instead of resetting the dealer’s cards immediately, retain the state temporarily and reset it with a separate resetGame function.
    Example:

mapping(address => bool) public gameEnded;
function endGame(address player, bool playerWon) internal {
gameEnded[player] = true;
if (playerWon) {
payable(player).transfer(2 ether);
emit FeeWithdrawn(player, 2 ether);
}
}
function resetGame(address player) public {
require(gameEnded[player], "Game not ended");
delete dealersDeck[player].dealersCards;
gameEnded[player] = false;
}
  • Remove Useless Getter Functions (If No Fix is Made):

    If no changes are introduced to retain or log dealer data after the game ends, remove getDealerCards and dealersHand to avoid confusion and redundancy.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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