An attacker is able to front- and back-run a selectRamIfNotSelected call, allowing them to heavily skew (or guarantee) an NFT they own is picked as selectedRam for free, allowing them to collect the event's reward.
An attacker can monitor a chain's mempool for a selectRamIfNotSelected call, then deploy a malicious contract which directly mints (for free) a very large amount of RamNFTs using the unprotected RamNFT::mintRamNFT function.
Create the following example attack contract under src/mocks/SandwichAttack.sol:
Import the attack contract, and include the following test case in Dussehra.t.sol:
Then, run the test case:
For example, say 100 wallets have entered and minted a Ram NFT and paid the associated entranceFee of 1 ether. The organiser then calls selectRamIfNotSelected when enough time has passed. Subsequently, this call is front-run and the attacker's contract is deployed and mints 100,000 NFTs for free (excluding gas). Then, selectRamIfNotSelected is executed, giving the attacker a 99.90% chance (100,000 / 100,100) of being selected. The attacker can ALSO back-run the selectRamIfNotSelected tx, in the same block, to atomically call Dussehra::killRavana and Dussehra::withdraw preventing a previously mentioned block stuffing DOS attack. The attacker has profited 50 ether (50% to the organizer, minus gas fees).
The attacker can potentially work with a malicious validator to manipulate block.timestamp in the random calculation to guarantee one of their tokenIds gets selected.
Manual Review
Add the onlyChoosingRamContract modifier to mintRamNFT to ensure only the ChoosingRam contract can mint Ram NFTs. This removes the scenario where front- and back-running are profitable.
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.