Puppy Raffle

AI First Flight #1
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

Missing Zero Address Validation in changeFeeAddress()

Root + Impact

Description

  • The changeFeeAddress() function does not validate that the new fee address is not the zero address. If the owner accidentally sets feeAddress to address(0), all future fee withdrawals will fail permanently, locking funds in the contract forever since there's no way to recover from this mistake.

// Root cause in the codebase with @> marks to highlight the relevant section
function changeFeeAddress(address newFeeAddress) external onlyOwner {
feeAddress = newFeeAddress; // No validation!
emit FeeAddressChanged(newFeeAddress);
}

Risk

Likelihood:

The issue does not require a malicious attacker; it can occur due to human error by the contract owner.

  • Admin functions like changeFeeAddress() are typically executed infrequently, but when they are, a simple mistake (e.g., passing address(0) or an uninitialized variable) is enough to trigger the issue.

  • There is no built-in safeguard or confirmation step in the vulnerable version, increasing the chance of accidental misconfiguration.

  • Once triggered, the impact is irreversible, even though the action itself is simple.

Summary:

  • Ease of occurrence: Moderate

  • Requires special permissions: Yes (owner)

  • Accidental vs malicious: Accidental is more likely

➡️ Overall, while not easily exploitable by external attackers, the risk of occurrence through operational error makes the likelihood Medium.

Impact:

  • If feeAddress is set to zero address, all accumulated and future fees become permanently locked in the contract. The withdrawFees() function will always revert when trying to send ETH to address(0), making fees unrecoverable.

Proof of Concept

  • changeFeeAddress() does not validate against address(0)

  • Fees have accumulated in the contract

  • withdrawFees() sends ETH to feeAddress

  • single administrative mistake can cause irreversible loss of protocol revenue. Input validation on critical admin functions is mandatory.

// Owner accidentally sets fee address to zero
puppyRaffle.changeFeeAddress(address(0));
// Later, after fees accumulate...
puppyRaffle.withdrawFees(); // Reverts: cannot send ETH to zero address
// Fees are now permanently locked

Recommended Mitigation

To prevent permanent locking of protocol fees due to an invalid feeAddress, implement the following safeguards:

1. Validate Admin Input (Required)

Reject the zero address when updating the fee recipient.

2. Two-Step Address Change (Recommended)

Reduce the risk of accidental misconfiguration by requiring acceptance from the new address.

3. Emergency Recovery Mechanism (Optional)

Allow the owner to recover fees if withdrawals fail.

4. Add Monitoring & Alerts

Emit events on fee address changes and monitor them off-chain to detect misconfiguration early.

Recommended Fix: Input validation + two-step address update.

- remove this code
+ add this code
function changeFeeAddress(address newFeeAddress) external onlyOwner {
+ require(newFeeAddress != address(0), "PuppyRaffle: Fee address cannot be zero");
feeAddress = newFeeAddress;
emit FeeAddressChanged(newFeeAddress);
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!