Skip to content

Commit

Permalink
Marketplace implementation addresses (#5822)
Browse files Browse the repository at this point in the history
TOOL-2814

## Problem solved

Short description of the bug fixed or feature added

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces support for `ZkSync` chains by adding implementations for contracts and adjusting methods to handle `ZkSync` specific logic, including fetching default constructor parameters and deploying contracts.

### Detailed summary
- Added `ZKSYNC_IMPLEMENTATIONS` and `ZKSYNC_WETH` records for various `ZkSync` chains.
- Updated `CustomContractForm` to handle `MarketplaceV3` differently for `ZkSync` chains.
- Introduced a test for retrieving default constructor parameters for `ZkSync`.
- Modified `getAllDefaultConstructorParamsForImplementation` to return `nativeTokenWrapper` for `ZkSync`.
- Updated contract deployment logic in `bootstrap.ts` to use `ZkSync` implementations.
- Added a test case for saving implementations for `ZkSync` chains.
- Enhanced contract fetching logic in `getOrDeployInfraContract` for `WETH9` on `ZkSync`.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->
  • Loading branch information
kumaryash90 committed Dec 20, 2024
1 parent 243c497 commit 3718020
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
} from "thirdweb/deploys";
import { useActiveAccount, useActiveWalletChain } from "thirdweb/react";
import { upload } from "thirdweb/storage";
import { isZkSyncChain } from "thirdweb/utils";
import { FormHelperText, FormLabel, Heading, Text } from "tw-components";
import { useCustomFactoryAbi, useFunctionParamsFromABI } from "../hooks";
import { addContractToMultiChainRegistry } from "../utils";
Expand Down Expand Up @@ -426,7 +427,10 @@ export const CustomContractForm: React.FC<CustomContractFormProps> = ({
}
}

if (metadata.name === "MarketplaceV3") {
if (
metadata.name === "MarketplaceV3" &&
!(await isZkSyncChain(walletChain))
) {
// special case for marketplace
return await deployMarketplaceContract({
account: activeAccount,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { describe, expect, it } from "vitest";
import { ANVIL_CHAIN } from "../../../../test/src/chains.js";
import { TEST_CLIENT } from "../../../../test/src/test-clients.js";
import { TEST_ACCOUNT_A } from "../../../../test/src/test-wallets.js";
import { deployCloneFactory } from "./bootstrap.js";
import { defineChain } from "../../../chains/utils.js";
import {
deployCloneFactory,
getOrDeployInfraContract,
getOrDeployInfraForPublishedContract,
} from "./bootstrap.js";
import { getDeployedCreate2Factory } from "./create-2-factory.js";
import { getDeployedInfraContract } from "./infra.js";

Expand Down Expand Up @@ -42,4 +47,42 @@ describe.runIf(process.env.TW_SECRET_KEY)("bootstrap", () => {
});
expect(cloneFactory).not.toBeNull();
});

it("should return saved implementations for zksync chains", async () => {
let infra = await getOrDeployInfraForPublishedContract({
client: TEST_CLIENT,
chain: defineChain(300),
account: TEST_ACCOUNT_A,
contractId: "MarketplaceV3",
});

expect(infra.cloneFactoryContract.address).to.eq(
"0xa51baf6a9c0ef5Db8C1898d5aDD92Bf3227d6088",
);
expect(infra.implementationContract.address).to.eq(
"0x58e0F289C7dD2025eBd0696d913ECC0fdc1CC8bc",
);

infra = await getOrDeployInfraForPublishedContract({
client: TEST_CLIENT,
chain: defineChain(300),
account: TEST_ACCOUNT_A,
contractId: "DropERC721",
version: "5.0.4",
});

expect(infra.cloneFactoryContract.address).to.eq(
"0xa51baf6a9c0ef5Db8C1898d5aDD92Bf3227d6088",
);
expect(infra.implementationContract.address).toBeDefined();

const weth = await getOrDeployInfraContract({
client: TEST_CLIENT,
chain: defineChain(300),
account: TEST_ACCOUNT_A,
contractId: "WETH9",
});

expect(weth.address).to.eq("0x0462C05457Fed440740Ff3696bDd2D0577411e34");
});
});
49 changes: 38 additions & 11 deletions packages/thirdweb/src/contract/deployment/utils/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import { isZkSyncChain } from "../../../utils/any-evm/zksync/isZkSyncChain.js";
import type { ClientAndChainAndAccount } from "../../../utils/types.js";
import { type ThirdwebContract, getContract } from "../../contract.js";
import { fetchPublishedContractMetadata } from "../publisher.js";
import {
ZKSYNC_IMPLEMENTATIONS,
ZKSYNC_WETH,
} from "../zksync/implementations.js";
import { zkDeployCreate2Factory } from "../zksync/zkDeployCreate2Factory.js";
import { zkDeployContractDeterministic } from "../zksync/zkDeployDeterministic.js";
import { getDeployedCloneFactoryContract } from "./clone-factory.js";
Expand Down Expand Up @@ -69,18 +73,29 @@ export async function getOrDeployInfraForPublishedContract(
publisher,
version,
});
const implementationContract = await zkDeployContractDeterministic({
chain,
client,
account,
abi: compilerMetadata.abi,
bytecode: await fetchBytecodeFromCompilerMetadata({
compilerMetadata,
client,

const zksyncImplementations = ZKSYNC_IMPLEMENTATIONS[chain.id];
let implementationContract: string | undefined;

if (zksyncImplementations) {
implementationContract = zksyncImplementations[contractId];
}

if (!implementationContract) {
implementationContract = await zkDeployContractDeterministic({
chain,
}),
params: constructorParams,
});
client,
account,
abi: compilerMetadata.abi,
bytecode: await fetchBytecodeFromCompilerMetadata({
compilerMetadata,
client,
chain,
}),
params: constructorParams,
});
}

return {
cloneFactoryContract: getContract({
address: cloneFactoryContract,
Expand Down Expand Up @@ -188,6 +203,18 @@ export async function getOrDeployInfraContract(
version?: string;
},
) {
if (options.contractId === "WETH9" && (await isZkSyncChain(options.chain))) {
const weth = ZKSYNC_WETH[options.chain.id];

if (weth) {
return getContract({
client: options.client,
chain: options.chain,
address: weth,
});
}
}

const contractMetadata = await fetchPublishedContractMetadata({
client: options.client,
contractId: options.contractId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const ZKSYNC_IMPLEMENTATIONS: Record<number, Record<string, string>> = {
[300]: {
MarketplaceV3: "0x58e0F289C7dD2025eBd0696d913ECC0fdc1CC8bc",
},
[302]: {
MarketplaceV3: "0x8b0DBCf5b7D01eBB0F24525CE8AB72F16CE4F8C8",
},
[324]: {
MarketplaceV3: "0xBc02441a36Bb4029Cd191b20243c2e41B862F118",
},
[11124]: {
MarketplaceV3: "0x2dA4Dd326A6482679547071be21f74685d730504",
},
};

export const ZKSYNC_WETH: Record<number, string> = {
[300]: "0x0462C05457Fed440740Ff3696bDd2D0577411e34",
[324]: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91",
[11124]: "0x9EDCde0257F2386Ce177C3a7FCdd97787F0D841d",
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { describe, expect, it } from "vitest";
import { CLEAN_ANVIL_CHAIN } from "../../../test/src/chains.js";
import { TEST_CLIENT } from "../../../test/src/test-clients.js";
import { defineChain } from "../../chains/utils.js";
import { fetchPublishedContractMetadata } from "../../contract/deployment/publisher.js";
import { getRequiredTransactions } from "./get-required-transactions.js";
import {
getAllDefaultConstructorParamsForImplementation,
getRequiredTransactions,
} from "./get-required-transactions.js";

describe.runIf(process.env.TW_SECRET_KEY)(
"getRequiredTransactions",
Expand Down Expand Up @@ -59,5 +63,14 @@ describe.runIf(process.env.TW_SECRET_KEY)(
});
expect(results.length).toBe(7);
});

it("should return default constructor params for zksync chains", async () => {
const params = await getAllDefaultConstructorParamsForImplementation({
chain: defineChain(300),
client: TEST_CLIENT,
});

expect(params.nativeTokenWrapper).toBeDefined();
});
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ThirdwebClient } from "../../client/client.js";
import { getDeployedCreate2Factory } from "../../contract/deployment/utils/create-2-factory.js";
import { getDeployedInfraContract } from "../../contract/deployment/utils/infra.js";
import { getDeployedInfraContractFromMetadata } from "../../contract/deployment/utils/infra.js";
import { ZKSYNC_WETH } from "../../contract/deployment/zksync/implementations.js";
import { computePublishedContractAddress } from "../../utils/any-evm/compute-published-contract-address.js";
import type { FetchDeployMetadataResult } from "../../utils/any-evm/deploy-metadata.js";
import { isZkSyncChain } from "../../utils/any-evm/zksync/isZkSyncChain.js";
Expand Down Expand Up @@ -227,8 +228,11 @@ export async function getAllDefaultConstructorParamsForImplementation(args: {
const { chain, client } = args;
const isZkSync = await isZkSyncChain(chain);
if (isZkSync) {
// zksync contracts dont need these implementation constructor params
return {};
const weth = ZKSYNC_WETH[chain.id];

return {
nativeTokenWrapper: weth,
};
}
const [forwarder, weth] = await Promise.all([
computePublishedContractAddress({
Expand Down

0 comments on commit 3718020

Please sign in to comment.