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

Incorrect Merkle Root Used during Deployment Makes It Impossible to Claim an Airdrop Allocation and Permanently Locks Tokens in the Contract

Summary

The deployment script, Deploy.s.sol, deploys the MerkleAirdrop contract with an incorrectly calculated merkle root. This makes it impossible for an airdrop allocation to be claimed, either by providing an incorrect proof or by providing a valid proof (and amount) that is calculated using 18 decimals, but results in the contract attempting to transfer a much larger number of tokens than is present in the contract. In addition, since there is no functionality to manually send USDC tokens out of the contract, the tokens are permanently stuck. To mitigate this, replace Deploy::s_merkleRoot with a properly calculated root. This can be done using the existing makeMerkle.js script.

Vulnerability Details

The deployment script, Deploy.s.sol, deploys the MerkleAirdrop contract with an incorrectly calculated merkle root. The root present in the deploy script is calculated based on a token having 18 decimals (the ERC20 default), when the airdropped token in this case (USDC) uses 6 decimals. MerkleAirdropTest.t.sol uses the correct root and proofs, making the test case (MerkleAirdropTest::testUsersCanClaim) pass.

Deploy.s.sol

contract Deploy is Script {
...
bytes32 public s_merkleRoot = 0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;

MerkleAirdropTest.t.sol

contract MerkleAirdropTest is Test {
...
bytes32 public merkleRoot = 0x3b2e22da63ae414086bec9c9da6b685f790c6fab200c7918f2879f08793d77bd;

Impact

This makes it impossible for an airdrop allocation to be claimed, either by providing an incorrect proof (calculated using 6 decimals compared to the root's 18 decimals) or by providing a valid proof (and amount) that is calculated using 18 decimals, but results in the contract attempting to transfer a much larger number of tokens than is present in the contract. In addition, since there is no functionality to manually send USDC tokens out of the contract, the tokens are permanently stuck.

Tools Used

Manual Analysis

Recommendations

Replace Deploy::s_merkleRoot with a properly calculated root. This can be done using the existing makeMerkle.js script.

- const amount = (25 * 1e18).toString()
+ const amount = (25 * 1e6).toString()
Updates

Lead Judging Commences

inallhonesty Lead Judge over 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.