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

msg.value is not supported on zkSync Era, leading to users not being able to claim their airdrop

Description

Native ETH transfers are not supported on the zkSync Era chain, which means that msg.value is always zero. Instead of using msg.value for transactions, zkSync utilizes a system of fees and gas limits that are abstracted away from the traditional Ethereum model.

Thus, when users try to claim their airdrop amounts, msg.value will be zero, which will cause the transaction to revert with MerkleAirdrop__InvalidFeeAmount().

Impact

Severity: High
Likelihood: High

Eligible users will be unable to claim their airdrop amounts due to msg.value always being set to zero. This defeats the purpose of the protocol. Additionally, the USDC funds transferred to the MerkleAirdrop by the protocol team will be stuck in the contract, since there is no function to withdraw the remaining token balance.

Tools Used

Manual review.

Recommended Mitigation

Collect fees in WETH, an ERC20 token. We'll need to modify both the MerkleAirdrop::claim() and the MerkleAirdrop::claimFees() functions. Here are the changes:

+ IERC20 public immutable i_weth;
...
- constructor(bytes32 merkleRoot, IERC20 airdropToken) Ownable(msg.sender) {
+ constructor(bytes32 merkleRoot, IERC20 airdropToken, IERC20 weth) Ownable(msg.sender) {
i_merkleRoot = merkleRoot;
i_airdropToken = airdropToken;
+ i_weth = weth;
}
function claim(address account, uint256 amount, bytes32[] calldata merkleProof) external payable {
- if (msg.value != FEE) {
- revert MerkleAirdrop__InvalidFeeAmount();
- }
+ i_weth.safeTransferFrom(account, address(this), FEE);
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);
}
function claimFees() external onlyOwner {
- (bool succ,) = payable(owner()).call{ value: address(this).balance }("");
- if (!succ) {
- revert MerkleAirdrop__TransferFailed();
- }
+ i_weth.safeTransfer(owner(), i_weth.balanceOf(address(this)));
}
Updates

Lead Judging Commences

inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
mgnfy_view Submitter
over 1 year ago
inallhonesty Lead Judge
over 1 year ago
inallhonesty Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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