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

Incorrect Merkle root due to incorrect decimals at the tree's creation

Description

In Deploy.s.sol, the Airdrop is created using the Merkle root from makeMerkle.js. The issue arises because the tree is created with 18 decimals in the JavaScript file, while all Solidity contracts assume amounts have 6 decimals. Given that only 100(e6) USDC are sent to the Airdrop contract, no user can retrieve a number with 18 decimals due to insufficient funds. This prevents users from claiming rewards because the Merkle proof won't pass with a 6-decimal number.

Moreover, the correct root is used in the test file.

`Deploy.s.sol`
contract Deploy is Script {
address public s_zkSyncUSDC = 0x1D17CbCf0D6d143135be902365d2e5E2a16538d4;
bytes32 public s_merkleRoot =
0
xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;
// 4 users, 25 USDC each
uint256 public s_amountToAirdrop = 4 * (25 * 1e6);
// Deploy the airdropper
function run() public {
vm.startBroadcast();
MerkleAirdrop airdrop = deployMerkleDropper(s_merkleRoot, IERC20(s_zkSyncUSDC));
// Send USDC -> Merkle Air Dropper
IERC20(0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4).transfer(address(airdrop), s_amountToAirdrop);
vm.stopBroadcast();
}
function deployMerkleDropper(bytes32 merkleRoot, IERC20 zkSyncUSDC) public returns (MerkleAirdrop) {
return (new MerkleAirdrop(merkleRoot, zkSyncUSDC));
}
}
`makeMerkle.js`
const amount = (25 * 1e18).toString();
const userToGetProofOf = "0x20F41376c713072937eb02Be70ee1eD0D639966C";
// (1)
const values = [
[userToGetProofOf, amount],
["0x277D26a45Add5775F21256159F089769892CEa5B", amount],
["0x0c8Ca207e27a1a8224D1b602bf856479b03319e7", amount],
["0xf6dBa02C01AF48Cf926579F77C9f874Ca640D91D", amount],
];
/*//////////////////////////////////////////////////////////////
PROCESS
//////////////////////////////////////////////////////////////*/
// (2)
const tree = StandardMerkleTree.of(values, ["address", "uint256"]);

The following file shows the generated root, which is the same as the one used in the deployment script.

`tree.json`

{"format":"standard-v1","tree":["0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05",...

Risk

Likelihood: High

  • The contract will never send USDC to users unless the user deposits 100e12 USDC into it.

Impact:

  • Loss of funds, which become stuck in the Airdrop contract.

Recommended Mitigation

Recreate a valid root with 6 decimals (like USDC) and replace the one in the deployment script.
For reference, the calculated Merkle root on my end is 0x3b2e22da63ae414086bec9c9da6b685f790c6fab200c7918f2879f08793d77bd, which matches the one in the test file.

Updates

Lead Judging Commences

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

wrong-usdc-decimals-in-merkle

Support

FAQs

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