fee withdrawal impossible.The withdrawFees() function sends the fees that has been earned throughout the duration of an active raffle to the feeAddress designated upon deployment of the PuppyRaffle contract. The problem lies in the fact that it checks if the contract balance matches the the amount of fees collected.
Fee withdrawal from the protocol is dependent on the balance of the contract being strictly equal to the total fees collected as denoted here in withdrawFees() below:
To demonstrate we use a sample smart contract that forcibly sends ETH to the contract using selfdestruct which is currently deprecated in solidity but can still be used in this instance.
Attack contract:
Poc test:
Any call to withdraw the protocol fees will be reverted, as a result fees can never be withdrawn from the protocol.
Manual review and foundry.
The usage of strict equality for that check is not recommended in this instance.
A more flexible check like this would suffice.
require(address(this).balance >= uint256(totalFees), "PuppyRaffle: There are currently players active!");
Any amount that is left in the contract balance after the winner has been selected and paid should be withdrawn.
This would allow fees to be withdrawn even though the contract balance is forcibly inflated.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.