Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Weak Randomness Implementation in `PuppyRaffle::selectWinner` Compromises Raffle Randomness

Summary

The PuppyRaffle::selectWinner function relies on on-chain data to determine randomness, which compromises the quality of randomness in the game.

Vulnerability Details

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.

function selectWinner() external {
// ...
- uint256 winnerIndex = uint256(
- keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty)
- ) % players.length;
// ...
- uint256 rarity = uint256(
- keccak256(abi.encodePacked(msg.sender, block.difficulty))
- ) % 100;
// ...
}

Proof of Concept

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.

How to Run the Test

Requirements

  • Install Foundry.

  • Clone the project codebase into your local workspace.

Step-by-step Guide to Run the Test

  1. Ensure the above requirements are met.

  2. Execute the following command in your terminal to run the test:

forge test --match-test "testSelectWinner"

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.

Impact:

Implications:

  1. 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.

  2. 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.

Tools Used

  • Foundry

Recommendations

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.

Updates

Lead Judging Commences

Hamiltonite Lead Judge about 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

weak-randomness

Root cause: bad RNG Impact: manipulate winner

Support

FAQs

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

Give us feedback!