# 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
}
```