AirDropper

AI First Flight #5
Beginner FriendlyDeFiFoundry
EXP
View results
Submission Details
Severity: high
Valid

L1 smart-contract wallet addresses in the Merkle tree do not map to the same owners on zkSync

Executive summary

Eligibility is derived from Ethereum L1 addresses but distribution occurs on zkSync Era. Contract-wallet addresses are chain-specific and are not guaranteed to represent the same wallet on L2. At least one selected recipient is a smart-contract wallet, so its leaf can point to an address that the intended owner cannot control on zkSync.

Root cause and evidence

The README states the four addresses were selected from Ethereum L1 activity. The hardcoded root in Deploy.s.sol commits those L1 addresses without resolving their zkSync counterparts. Unlike EOAs, contract addresses depend on deployment mechanics and can differ across chains.

Impact

The affected winner cannot control the address bound into the Merkle leaf on zkSync and cannot receive/use the allocation as intended. Because the contract has no recovery path for unclaimed tokens or root update, the corresponding USDC remains permanently stuck.

Proof of concept

Take the selected L1 smart-wallet address and inspect the same address on zkSync. It is not the intended deployed wallet/owner. The proof is valid only for that exact L1 address; substituting the actual L2 wallet changes the leaf and fails verification.

Recommended mitigation

Collect and verify recipient addresses on the target zkSync chain before generating the tree. For contract wallets, use the explicitly deployed L2 address or a signed claim flow that lets the proven L1 owner nominate a target L2 account. Add a recovery/update mechanism before funding.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 2 hours ago
Submission Judgement Published
Validated
Assigned finding tags:

[H-04] Unable to receive airdrop due to account abstraction

## Description The users that use account abstraction wallets have different addresses across chains for the same account. ## Vulnerability Details In the docs is said: ```javascript "Our team is looking to airdrop 100 USDC tokens on the zkSync era chain to 4 lucky addresses based on their activity on the Ethereum L1. The Ethereum addresses are: 0x20F41376c713072937eb02Be70ee1eD0D639966C 0x277D26a45Add5775F21256159F089769892CEa5B 0x0c8Ca207e27a1a8224D1b602bf856479b03319e7 0xf6dBa02C01AF48Cf926579F77C9f874Ca640D91D" ``` The user can claim his/her USDC tokens through the `MerkleAirdrop::claim` function. This function requires `account, amount and proof array`. With the help of this three arguments the merkle proof will ensure that the caller is eligible to claim. But in the generated merkle root are used the Ethereum addresses of the lucky users. But the protocol will be deployed on the zkSync era chain. If any of them uses account abstraction wallet, this lucky user will not be able to claim his/her tokens. The account abstraction wallets have different addresses in the different chains for the same account. ## Impact The users that use account abstraction wallets have different addresses on the zkSync era chain. That means these users will not be able to claim their USDC tokens, because the merkle root will require another account address (this on Ethereum). ## Recommendations Ensure that the addresses in `makeMerkle` file for the lucky users are their addresses for the zkSync era chain.

Support

FAQs

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

Give us feedback!