Snowman Merkle Airdrop

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

Inconsistent Variable Naming and Lint Violations Reduce Code Readability

Root + Impact

Description

While these issues do not directly affect protocol security, inconsistent naming makes the codebase harder to audit, reason about, and maintain. This increases the likelihood of future developer mistakes and overlooked bugs.

// Root cause in the codebase with @> marks to highlight the relevant sectionnote[mixed-case-variable]: mutable variables should use mixedCase
--> src/Snow.sol:29:21
|
29 | address private s_collector;
| ^^^^^^^^^^^ help: consider using: `sCollector`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[mixed-case-variable]: mutable variables should use mixedCase
--> test/TestSnowmanAirdrop.t.sol:19:20
|
19 | bytes32 public ROOT = 0xc0b6787abae0a5066bc2d09eaec944c58119dc18be796e93de5b2bf9f80ea79a;
| ^^^^ help: consider using: `root`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[mixed-case-variable]: mutable variables should use mixedCase
--> src/SnowmanAirdrop.sol:42:23
|
42 | address[] private s_claimers; // array to store addresses of claimers
| ^^^^^^^^^^ help: consider using: `sClaimers`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[screaming-snake-case-immutable]: immutables should use SCREAMING_SNAKE_CASE
--> src/SnowmanAirdrop.sol:43:31
|
43 | bytes32 private immutable i_merkleRoot; // Merkle root used to validate airdrop claims
| ^^^^^^^^^^^^ help: consider using: `I_MERKLE_ROOT`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#screaming-snake-case-immutable
note[screaming-snake-case-immutable]: immutables should use SCREAMING_SNAKE_CASE
--> src/SnowmanAirdrop.sol:44:28
|
44 | Snow private immutable i_snow; // Snow token to be staked for the airdrop
| ^^^^^^ help: consider using: `I_SNOW`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#screaming-snake-case-immutable
note[screaming-snake-case-immutable]: immutables should use SCREAMING_SNAKE_CASE
--> src/SnowmanAirdrop.sol:45:31
|
45 | Snowman private immutable i_snowman; // Snowman nft to be claimed
| ^^^^^^^^^ help: consider using: `I_SNOWMAN`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#screaming-snake-case-immutable
note[mixed-case-variable]: mutable variables should use mixedCase
--> src/SnowmanAirdrop.sol:47:38
|
47 | mapping(address => bool) private s_hasClaimedSnowman; // mapping to verify if an address has claimed Snowman
| ^^^^^^^^^^^^^^^^^^^ help: consider using: `sHasClaimedSnowman`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[unsafe-cheatcode]: usage of unsafe cheatcodes that can perform dangerous operations
--> script/DeploySnowman.s.sol:10:39
|
10 | string memory snowmanSvg = vm.readFile("./img/snowman.svg");
| ^^^^^^^^
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#unsafe-cheatcode
note[mixed-case-variable]: mutable variables should use mixedCase
--> test/TestSnow.t.sol:15:13
|
15 | uint256 FEE;
| ^^^ help: consider using: `fee`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[mixed-case-variable]: mutable variables should use mixedCase
--> src/Snow.sol:30:21
|
30 | uint256 private s_earnTimer;
| ^^^^^^^^^^^ help: consider using: `sEarnTimer`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[mixed-case-variable]: mutable variables should use mixedCase
--> src/Snow.sol:31:20
|
31 | uint256 public s_buyFee;
| ^^^^^^^^ help: consider using: `sBuyFee`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable
note[screaming-snake-case-immutable]: immutables should use SCREAMING_SNAKE_CASE
--> src/Snow.sol:32:31
|
32 | uint256 private immutable i_farmingOver;
| ^^^^^^^^^^^^^ help: consider using: `I_FARMING_OVER`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#screaming-snake-case-immutable
note[mixed-case-variable]: mutable variables should use mixedCase
--> src/Snow.sol:34:12
|
34 | IERC20 i_weth;
| ^^^^^^ help: consider using: `iWeth`
|
= help: https://book.getfoundry.sh/reference/forge/forge-lint#mixed-case-variable

Risk

Likelihood:

  • Reason 1
    This occurs during normal development and auditing workflows whenever developers or auditors run forge lint or review the codebase, as the variable naming conventions are consistently violated across multiple contracts.

  • Reason 2
    The issue is present in deployed source code and test files, meaning it will repeatedly surface during maintenance, refactoring, onboarding of new contributors, or CI checks.

Impact:

  • Impact 1
    Reduced readability and consistency across the codebase makes auditing more difficult and increases the chance of human error during future development or security reviews.

  • Impact 2
    Failure to follow established Solidity and Foundry conventions can lead to overlooked logic issues, weaker code quality standards, and difficulty enforcing automated linting or CI rules.

Proof of Concept

The issue can be consistently reproduced by running Foundry’s linting tool against the repository. Foundry flags multiple variable naming violations and unsafe cheatcode usage, demonstrating that the codebase does not conform to recommended Solidity conventions.

// Example from Snow.sol
address private s_collector; // mutable variable using snake_case
// Example from SnowmanAirdrop.sol
bytes32 private immutable i_merkleRoot; // immutable variable not using SCREAMING_SNAKE_CASE

Recommended Mitigation

To resolve these issues and improve overall code quality, variable names should be updated to follow Solidity and Foundry naming conventions. Mutable state variables should use mixedCase, while immutable variables should use SCREAMING_SNAKE_CASE.

forge lint
- remove this code
address private s_collector;
bytes32 private immutable i_merkleRoot;
+ add this code
address private sCollector;
bytes32 private immutable I_MERKLE_ROOT;
Updates

Lead Judging Commences

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