Santa's List

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

buyPresent omits the Christmas time gate that collectPresent enforces, allowing pre-unlock present minting

buyPresent does not check the Christmas timestamp that collectPresent enforces, so presents can be minted before the intended unlock date.

Description

  • The present distribution is meant to stay closed until Christmas. collectPresent (src/SantasList.sol:148) reverts with SantasList__NotChristmasYet before CHRISTMAS_2023_BLOCK_TIME.

  • buyPresent (src/SantasList.sol:172) mints the same present NFT but never references CHRISTMAS_2023_BLOCK_TIME, so the time lock is absent on this path. To be clear, this is not the README known issue, which states the date constant may be off by up to 24 hours. That known issue is a tolerance on the value of the constant. The finding here is that buyPresent performs no timestamp check at all, regardless of how the constant is set.

// src/SantasList.sol
function collectPresent() external {
@> if (block.timestamp < CHRISTMAS_2023_BLOCK_TIME) { // gate present here
revert SantasList__NotChristmasYet();
}
// ...
}
function buyPresent(address presentReceiver) external {
@> i_santaToken.burn(presentReceiver); // no timestamp gate
_mintAndIncrement();
}

Risk

Likelihood:

  • Any holder of SantaTokens can call buyPresent before the unlock and mint a present.

Impact:

  • The timed-release invariant that keeps presents closed until Christmas is broken on the buyPresent path, so presents enter circulation before the advertised unlock.

  • The caller still pays tokens, so impact is limited. It is a Low severity issue.

Proof of Concept

collectPresent is shown reverting before Christmas, while buyPresent mints a present at the same pre-Christmas timestamp. The test passes.

function test_F7_buyPresent_sinGateDeNavidad() public {
_fundWithTokens(victim); // warps to Christmas only to fund 1e18 to victim
vm.warp(1); // now we are BEFORE Christmas
// collectPresent is correctly closed before Christmas
address ghost = makeAddr("ghostF7");
vm.prank(ghost);
vm.expectRevert(SantasList.SantasList__NotChristmasYet.selector);
santasList.collectPresent();
// but buyPresent mints a present despite being before Christmas
uint256 nftBefore = santasList.balanceOf(victim);
vm.prank(victim);
santasList.buyPresent(victim);
assertLt(block.timestamp, santasList.CHRISTMAS_2023_BLOCK_TIME());
assertEq(santasList.balanceOf(victim), nftBefore + 1);
}

Recommended Mitigation

Apply the same time gate to buyPresent that collectPresent already has.

function buyPresent(address presentReceiver) external {
+ if (block.timestamp < CHRISTMAS_2023_BLOCK_TIME) {
+ revert SantasList__NotChristmasYet();
+ }
i_santaToken.burn(presentReceiver);
_mintAndIncrement();
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 9 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!