Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

Use of Dynamic `balanceOf` in Proof Generation makes Claim become Invalid

# Use of Dynamic `balanceOf` in Proof Generation makes Claim become Invalid
## Description
* The contract uses `balanceOf(receiver)` to determine the amount of Snow tokens staked, which is later used in the Merkle proof and EIP712 signature.
* **Problem**: `balanceOf` is **dynamic**, and if the balance changes between proof generation and contract interaction, the proof becomes invalid — **introducing fragility and failure risk**.
```solidity
if (i_snow.balanceOf(receiver) == 0) {
revert SA__ZeroAmount();
}
uint256 amount = i_snow.balanceOf(receiver); // @> dynamic lookup
...
bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(receiver, amount))));
```
## Risk
**Likelihood**:
* Highly likely if users accidentally transfer Snow tokens after proof/signature is generated but before calling `claimSnowman`.
**Impact**:
* Users are unable to claim NFTs despite having valid proof/signatures at generation time.
* Poor user experience and potential loss of eligibility.
## Proof of Concept
The following solidity example proves that balanceOf can cause claim fails.
```solidity
uint256 amount = 1000;
generateProof(receiver, amount);
snow.transfer(receiver, amount);
// user spends tokens before claiming
snow.transfer(other, 1000);
// claim fails due to changed balance
airdrop.claimSnowman(receiver, proof, v, r, s);
```
## Recommended Mitigation
Do not depend on `balanceOf()` inside the contract. Instead, accept `amount` as a parameter signed via EIP712 and encoded into the Merkle tree.
```diff
function claimSnowman(address receiver, uint256 amount, bytes32[] calldata proof, ...) external {
- uint256 amount = i_snow.balanceOf(receiver); // remove this dynamic call
+ // Use amount passed in by the user that matches the signed message and Merkle leaf
}
```
Updates

Lead Judging Commences

yeahchibyke Lead Judge 16 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Invalid merkle-proof as a result of snow balance change before claim action

Claims use snow balance of receiver to compute the merkle leaf, making proofs invalid if the user’s balance changes (e.g., via transfers). Attackers can manipulate balances or frontrun claims to match eligible amounts, disrupting the airdrop.

Support

FAQs

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