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

Inconsistent USDC Token address and Ownership issue in `Deploy` script.

Summary

The USDC token address 0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4 hardcoded in Deploy::run() to transfer tokens differs from the s_zkSyncUSDC address. While s_zkSyncUSDC is passed down as airdropToken when deploying MerkleAirdrop contract, the hardcoded address is used to transfer tokens to the airdrop. This directly affects MerkleAirdrop::claim which transfer tokens to eligible addresses, thereby directly disrupting the functionality of the protocol if s_zkSyncUSDC address is not the correct token address of USDC token.

@> address public s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
function run() public {
vm.startBroadcast();
@> MerkleAirdrop airdrop = deployMerkleDropper(s_merkleRoot, IERC20(s_zkSyncUSDC));
@> IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
vm.stopBroadcast();
}

Additionally, for transfering s_amountToAirdrop USDC to MerkleAirdrop, the account executing the transaction needs to have sufficient balance of USDC tokens on Mainnet/Testnet, depending on the network. The way deploy script is set up, the owner is the Deploy contract which does not possess any USDC tokens, so the transfer function would revert and deployment would fail.

Impact

The inconsistency in the USDC token address and the ownership issue significantly disrupts the functionality of the MerkleAirdrop protocol. Users may experience transaction fails, resulting in a loss of trust and confidence in the protocol. The deployment failures hinder the successful initialization of the contract, delaying or preventing the airdrop distribution process altogether.

Tools Used

Manual Review

Proof of Concept

The address assigned to s_zkSyncUSDC is not equal to the one used for transfer of token,

function testInconsistentUSDCTokenAddressInDeploy() public pure {
address s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
// IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
address transferAddress = 0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4;
assertTrue(s_zkSyncUSDC != transferAddress);
}

Run make deploy script of the Makefile. The script would revert with error routing to the transfer token function,

@> IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);

Recommendations

Consider using transferFrom to transfer USDC from another account (with USDC possession) to the airdrop, or ensure the caller of the run() function has enough USDC to transfer. Use s_zkSyncUSDC for the IERC20 transfer instead of hardcoded address, and ensure that the USDC token address is correct.

- address zksyncusdc = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
// The correct zksyncUSDC mainnet address
+ address zksyncusdc = 0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4;
function run() public {
- vm.startBroadcast();
// Start broadcast with an account with ownership of USDC
+ vm.startBroadcast(ACCOUNT_A);
MerkleAirdrop airdrop = deployMerkleDropper(s_merkleRoot, IERC20(s_zkSyncUSDC));
- IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
+ IERC20(zksyncusdc).approve(address(airdrop), s_amountToAirdrop);
+ IERC20(zksyncusdc).transfer(address(airdrop), s_amountToAirdrop);
vm.stopBroadcast();
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

usdc-wrong-address

Support

FAQs

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