Params logic error in Claim()
Description
@> 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
Likelihood: High
It occurs every time msg.sender pass other address as account
Impact: Medium
It leads to loss of control beacause the real owner of this funds doesnt have control over his funds.
Proof of Concept
In this case user just call claim function with collectorOne as a account parameter and as we can see he claim funds even if it wasnt his.
function testProofOfCodeLossOfControl() public {
address user = makeAddr("user");
vm.deal(user, airdrop.getFee());
vm.startPrank(user);
airdrop.claim{ value: airdrop.getFee() }(collectorOne, amountToCollect, proof);
vm.stopPrank();
console.log(token.balanceOf(collectorOne));
}
Ran 1 test for test/MerkleAirdropTest.t.sol:MerkleAirdropTest
[PASS] testProofOfCodeLossOfControl() (gas: 76647)
Logs:
25000000
Recommended Mitigation
Check if account == msg.sender otherwise revert
- remove this code
+ add this code
function claim(address account, uint256 amount, bytes32[] calldata merkleProof) external payable {
if (msg.value != FEE) {
revert MerkleAirdrop__InvalidFeeAmount();
+ if(account != msg.sender){
+ revert()
+}
} //audit-high, could claim many times, no checks, leads to drain all other eligable users funds
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); //audit-low, account could be a different then msg.sender
}