Santa's List

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

[M-1] Santa can accidentally overwrite first check after second check, blocking rewards

Root + Impact

Description

  • The protocol allows Santa to call checkList even after checkTwice has already been completed. This creates a state regression vulnerability where a finalized decision can be accidentally overwritten with a weaker classification. In the provided POC, Santa correctly assigns EXTRA_NICE twice, but a subsequent mistaken call to checkList downgrades the user to NICE, making them ineligible for rewards.


  • This issue is not malicious but operationally dangerous. It assumes perfect operational discipline from Santa and provides no guardrails to prevent human error. Once the overwrite occurs, the user permanently loses access to their reward, despite having been validly approved earlier. There is no recovery mechanism.


  • From a protocol perspective, finalized states should be immutable or at least protected against regression. The absence of state validation violates this principle and introduces unnecessary trust risk.

function checkList(address person, Status status) external {
@> //theres no check here
s_theListCheckedOnce[person] = status;
emit CheckedOnce(person, status);
}

Risk

Likelihood:

  • Medium. Requires operator error but is plausible in real usage.

Impact:

  • High. Legitimate users can permanently lose rewards due to admin mistakes.

Proof of Concept

Please add this POC on the test file

function testSantaMistakenCheckFirst() public {
vm.startPrank(santa);
santasList.checkList(user, SantasList.Status.EXTRA_NICE);
santasList.checkTwice(user, SantasList.Status.EXTRA_NICE);
// second time doing the first check mistakenly
santasList.checkList(user, SantasList.Status.NICE);
vm.stopPrank();
vm.warp(santasList.CHRISTMAS_2023_BLOCK_TIME() +1 );
vm.startPrank(user);
// user cannot claim their present because santas fault
vm.expectRevert(SantasList.SantasList__NotNice.selector);
santasList.collectPresent();
vm.stopPrank();
}

Recommended Mitigation

Consider add the require / if statement to validate the second choice already entered

function checkList(address person, Status status) external {
+ require(secondChecked != 0 or whatever it is);
s_theListCheckedOnce[person] = status;
emit CheckedOnce(person, status);
}
Updates

Lead Judging Commences

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