The provided function uses block.timestamp
and block.difficulty
to generate pseudorandom numbers for selecting a winner and determining rarity in the PuppyRaffle
game. This approach could worked in the Ethereum Proof-of-Work (PoW) consensus mechanism, but it has issues in the Ethereum Proof-of-Stake (PoS) consensus mechanism.
In Pos block.timestamp
is 12 seconds after the previous block so it is predictable (as spec here https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#compute_timestamp_at_slot).
Also block.difficulty
will not be used in the same way as in PoW. After the merge to PoS, the EVM 0x44 opcode, which currently returns DIFFICULTY, will be replaced by PREVRANDAO, which is the output of the randomness beacon provided by the beacon chain in the previous block.
As per solidiry docs (https://docs.soliditylang.org/en/v0.8.18/units-and-global-variables.html#block-and-transaction-properties):
block.difficulty (uint): current block difficulty (EVM < Paris). For other EVM versions it behaves as a deprecated alias for block.prevrandao (EIP-4399).
The function will not work as expected after the transition to PoS. The calculation of winnerIndex
and rarity
will not be valid because block.difficulty
will not return the same kind of value as it does in PoW. This could lead to unpredictable and potentially unfair results in the raffle game.
Manual review
Suggested to use a Chainlink Oracle like VRF v2 to get a random number.
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.