The PuppyRaffle contract uses a mapping (tokenIdToRarity) to associate token IDs with their respective rarities. This mapping is modified in the selectWinner function, which is public and can be called by anyone. The logic in this function can be manipulated, leading to incorrect rarity assignments.
The selectWinner function calculates a rarity value based on the msg.sender and block.difficulty, and then assigns this rarity to a token ID in the tokenIdToRarity mapping. An attacker can influence this calculation, they could potentially manipulate the rarity of a token.
The potential vulnerability lies in the calculation of rarity in the selectWinner function. The rarity is calculated using the keccak256 hash of the msg.sender and block.difficulty.
uint256 rarity = uint256(keccak256(abi.encodePacked(msg.sender, block.difficulty))) % 100;
An attacker could potentially manipulate this calculation in the following ways:
Predicting block.difficulty: The block.difficulty is a value that can be influenced by miners. If an attacker is also a miner, they could potentially manipulate this value when they mine a block.
An attacker could potentially create multiple addresses and call the selectWinner function from these addresses to influence the rarity calculation.
Here's an example of how an attacker might manipulate the rarity:
In this example, the attacker creates a contract that calls the selectWinner function from multiple addresses. This could potentially influence the rarity calculation.
The impact of this vulnerability would be that the attacker could potentially manipulate the rarity of the tokens they win, which could disrupt the fairness of the raffle and impact the perceived value of the tokens.
manual code review
To mitigate this vulnerability, consider implementing additional checks or using a more secure source of randomness in the selectWinner function. For example as explained in my high severity findings, you could use a commit-reveal scheme or an off-chain oracle to generate random numbers.
Additionally, consider making the selectWinner function only callable by the contract owner or a trusted party to prevent potential manipulation by attackers.
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.