Skip to content

Commit 915e7fb

Browse files
committed
[SDK] FIx merkle tree proof for Drop contracts (#4344)
internal discussion: https://thirdwebdev.slack.com/archives/C04DP04AF1V/p1725028836481129 <!-- start pr-codex --> --- ## PR-Codex overview **Focus:** This PR focuses on fixing the Merkle tree proof for Drop contracts in the `thirdweb` package. ### Detailed summary - Fixed sorting of leaves in `MerkleTree.ts`. - Renamed `ADDRESS_ZERO` to `ZERO_ADDRESS`. - Updated logic for fetching proofs in `fetchProofsForClaimer`. - Added a test for large Merkle trees in `MerkleTree.test.ts`. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent c54822f commit 915e7fb

File tree

4 files changed

+40
-5
lines changed

4 files changed

+40
-5
lines changed

.changeset/hip-apples-beg.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
Fix merkletree proof for Drop contracts

packages/thirdweb/src/merkletree/MerkleTree.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { describe, expect, it } from "vitest";
2+
import type { Hex } from "../utils/encoding/hex.js";
23
import { stringToBytes } from "../utils/encoding/to-bytes.js";
34
import { MerkleTree } from "./MerkleTree.js";
45

@@ -14,6 +15,35 @@ describe("MerkleTree", () => {
1415
`"0xebd2ffa91ce49e68a5ae1283e5babdf2655f8ea9ea0ee36ed525cc41d171a882"`,
1516
);
1617
});
18+
19+
it("should return root for large merkle trees", () => {
20+
const leaves: Hex[] = [
21+
"0xe1b12834247548c6bf6a9d37d2090a5f41beda62be633f705bc7c6e924342b4d",
22+
"0x232570d6677f4e4b8947d8369750a4da492511d19e104db19dfae1200c3ff4db",
23+
"0xe30d909533984527552083c16f23927cb9928c2e01b7252989f1c4fb9714deca",
24+
"0xd13d5d1bf095147532482f25aac6d72905850864aab58f9dac28beb655dc4726",
25+
"0xa0eea66d581045e22cbeccd59027e62b5d753fd3118f068b444bceec601be03f",
26+
"0x222cd80957bf16ed8ce63a492a5035830cc2bfe04e2d46cc28e3aacb5db1277a",
27+
"0xb1525c3a1a9d0fa632857acd0216609a80c19293fc3273f4cac664ca49a9e323",
28+
"0x18b19c2a11bd54e98cc841bc8863d3e8582da3dd21903aedfe6745d41083653b",
29+
"0xc198129437401b73388fa41dfaa82457015716050c6632364a1db94db1f0fb19",
30+
"0x7621bd1c73bb5d8487459d8be36c5445a65a7fda457972d7f9de22a826739281",
31+
"0x1cc9ca923d763f8de998921de43da79d6415eaff9b875e3e619c246fc26160b7",
32+
"0xb4526c4f954e3230701cb7a392081007c050e950d886a25bac5fb14e3639e258",
33+
"0x7d00f9a67344ed46afab13a398ea4bbf40915283f08f5caaf7d128a836361943",
34+
"0xb11d4116f885aa50e9e9cbddf61b4d582413cd959302c68bfc0430fe8d5f609b",
35+
"0xd474bee9ba879f0e0ae0827601642460e5439b4c3acb69da07b77ae2779a4eb2",
36+
"0xb2b902dfab66d5dbee090467f02abd14c49e11f92a7d58fda53982f006f4360c",
37+
"0x7ed8ec6456a2418c91d362f5ef5b4865d68a1df05722fe0fa9ecf23e0fc7e935",
38+
"0xb1efbe628e4a0062c6f241f2ccd3663269fafb4305d2cbe33c6f94d0aea8e195",
39+
];
40+
const merkleTree = new MerkleTree(leaves);
41+
const hexProof = merkleTree.getHexRoot();
42+
43+
expect(hexProof).toBe(
44+
"0x58053466a63f980211c457688c927035d61a7717b7744afe3758138ce66a6fda",
45+
);
46+
});
1747
});
1848

1949
describe("getHexProof", () => {

packages/thirdweb/src/merkletree/MerkleTree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class MerkleTree {
2626
el instanceof Uint8Array ? el : hexToBytes(el),
2727
);
2828

29-
this.leaves = this.leaves.sort();
29+
this.leaves = this.leaves.sort(compareUint8Arrays);
3030

3131
this.createHashes(this.leaves);
3232
}

packages/thirdweb/src/utils/extensions/drops/fetch-proofs-for-claimers.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {
2-
ADDRESS_ZERO,
2+
ZERO_ADDRESS,
33
isNativeTokenAddress,
44
} from "../../../constants/addresses.js";
55
import type { ThirdwebContract } from "../../../contract/contract.js";
@@ -69,8 +69,8 @@ export async function fetchProofsForClaimer(options: {
6969
});
7070
}),
7171
);
72-
const tree = new MerkleTree(hashedEntries);
7372
// 5. get the proof for the claimer + the sub merkle tree root
73+
const tree = new MerkleTree(hashedEntries);
7474
const entry = shardData.entries.find(
7575
(i) => i.address.toLowerCase() === claimer.toLowerCase(),
7676
);
@@ -88,11 +88,11 @@ export async function fetchProofsForClaimer(options: {
8888
)
8989
.concat(shardData.proofs);
9090
// 6. return the proof and the entry data for the contract call
91-
const currencyAddress = (entry.currencyAddress || ADDRESS_ZERO) as Address;
91+
const currencyAddress = (entry.currencyAddress || ZERO_ADDRESS) as Address;
9292
const currencyDecimals = await (async () => {
9393
if (
9494
isNativeTokenAddress(currencyAddress) ||
95-
currencyAddress === ADDRESS_ZERO
95+
currencyAddress === ZERO_ADDRESS
9696
) {
9797
return 18;
9898
}

0 commit comments

Comments
 (0)