PuppyRaffle::selectWinner allows winner predictionThe PuppyRaffle::selectWinner function attempts to generate a random winner index using keccak256 hashing of msg.sender, block.timestamp, and block.difficulty.
In the EVM, these variables are not secure sources of entropy. block.timestamp can be slightly manipulated by miners/validators, and block.difficulty (replaced by prevrandao post-Merge) is known before the transaction is finalized. Because an attacker can calculate the result of this hash off-chain using current block data, they can choose to only call selectWinner or enter the raffle when the calculation guarantees them a win.
The vulnerability stems from using deterministic on-chain variables for randomness in src/PuppyRaffle.sol. The hash calculation can be perfectly replicated by any external observer.
Likelihood: High. Any sophisticated user or bot can monitor the state of the blockchain and compute the winner index in real-time.
Impact: High. The fairness of the raffle is compromised. An attacker can ensure they (or a specific address) win the prize every time, effectively stealing the pool from honest participants.
The following Foundry test proves that an attacker can pre-calculate the winner using the exact same logic as the contract.
The protocol should utilize a Verifiable Random Function (VRF), such as Chainlink VRF, to obtain provably fair and tamper-proof randomness from an off-chain oracle.
uint256 winnerIndex = uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % players.length;
// Call Chainlink VRF and handle the random number in a callback
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.