Santa's List

AI First Flight #3
Beginner FriendlyFoundry
EXP
View results
Submission Details
Impact: medium
Likelihood: high
Invalid

SantaToken.mint mints only 1e18 but PURCHASED_PRESENT_COST is 2e18, making buyPresent permanently uncallable by EXTRA_NICE users

Root + Impact

Description

  • collectPresent mints 1e18 SantaTokens to EXTRA_NICE users via SantaToken.mint. But buyPresent requires burning 2e18 tokens (PURCHASED_PRESENT_COST). An EXTRA_NICE user can never accumulate enough tokens from a single collect to buy a present, breaking the core protocol mechanic.

// SantaToken.sol
function mint(address to) external {
_mint(to, 1e18); // mints 1 token
}
// SantasList.sol
uint256 public constant PURCHASED_PRESENT_COST = 2e18; // costs 2 tokens

Risk

Likelihood:

  • Affects every EXTRA_NICE user - the feature is completely broken by default

  • No workaround exists unless user receives tokens from multiple sources

Impact:

  • buyPresent is permanently unusable for any single EXTRA_NICE user

  • The NAUGHTY redemption path advertised in the protocol docs is broken

Proof of Concept

The following test demonstrates that an EXTRA_NICE user receives only 1e18 tokens from collectPresent but
buyPresent requires burning 2e18, making the function permanently uncallable after a single collect:
function testBuyPresentUnusableForExtraNiceUser() public {
address extraNiceUser = makeAddr("extraNiceUser");
// Setup: mark user as EXTRA_NICE
vm.startPrank(santa);
santasList.checkList(extraNiceUser, SantasList.Status.EXTRA_NICE);
santasList.checkTwice(extraNiceUser, SantasList.Status.EXTRA_NICE);
vm.stopPrank();
vm.warp(CHRISTMAS_2023_BLOCK_TIME + 1);
// User collects present and receives 1e18 SantaTokens
vm.startPrank(extraNiceUser);
santasList.collectPresent();
assertEq(santaToken.balanceOf(extraNiceUser), 1e18);
// Approve santasList to spend tokens
santaToken.approve(address(santasList), 2e18);
// buyPresent requires 2e18 but user only has 1e18 - reverts
vm.expectRevert();
santasList.buyPresent(makeAddr("friend"));
vm.stopPrank();
}

Recommended Mitigation

- function mint(address to) external {
- _mint(to, 1e18);
+ function mint(address to) external {
+ _mint(to, 2e18);
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!