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 3 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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