The PuppyRaffle::selectWinner function relies on on-chain data to determine randomness, which compromises the quality of randomness in the game.
The contract uses the keccak256 hash of msg.sender, block.timestamp, and block.difficulty to determine the winner. Additionally, it calculates the rarity of the reward puppy using the keccak256 hash of msg.sender and block.difficulty. This method is not truly random and can be predicted by users and manipulated by miners.
The provided test suite demonstrates the vulnerability's validity and severity. It consistently shows that the winner is predictable, given the known on-chain data, highlighting the lack of true randomness.
Requirements
Install Foundry.
Clone the project codebase into your local workspace.
Step-by-step Guide to Run the Test
Ensure the above requirements are met.
Execute the following command in your terminal to run the test:
In the above test, you'll notice how the winner is always playerFour given the known on-chain data, which clearly reinforces the predictability of the winner.
Implications:
Frontrunning: The protocol is exposed to frontrunning. Since the transaction is public on the blockchain, a miner can calculate their chances of winning and enter the game at the exact time with a higher gas price, effectively frontrunning other potential winners.
Refund Manipulation: Winners can calculate their chances of winning and the rarity of the reward puppy. This knowledge allows them to decide whether to get a refund at the last moment, potentially exploiting the system.
Exploit Scenario:
John monitors the PuppyRaffle contract and observes Sarah sending a selectWinner transaction to the mempool.
John realizes that under specific on-chain conditions, he has a higher probability of winning.
He promptly sends a selectWinner transaction with a higher gas fee to frontrun Sarah and secures the raffle win.
Foundry
To address this vulnerability, consider using external sources of randomness via oracles and cryptographically verifying the outcome of the oracle on-chain, for instance, by implementing Chainlink VRF (Verifiable Random Function). This will significantly enhance the randomness and fairness of the game.
Root cause: bad RNG Impact: manipulate winner
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.