TwentyOne

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

DoS vulnerabilities in the TwentyOne contract

Summary

The TwentyOne contract, contains several Denial of Service vulnerabilities. These arise primarily from unbounded loops, improper Ether handling, and state-update patterns that violate Solidity best practices.

Vulnerability Details

ìnitializeDeck()function contains a loop that iterates 52 times to populate the player's deck of cards. This operation consumes significant gas, especially when called for multiple players in the same block. If the loop exceeds the block gas limit, the transaction will revert. This could prevent the game from starting for a player, resulting in a DoS.

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

The call function repeatedly invokes dealersHand within a while loop. Each invocation iterates over the dealer's cards, leading to potential hitting the block gas limit as the number of dealer cards increases, potentially locking players out of completing their games.

while (dealersHand(msg.sender) < standThreshold) {
uint256 newCard = drawCard(msg.sender);
addCardForDealer(msg.sender, newCard);
}

Impact

Players may be unable to start or complete games due to gas exhaustion caused by unbounded loops.

Tools Used

  • Manual Review

Recommendations

Replace the unbounded loop in initializeDeck with a predefined deck stored in storage or calldata:

uint256[52] defaultDeck = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
// Add remaining cards
];
function initializeDeck(address player) internal {
require(
availableCards[player].length == 0,
"Player's deck is already initialized"
);
availableCards[player] = defaultDeck;
}

Cache the result of dealersHand to avoid repeated iterations

uint256 dealerTotal = dealersHand(msg.sender);
while (dealerTotal < standThreshold) {
uint256 newCard = drawCard(msg.sender);
addCardForDealer(msg.sender, newCard);
dealerTotal = dealersHand(msg.sender);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 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.