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

Missing check for already claimed proof cause replay attack

Summary

The MerkleAirdrop::claim function lacks a check to prevent replay attacks. This vulnerability allows an airdrop receiver to claim multiple times, potentially draining the contract.

Impact

This issue enables a single receiver to steal all the funds allocated for the airdrop.

Proof of Concept:

To demonstrate the vulnerability, add the following code to the existing MerkleAirdropTest contract:

Proof Of Code
function testUsersCanClaimOneTime() public {
uint256 fee = airdrop.getFee();
vm.deal(collectorOne, fee * 2);
vm.startPrank(collectorOne);
airdrop.claim{ value: fee }(collectorOne, amountToCollect, proof);
vm.expectRevert();
airdrop.claim{ value: fee }(collectorOne, amountToCollect, proof);
vm.stopPrank();
}

Tools Used

foundry

Recommendations

In MerkleAirdrop, implement a mapping to track addresses that have already claimed the airdrop to prevent replay attacks.

contract MerkleAirdrop is Ownable {
...
error MerkleAirdrop__TransferFailed();
+ error MerkleAirdrop__AlreadyClaimed();
uint256 private constant FEE = 1e9;
IERC20 private immutable i_airdropToken;
bytes32 private immutable i_merkleRoot;
+ mapping(address => bool) s_alreadyClaimed;
event Claimed(address account, uint256 amount);
...
function claim(address account, uint256 amount, bytes32[] calldata merkleProof) external payable {
+ if (s_alreadyClaimed[account]) {
+ revert MerkleAirdrop__AlreadyClaimed();
+ }
+ s_alreadyClaimed[account] = true;
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);
}
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.