The PuppyRaffle::withdrawFees function uses the balance of the smart contract inside a require. An attacker can sending eth to the contract through a selfdestruct.
The PuppyRaffle::withdrawFees check if there are active players by checking the difference between the smart contract balance and the total fees.
An attacker can create a contract and send a smaller value to entranceFee via the selfdestruct function, thus blocking the contract and no longer being able to collect the fees.
I verify the vulnerability with a test:
I created an attacker contract called Attacker.sol in src folder
I created a test called SelfDestruct.t.sol inside test folder, where I verify withdrawFees function works inside the testWithdrawFees test, and in the testSelfDestruct test I called attacker.SelfDestructAttack(); before withdrawFees and check that the function reverts.
In the event that ´entranceFee´ is for example 1 ether, if the attacker adds 0.5 ether to the balance of the contract with the selfdestruct function, the withdrawFees function will never allow the move the fees to the feeAddress address.
Foundry
Manual review
It is recommended not to use the smart contract balance, address(this).balance in this case, in the controls, but to use a dedicated variable.
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.