The constructor accepts any amount of ETH via the payable keyword without validating that the contract receives sufficient funds to cover the expected treasure rewards. The protocol documentation states the contract should be funded with 100 ETH (10 treasures x 10 ETH), but there is no on-chain enforcement of this minimum.
Likelihood:
Reason 1: the owner initiates the TreasureHunt contract with less than 100 ETH
Impact:
Impact: Contract can be deployed with insufficient funds (e.g., 1 ETH instead of 100 ETH)
Early claimants may successfully claim treasures but later claimants find the contract has insufficient balance
Creates a "race to claim" dynamic where late participants are denied their expected rewards
Damages protocol credibility and trust
A owner funds the TreasureHunt contract with 85 Eth.
8 hunters successfully claimed the rewards.
There is no other hunters can successfully claim rewards due to lack of funds.
Add a minimum funding check in the contract constructor:
The liquidity-enforcement issue arises because the protocol assumes the hunt will be funded with enough ETH to cover all rewards, but the contract itself does not actively enforce that invariant at deployment time. The constructor accepts arbitrary `msg.value` and only validates the verifier address, even though the contract hardcodes a reward of 10 ether and a maximum of 10 treasures, implying an expected full funding target of 100 ether; the README likewise states that the contract is expected to be funded with enough ETH to cover all rewards and notes that the default deployment flow uses 100 ether. Although the deployment script sets `DEFAULT_INITIAL_FUNDING = 100 ether`, it also allows that amount to be overridden via `vm.envOr("INITIAL_FUNDING", DEFAULT_INITIAL_FUNDING)`, and the only post-deployment balance check is that the contract balance equals the chosen `initialFunding`, not that the chosen amount is actually sufficient to fund the full hunt. As a result, the system can be deployed in an underfunded state after which otherwise valid claims will begin reverting with `NotEnoughFunds()` once the balance drops below a single reward payment.
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.