Snowman Merkle Airdrop

AI First Flight #10
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

[L-02] Declared events are not emitted in state-changing functions

Root + Impact

Description

  • Describe the normal behavior in one or more sentences

  • The contract defines several events intended to signal important state changes:

    event SnowBought(address indexed buyer, uint256 indexed amount);
    event SnowEarned(address indexed earner, uint256 indexed amount);
    event FeeCollected();
    event NewCollector(address indexed newCollector);

    However, the corresponding state-changing functions do not emit these events when the associated actions occur

  • Especifically earnSnow() does not emit SnowEarned after minting tokens to the caller.

  • collectFee() does not emit FeeCollected after transferring collected fees to the designated collector.

// Root cause in the codebase with @> marks to highlight the relevant section
function earnSnow() external canFarmSnow {
if (s_earnTimer != 0 && block.timestamp < (s_earnTimer + 1 weeks)) {
revert S__Timer();
}
_mint(msg.sender, 1);
s_earnTimer = block.timestamp;
@> missing emit here
}
function collectFee() external onlyCollector {
uint256 collection = i_weth.balanceOf(address(this));
i_weth.transfer(s_collector, collection);
(bool collected,) = payable(s_collector).call{value: address(this).balance}("");
require(collected, "Fee collection failed!!!");
@> missing emit here
}

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • The absence of event emissions does not affect on-chain execution or protocol security. However, it reduces off-chain observability and may negatively impact:

    Frontend applications that rely on events to update UI state

    Indexing services and analytics platforms

    Monitoring and accounting systems that track protocol activity

  • Without emitting the declared events, off-chain consumers cannot reliably detect when rewards are earned or when fees are collected.

Proof of Concept

Recommended Mitigation

Emit the appropriate events at the end of each state-changing function. For example:

earnSnow function
+ emit SnowEarned(msg.sender, amount);
CollectFee function
+ emit FeeCollected();
Updates

Lead Judging Commences

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