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

Incorrect handling of decimals.

[H-2] In the script use the incorrect amount of 25000000000000000000 and this is equivalent to 25_000_000_000_000 USDC, therefore, nobody could successfully claim, leaving the money blocked in the contract.

Description: The script is configured with 18 decimals in the amount, which will create an incorrect proof to use in the MerkleAirdrop::claim()

Impact: Due to the incorrect proof, no user would be able to claim the airdrop. This locks the money in the contract since there is no way to update the Merkle Root. At the same time, if a user knows, they could try to send the amount in 18 decimals (25_000_000_000_000), but if the contract doesn't have enough funds, the claim would fail.

Proof of Concept:

  1. Receive a proof created with the script makeMerkle.js

  2. The user uses the MerkleAirdrop::claim() function to redeem their airdrop with the received proof.

  3. The claim is reverted because the amounts are different, making the proof invalid.

Code

This test was added in MerkleAirdrop.t.test

function testFailProofOfTheScript() public {
bytes32 merkleRoot2 =0xf69aaa25bd4dd10deb2ccd8235266f7cc815f6e9d539e9f4d47cae16e0c36a05;
bytes32 proof1 = 0x4fd31fee0e75780cd67704fbc43caee70fddcaa43631e2e1bc9fb233fada2394;
bytes32 proof2 = 0xc88d18957ad6849229355580c1bde5de3ae3b78024db2e6c2a9ad674f7b59f84;
bytes32[] memory badProof = new bytes32[](2);
badProof[0] = proof1;
badProof[1] = proof2;
MerkleAirdrop airdrop2 = new MerkleAirdrop(merkleRoot2, token);
vm.deal(collectorOne, airdrop.getFee());
vm.startPrank(collectorOne);
airdrop2.claim{ value: airdrop.getFee() }(collectorOne, amountToCollect, badProof);
}

Recommended Mitigation: They need to correct the script to generate proofs with the correct amount, and also create the mock token with 6 decimals to accurately simulate the USDC on the mainnet and thus realize the error.

In makeMerkle.js

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

In AirdropToken.sol

+ function decimals() public view virtual override returns (uint8) {
+ return 6;
+ }
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.