RapBattle
determines the winner of a battle by generating a random number and comparing it to the defender rapper skill. The random number is generated using the keccak256
hash of the current block's timestamp, the block prevrandao
value, and the challenger's address. This allows the challenger to predict the outcome of the battle by copying the random number generation into their own contract.
Import into OneShotTest.t.sol
Add the following lines to OneShotTest.t.sol::RapBattleTest
Add the following lines to the setUp
function in OneShotTest.t.sol::RapBattleTest
Copy-paste the testRNGAttack
function to OneShotTest.t.sol::RapBattleTest
Copy-paste the WinOnly
contract to OneShotTest.t.sol
Run forge test --mt testRNGAttack -vv
in the terminal
An attacker can predict the outcome of a battle and only enter when they are guaranteed to win. This allows the attacker to win battles without risking any balance.
Manual review
Use a more secure random number generation method to determine the winner of a battle. Consider using Chainlink VRF oracles to generate random numbers.
According to Chainlink VRF documentation:
https://docs.chain.link/vrf/v2/getting-started
"Randomness is very difficult to generate on blockchains. This is because every node on the blockchain must come to the same conclusion and form a consensus. Even though random numbers are versatile and useful in a variety of blockchain applications, they cannot be generated natively in smart contracts. The solution to this issue is Chainlink VRF, also known as Chainlink Verifiable Random Function."
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.