withdraw() is intended to be an owner-controlled function, but it has no msg.sender or onlyOwner check.
As a result, anyone can trigger the post-hunt withdrawal once claimsCount >= MAX_TREASURES.
Likelihood:
This happens deterministically after claimsCount reaches MAX_TREASURES
Any address can call withdraw() and force the remaining funds to be sent to the owner.
Impact:
Funds are still sent to owner, so this does not allow direct theft.
However, it violates the documented access-control model and allows arbitrary users to trigger an owner-only administrative action before the owner chooses to do so.
The PoC deploys and funds TreasureHunt, then advances the contract to the post-hunt state where claimsCount == MAX_TREASURES. Once that condition is met, an arbitrary attacker address calls withdraw() successfully. The ETH is sent to owner, but the unauthorized caller is able to execute an administrative function that the README describes as owner-controlled.
Restrict withdraw() to the owner by adding an explicit check.
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.
The contest is complete and the rewards are being distributed.