Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: medium
Likelihood: medium
Invalid

### [M-3] Excessive Gas Consumption Issue or Potential Denial-Of-Service in ```Snowman::mintSnowman``` Function.

[M-3] Excessive Gas Consumption Issue or Potential Denial-Of-Service in Snowman::mintSnowman Function.

Description

The Snowman::mintSnowman Function Causes Excessive Gas Consumption or Potential Denial-Of-Service Attack.
If User buys snow tokens in very large amount then,the contract will attempt to loop till amount
and mint that many NFTs.

Impact:

1.Exceed the block gas limit: The transaction will fail, and no NFTs will be minted.

2.Waste gas fees: The user loses gas fees for attempting the transaction.

Proof of Concept

​
1.User Alice Buys snow 1000 tokens and try to claim airdrop.
​
2.The contract attempts to loop 1000 times and mint NFTs for Alice.
​
3.The gas required exceeds the block gas limit, and the transaction fails.
​
4.Alice loses gas fees for initiating the transaction.
​

Recommended Mitigation

1.Limit The Amount Parameter ,user cannot mint that much tokens in single transaction.

2.Enable Batch Processing.

​
function claimSnowman(
address receiver,
bytes32[] calldata merkleProof,
uint8 v,
bytes32 r,
bytes32 s
) external nonReentrant {
if (receiver == address(0)) {
revert SA__ZeroAddress();
}
​
uint256 amount = i_snow.balanceOf(receiver);
if (amount == 0) {
revert SA__ZeroAmount();
}
​
if (s_hasClaimedSnowman[receiver]) {
revert SA__AlreadyClaimed();
}
​
if (!_isValidSignature(receiver, getMessageHash(receiver), v, r, s)) {
revert SA__InvalidSignature();
}
​
bytes32 leaf = keccak256(
bytes.concat(keccak256(abi.encode(receiver, amount)))
);
​
if (!MerkleProof.verify(merkleProof, i_merkleRoot, leaf)) {
revert SA__InvalidProof();
}
​
// Prevent excessive claims (arbitrary max set to 100 per claim)
​
+uint256 maxMintBatch = 100;
+if (amount > maxMintBatch) {
+revert SA__ExcessiveClaim();
+}
​
// Transfer Snow tokens from receiver to contract
i_snow.safeTransferFrom(receiver, address(this), amount);
​
// Mark Snowman claim as completed
s_hasClaimedSnowman[receiver] = true;
​
// Emit event before minting Snowman NFT
emit SnowmanClaimedSuccessfully(receiver, amount);
​
// Mint Snowman NFT(s) in batch
i_snowman.mintSnowman(receiver, amount);
}
​
Updates

Lead Judging Commences

yeahchibyke Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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

Give us feedback!