Beginner FriendlyDeFiFoundry
100 EXP
View results
Submission Details
Severity: high
Valid

Claim function can be called multiple times

Summary

The claim function is not updating any state. Thus, any subsequent claim will hold the same result as the first. If the user was allowed to claim the first time, he will still be allowed to claim later.

Vulnerability Details

The only checks performed by the claim function are the msg.value received and that the user is allowed to claim using the provided merkle tree proof.
There is no check to know if the user already claimed.

function claim(address account, uint256 amount, bytes32[] calldata merkleProof) external payable {
@> if (msg.value != FEE) {
revert MerkleAirdrop__InvalidFeeAmount();
}
bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(account, amount))));
@> if (!MerkleProof.verify(merkleProof, i_merkleRoot, leaf)) {
revert MerkleAirdrop__InvalidProof();
}
emit Claimed(account, amount);
@> i_airdropToken.safeTransfer(account, amount);
}

Impact

A malicious user could claim multiple times its allocation of the airdrop, until the contract is depleted or until it becomes uneconomical to claim (if the claimed value is less than the paid fee).

Tools Used

Manual review

Recommendations

Add a mapping of users that already claimed the airdrop and check that they are not present in the mapping before transferring the tokens.

uint256 private constant FEE = 1e9;
IERC20 private immutable i_airdropToken;
bytes32 private immutable i_merkleRoot;
+ mapping(address => bool) private userClaimed;
function claim(address account, uint256 amount, bytes32[] calldata merkleProof) external payable {
if (msg.value != FEE) {
revert MerkleAirdrop__InvalidFeeAmount();
}
+ if(userClaimed[account]) revert;
bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(account, amount))));
if (!MerkleProof.verify(merkleProof, i_merkleRoot, leaf)) {
revert MerkleAirdrop__InvalidProof();
}
+ userClaimed[account] = true;
emit Claimed(account, amount);
i_airdropToken.safeTransfer(account, amount);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

multi-claim-airdrop

Support

FAQs

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