Description: In ChoosingRam
contract, there are multiple functions where uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao, ...)))
was used to get a random number to do certain tasks. There are some issues with this attempt
Impact: Using block-related properties such as block.timestamp
and block.prevrandao
(or its predecessor block.difficulty
) does not provide true randomness and can be manipulated by miners
Predictability: Since block.timestamp and block.prevrandao are known or can be influenced by miners, the output can be predicted or manipulated.
Miner Manipulation: Miners can choose to include transactions in a block at specific times or modify the block timestamp slightly to influence the output.
Proof of Concept:
Miners calls Dussehra::enterPeopleWhoLikeRam
and get a token minted with their respective tokenId.
Miners sees that ChoosingRam::selectRamIfNotSelected
is being called which uses uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % ramNFT.tokenCounter();
to get a random number to choose a Ram.
Miners could calculate potential outcomes for various timestamps and find an optimal value.
The miner could then adjust the block's timestamp within allowed limits to produce a random value that favors a specific participant.
Their Ram gets selected and gets the privilege to kill ravana, call withdraw
function and get the money.
Mitigation: Consider using Chainlink VRF as it provides a secure source of randomness that cannot be predicted or influenced by any participant, including miners.
Here is a demo code of its implementation
Tools: Manual Review
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.