feeAddress Is Never Validated Against address(0), Permanently Locking All Protocol Fees
Severity: Low
Description
The constructor and changeFeeAddress both accept any address for feeAddress with no zero-address guard. If address(0) is passed — by accident or
misconfiguration — all accumulated fees are sent to the burn address and are unrecoverable.
withdrawFees transfers the full totalFees balance directly to feeAddress with no fallback or override path, so there is no way to redirect funds after the
fact.
constructor(uint256 _entranceFee, address _feeAddress, uint256 _raffleDuration) {
@> feeAddress = _feeAddress; // no zero-address check
raffleDuration = _raffleDuration;
entranceFee = _entranceFee;
}
function changeFeeAddress(address newFeeAddress) external onlyOwner {
@> feeAddress = newFeeAddress; // no zero-address check
emit FeeAddressChanged(newFeeAddress);
}
Risk
Likelihood:
Deployment mistakes (copy-paste errors, scripting bugs) commonly pass address(0) for address parameters
A single changeFeeAddress(address(0)) call by the owner permanently destroys all future fee withdrawals
Impact:
All protocol fees sent to address(0) are permanently lost — ETH cannot be recovered from the zero address
No financial loss to players, but the protocol operator loses 100% of accumulated revenue
Proof of Concept
Deploying with address(0) as the fee address silently succeeds, and any subsequent withdrawFees call sends ETH to the burn address.
PuppyRaffle broken = new PuppyRaffle(1 ether, address(0), 1 days);
// No revert. withdrawFees will later send all fees to address(0).
Recommended Mitigation
Add a zero-address check wherever feeAddress is assigned.
constructor(uint256 _entranceFee, address _feeAddress, uint256 _raffleDuration) {
require(_feeAddress != address(0), "PuppyRaffle: Fee address cannot be zero");
feeAddress = _feeAddress;
function changeFeeAddress(address newFeeAddress) external onlyOwner {
require(newFeeAddress != address(0), "PuppyRaffle: Fee address cannot be zero");
feeAddress = newFeeAddress;
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.