SNARKeling Treasure Hunt

First Flight #59
Beginner FriendlyGameFiFoundry
100 EXP
View results
Submission Details
Severity: low
Valid

updateVerifier() missing zero-address check allows owner to permanently brick all future claims

Root + Impact

Description

  • The constructor correctly guards against a zero-address verifier using the InvalidVerifier error. However, updateVerifier() has no equivalent check, allowing the owner to set the verifier to address(0) — either accidentally or maliciously. Once set, all future claim() calls will silently fail verification and revert with InvalidProof, permanently locking participants out.

// Constructor correctly guards this:
constructor(address _verifier) payable {
// @> zero-address check present here
if (_verifier == address(0)) revert InvalidVerifier();
verifier = IVerifier(_verifier);
}
// updateVerifier() does not:
function updateVerifier(IVerifier newVerifier) external {
require(paused, "THE_CONTRACT_MUST_BE_PAUSED");
require(msg.sender == owner, "ONLY_OWNER_CAN_UPDATE_VERIFIER");
// @> no zero-address check — address(0) accepted silently
verifier = newVerifier;
}

Risk

Likelihood:

  • Requires owner action, accidental mis-paste or wrong address during verifier upgrade

  • Owner is trusted but human error is realistic during contract maintenance

Impact:

  • All future claim() calls revert InvalidProof — participants permanently locked out

  • ETH remains in contract, recoverable by owner via emergency Withdraw(), but hunt is effectively dead

  • InvalidVerifier error is already defined in the contract but unused in this function, clear oversight

Proof of Concept

The hunt.updateVerifier() function is missing an address(0) check.

function testUpdateVerifierZeroAddressBricksContract() public {
vm.startPrank(owner);
hunt.pause();
hunt.updateVerifier(IVerifier(address(0))); // accepted — no zero-address check
hunt.unpause();
vm.stopPrank();
// Any claim now reverts — call to address(0) fails at ABI decoding level
// before InvalidProof is even reached
vm.prank(attacker);
vm.expectRevert();
hunt.claim(hex"deadbeef", bytes32(uint256(1)), payable(recipient));
}

Recommended Mitigation

function updateVerifier(IVerifier newVerifier) external {
require(paused, "THE_CONTRACT_MUST_BE_PAUSED");
require(msg.sender == owner, "ONLY_OWNER_CAN_UPDATE_VERIFIER");
+ if (address(newVerifier) == address(0)) revert InvalidVerifier();
verifier = newVerifier;
}
Updates

Lead Judging Commences

s3mvl4d Lead Judge 18 days ago
Submission Judgement Published
Validated
Assigned finding tags:

no zero-address check in updateVerifier()

The issue is that `updateVerifier()` allows the owner to replace the verifier with an arbitrary address, including `address(0)`, even though the constructor explicitly treats a zero verifier as invalid and reverts with `InvalidVerifier()` during initial deployment. In other words, the contract establishes at deployment time that a null verifier address is not an acceptable configuration, but then fails to preserve that same invariant when the verifier is later updated through the admin recovery path.

Support

FAQs

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

Give us feedback!