The deployment script is designed to deploy the MerkleAirdrop contract and transfer the correct USDC token amount to it, using a consistent reference to the zkSync USDC token address throughout the deployment process.
The deployment script uses two different case variations of the same zkSync USDC address - one stored in the state variable s_zkSyncUSDC and another hardcoded in the run() function with different character casing, creating inconsistency that could lead to deployment errors or transferring tokens to an unintended address.
Likelihood:
Developers manually typing addresses during deployment or modifications will introduce case inconsistencies
EIP-55 checksum validation tools and some blockchain explorers strictly validate address checksums and may reject incorrectly cased addresses
The deployment script executes automatically without manual verification of address consistency during the broadcast phase
Copy-paste errors when updating addresses from different sources (blockchain explorers, documentation) preserve inconsistent casing
Impact:
Deployment fails when strict EIP-55 validation is enabled in the development environment or deployment tooling
Potential transfer of tokens to a different address if the case difference represents a different checksum-valid address (extremely unlikely but theoretically possible)
Code maintainability issues where future developers cannot easily verify the addresses match without converting them to checksummed format
Confusion during audits and code reviews when comparing addresses across the codebase
Use a single constant with the correct EIP-55 checksummed address throughout the deployment script:
Additional recommendation: Verify checksum during deployment
## Description The `s_zkSyncUSDC` address in `Deploy.s.sol` is incorrectly set, leading to a failure in the claiming process. This error results in funds being stuck in the `MerkleAirdrop` contract due to the immutability of the token address. ## Impact All funds become permanently trapped in the `MerkleAirdrop` contract, rendering them inaccessible for claiming or transfer. **Proof of Concept:** To demonstrate the issue, a test contract can be added and executed using the following command: `forge test --zksync --rpc-url $RPC_ZKSYNC --mt testDeployOnZkSync` Use the RPC URL `https://mainnet.era.zksync.io` for testing. <details> <summary>Proof Of Code</summary> ```javascript // SPDX-License-Identifier: MIT pragma solidity 0.8.24; import { MerkleAirdrop, IERC20 } from "../src/MerkleAirdrop.sol"; import { Test, console2 } from "forge-std/Test.sol"; contract MerkleAirdropTest is Test { MerkleAirdrop public s_airdrop; uint256 s_amountToCollect = (25 * 1e6); // 25.000000 address s_collectorOne = 0x20F41376c713072937eb02Be70ee1eD0D639966C; bytes32 s_proofOne = 0x32cee63464b09930b5c3f59f955c86694a4c640a03aa57e6f743d8a3ca5c8838; bytes32 s_proofTwo = 0x8ff683185668cbe035a18fccec4080d7a0331bb1bbc532324f40501de5e8ea5c; bytes32[] s_proof = [s_proofOne, s_proofTwo]; address public deployer; // From Deploy.t.sol bytes32 public s_merkleRoot = 0x3b2e22da63ae414086bec9c9da6b685f790c6fab200c7918f2879f08793d77bd; address public s_zkSyncUSDC = 0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4; uint256 public s_amountToAirdrop = 4 * (25 * 1e6); function setUp() public { deployer = makeAddr("deployer"); deal(0x1D17CbCf0D6d143135be902365d2e5E2a16538d4, deployer, 100 * 1e6); vm.deal(s_collectorOne, 100 ether); } function testDeployOnZkSync() public { if (block.chainid != 324) { return; } vm.startPrank(deployer); // From here there is the code from run() s_airdrop = deployMerkleDropper(s_merkleRoot, IERC20(s_zkSyncUSDC)); // Send USDC -> Merkle Air Dropper IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(s_airdrop), s_amountToAirdrop); // end code from run vm.stopPrank(); vm.startPrank(s_collectorOne); s_airdrop.claim{ value: s_airdrop.getFee() }(s_collectorOne, s_amountToCollect, s_proof); vm.stopPrank(); } function deployMerkleDropper(bytes32 merkleRoot, IERC20 zkSyncUSDC) public returns (MerkleAirdrop) { return (new MerkleAirdrop(merkleRoot, zkSyncUSDC)); } } ``` </details> ## Recommendations To resolve the issue, update the s_zkSyncUSDC address in Deploy.s.sol to the correct value: ```diff - address public s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4; + address public s_zkSyncUSDC = 0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4; ```
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.