TwentyOne

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

Deterministic values should not be used to generate random values.

Summary

The drawCard function that draws cards uses the block.timestamp and block.prevrandao values to generate a randomIndex, which is not random as they have the same value in the same block

Vulnerability Details

Within the same block, the block.timestamp and block.prevrandao values are the same, so the same address will always output the same result if the function is called from that address.

function testPredictableDraws() public {
vm.startPrank(player);
vm.warp(1234);
vm.prevrandao(bytes32(uint256(5678)));
game.startGame{value: 1 ether}();
uint256[] memory firstGameCards = game.getPlayerCards(player);
TwentyOne newGame = new TwentyOne();
vm.deal(address(newGame), 100 ether);
newGame.startGame{value: 1 ether}();
uint256[] memory secondGameCards = newGame.getPlayerCards(player);
console.log("First game initial cards:");
console.log("Card 1:", firstGameCards[0]);
console.log("Card 2:", firstGameCards[1]);
console.log("\nSecond game initial cards:");
console.log("Card 1:", secondGameCards[0]);
console.log("Card 2:", secondGameCards[1]);
bytes32 hash = keccak256(
abi.encodePacked(block.timestamp, player, block.prevrandao)
);
uint256 expectedIndex = uint256(hash) % 52;
console.log("\nCalculated first index:", expectedIndex);
vm.stopPrank();
assertTrue(
firstGameCards[0] == secondGameCards[0] &&
firstGameCards[1] == secondGameCards[1],
"Cards should be identical in both games"
);
}

Impact

If a user determines that his strategy is profitable in a particular block, he can exploit the vulnerability to steal all the balance of the contract, infinitely.

Tools Used

foundry

Recommendations

You should use Chainlink's VRF or something to ensure complete randomness.

Updates

Lead Judging Commences

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