Title: Enum default NICE=0 allows uninitialized addresses to collect presents
Severity: High
Impact: Every blockchain address can mint an NFT without any Santa interaction.
Likelihood: High — zero preconditions, one call after Christmas timestamp.
Reference Files: src/SantasList.sol:69-74, src/SantasList.sol:147-166
The Status enum places NICE at position 0, making it the mapping default. Both s_theListCheckedOnce and s_theListCheckedTwice return Status(0) == NICE for any uninitialized address, so collectPresent passes every address. The vulnerable code:
Santa never needs to check anyone — every address is already "double-checked as NICE" by default.
Impact: High. The entire two-phase checking system is meaningless. Billions of addresses qualify as NICE without Santa ever calling checkList or checkTwice.
Likelihood: High. Wait for Christmas timestamp, call collectPresent(). One transaction, zero setup.
Every single Ethereum address is pre-approved to collect a Christmas NFT with no authorization whatsoever.
A completely unknown address collects an NFT — Santa never checked them, proving the default NICE bypass.
Moving NOT_CHECKED_TWICE to position 0 makes it the default. Uninitialized addresses fail the NICE check in collectPresent, correctly reverting with SantasList__NotNice.
## Description `collectPresent` function is supposed to be called by users that are considered `NICE` or `EXTRA_NICE` by Santa. This means Santa is supposed to call `checkList` function to assigned a user to a status, and then call `checkTwice` function to execute a double check of the status. Currently, the enum `Status` assigns its default value (0) to `NICE`. This means that both mappings `s_theListCheckedOnce` and `s_theListCheckedTwice` consider every existent address as `NICE`. In other words, all users are by default double checked as `NICE`, and therefore eligible to call `collectPresent` function. ## Vulnerability Details The vulnerability arises due to the order of elements in the enum. If the first value is `NICE`, this means the enum value for each key in both mappings will be `NICE`, as it corresponds to `0` value. ## Impact The impact of this vulnerability is HIGH as it results in a flawed mechanism of the present distribution. Any unchecked address is currently able to call `collectPresent` function and mint an NFT. This is because this contract considers by default every address with a `NICE` status (or 0 value). ## Proof of Concept The following Foundry test will show that any user is able to call `collectPresent` function after `CHRISTMAS_2023_BLOCK_TIME` : ``` function testCollectPresentIsFlawed() external { // prank an attacker's address vm.startPrank(makeAddr("attacker")); // set block.timestamp to CHRISTMAS_2023_BLOCK_TIME vm.warp(1_703_480_381); // collect present without any check from Santa santasList.collectPresent(); vm.stopPrank(); } ``` ## Recommendations I suggest to modify `Status` enum, and use `UNKNOWN` status as the first one. This way, all users will default to `UNKNOWN` status, preventing the successful call to `collectPresent` before any check form Santa: ``` enum Status { UNKNOWN, NICE, EXTRA_NICE, NAUGHTY } ``` After modifying the enum, you can run the following test and see that `collectPresent` call will revert if Santa didn't check the address and assigned its status to `NICE` or `EXTRA_NICE` : ``` function testCollectPresentIsFlawed() external { // prank an attacker's address vm.startPrank(makeAddr("attacker")); // set block.timestamp to CHRISTMAS_2023_BLOCK_TIME vm.warp(1_703_480_381); // collect present without any check from Santa vm.expectRevert(SantasList.SantasList__NotNice.selector); santasList.collectPresent(); vm.stopPrank(); } ```
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.