SNARKeling Treasure Hunt

First Flight #59
Beginner FriendlyGameFiFoundry
100 EXP
Submission Details
Impact: low
Likelihood: low

(LOW)`emergencyWithdraw` forbids `recipient == owner`, so the owner cannot rescue funds to their own cold wallet

Author Revealed upon completion

Location: contracts/src/TreasureHunt.sol:276

Description

The emergency withdraw function explicitly blocks sending back to the owner:

require(recipient != address(0) && recipient != address(this) && recipient != owner, "INVALID_RECIPIENT");

An emergency typically means the owner wants to move funds to a safer wallet they directly control. Blocking the owner as recipient forces them to use a third address, which is precisely the wrong UX in a real emergency.

Risk (L)

Likelihood: Low. only triggered during an emergency withdraw attempt.

Impact: Low. Friction in emergency recovery; owner may have to deploy a temporary receiving contract or use another EOA, costing time during an active incident.

Proof of Concept

function test_OwnerCannotEmergencyWithdrawToSelf() public {
vm.prank(owner);
hunt.pause();
vm.prank(owner);
vm.expectRevert(bytes("INVALID_RECIPIENT"));
hunt.emergencyWithdraw(payable(owner), 1 ether);
}

Run:

forge test --match-test test_OwnerCannotEmergencyWithdrawToSelf -vv

The test passes, the owner is blocked from rescuing funds to their own address.

Recommended Mitigation

Remove the recipient != owner restriction:

- require(recipient != address(0) && recipient != address(this) && recipient != owner, "INVALID_RECIPIENT");
+ require(recipient != address(0) && recipient != address(this), "INVALID_RECIPIENT");

Support

FAQs

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

Give us feedback!