trickOrTreat
function has a weak psuedorandom generator that can be predicted in advance and thus the attacker can call trickOrTreat
based on the predictable random output. Furthermore when the random = 2 then the attacker can increment the nextTokenId
without transferring any ether (msg.value = 0). This will prevent other users from buying that treat, even if the owner does not buy it; by not calling resolveTrick
function.
The pseudorandom generator has three fields that will remain the same when the attacker calls the `trickOrTreat` function from their malicious contract.
The only variable that will generate a new random value is nextTokenId
within a function call. Since nextTokenId
can only be incremented when either random = 1 and user has paid atleast half the cost, when random = 2 then user can book the treat by paying nothing and when random is > 2, the user pays the exact cost of the treat.
The incentive that the attacker recieves is when he is able to generate random = 1 and pays half the cost. The nextTokenId
that will return a random = 1 can be pre-generated for a fixed timestamp and blockrandao. Then the attacker just have to increment the nextTokenId
and profit from the treat bought at half the price.
Here is a test file created in foundry that replicates this attack for 200 treats. Among these 200 treats only 4 were able to generate a random = 1. If the number of treats are increased then more nextTokenId
will generate random = 1.
High - As the attacker can technically profit from the attack if the number of treats are huge and book some treats for free when random = 2 and never buy them.
Manual Review
Use a better psuedorandom generator function like the one suggested in known issues.
It's written in the README: "We're aware of the pseudorandom nature of the current implementation. This will be replaced with Chainlink VRF in later builds." This is a known issue.
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.