There's a dangerous check that was made in the absence of fallback functions in the contract. That check is in the withdrawFees() function that allows the feeAddress to withdraw fees.
Initial State: winner has been selected and the victim is ready to call withdrawFees().
Step 1: the attacker decides to send a bit of ether, just enough to make address(this).balance different from uint256(totalFees).
Step 2: require(address(this).balance == uint256(totalFees), "PuppyRaffle: There are currently players active!"); fails when the victim calls withdrawFees().
Victim cannot take its profits... Funds locked in the contract
Manual analysis
Add a receive function to prevent contracts/EOA from sending eth
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.