TwentyOne

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

Insecure Random Number Generation Allows Players to Predict Outcomes and Exploit the Game

Root Cause

The contract relies on insecure sources for randomness when drawing cards and determining the dealer's stand threshold. Specifically, it uses block.timestamp, msg.sender, and block.prevrandao as inputs for generating random numbers:

uint256 randomIndex = uint256(
keccak256(
abi.encodePacked(block.timestamp, msg.sender, block.prevrandao)
)
) % availableCards[player].length;

These inputs are either predictable or can be influenced by miners and players:

  • block.timestamp: Can be slightly manipulated by miners within a certain range.

  • msg.sender: Known to the player and can be controlled.

  • block.prevrandao: Previously known value and not sufficiently unpredictable.

As a result, an attacker can predict the outcome of drawCard() and call() functions, allowing them to know which cards they will receive and manipulate the game in their favor.

Impact

An attacker can consistently predict the cards drawn for both themselves and the dealer, as well as the dealer's stand threshold. This enables them to:

  • Win Games Consistently: By knowing the cards and the dealer's behavior, the attacker can make optimal decisions to win each game.

  • Drain Contract Funds: Since the contract pays out 2 ether when the player wins, an attacker can repeatedly exploit this to drain the contract's balance.

  • Undermine Game Fairness: The predictability compromises the integrity of the game, leading to unfair advantages and potential loss of trust from legitimate players.

Recommendations

  • Use a Secure Randomness Source: Integrate Chainlink VRF or another verifiable random function to ensure that random numbers are unpredictable and cannot be manipulated by players or miners.

    // Example integration with Chainlink VRF
    import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
    contract TwentyOne is VRFConsumerBase {
    // Implement VRF logic here
    }
  • Avoid Predictable Inputs: Do not use block.timestamp, blockhash, block.prevrandao, or any other blockchain variables that can be predicted or influenced.

  • Delay Actions Dependent on Randomness: If using an off-chain randomness source, consider introducing a commit-reveal scheme or callback mechanism to handle asynchronous random number generation securely.

  • Limit Player Control: Reduce the amount of control the player has over the inputs used for randomness to minimize exploitation avenues.

  • Audit and Testing: Conduct thorough security audits and testing to identify and mitigate potential vulnerabilities related to randomness and other aspects of the contract.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

[INVALID] Known - Randomness

Randomness Manipulation: The randomness mechanism relies on block.timestamp, msg.sender, and block.prevrandao, which may be predictable in certain scenarios. Consider using Chainlink VRF or another oracle for more secure randomness.

Support

FAQs

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