diff --git a/src/DeploymentFactory.ts b/src/DeploymentFactory.ts index 806c6c33..aa5b2ce8 100644 --- a/src/DeploymentFactory.ts +++ b/src/DeploymentFactory.ts @@ -140,15 +140,17 @@ export class DeploymentFactory { ): Promise { const newTransaction = await this.getDeployTransaction(); const newData = newTransaction.data?.toString(); - if (this.isZkSync) { - const deserialize = zk.utils.parseTransaction(transaction.data) as any; - const desFlattened = hexConcat(deserialize.customData.factoryDeps); - const factoryDeps = await this.extractFactoryDeps(this.artifact); - const newFlattened = hexConcat(factoryDeps); + // NOTE: (25 Oct) zksync-era client does not support factoryDeps in transaction.data + // if (this.isZkSync) { + // const deserialize = zk.utils.parseTransaction(transaction.data) as any; + // const desFlattened = hexConcat(deserialize.customData.factoryDeps); + // const factoryDeps = await this.extractFactoryDeps(this.artifact); + // const newFlattened = hexConcat(factoryDeps); - return deserialize.data !== newData || desFlattened != newFlattened; - } else { - return transaction.data !== newData; - } + // return deserialize.data !== newData || desFlattened != newFlattened; + // } else { + // return transaction.data !== newData; + // } + return transaction.data !== newData; } } diff --git a/src/helpers.ts b/src/helpers.ts index 87d7baa8..576cba35 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -525,7 +525,7 @@ export function addHelpers( options ); - let overrides: PayableOverrides = { + const overrides: PayableOverrides = { gasLimit: options.gasLimit, gasPrice: options.gasPrice, maxFeePerGas: options.maxFeePerGas, @@ -1493,8 +1493,8 @@ Note that in this case, the contract deployment will not behave the same if depl upgradeArgsTemplate = ['{implementation}', '{data}']; } - let proxyAddress = proxy.address; - let upgradeArgs = replaceTemplateArgs(upgradeArgsTemplate, { + const proxyAddress = proxy.address; + const upgradeArgs = replaceTemplateArgs(upgradeArgsTemplate, { implementationAddress: implementation.address, proxyAdmin, data, @@ -1829,31 +1829,103 @@ Note that in this case, the contract deployment will not behave the same if depl // console.log({ oldFacets: JSON.stringify(oldFacets, null, " ") }); const facetsSet = [...options.facets]; - if (options.defaultCutFacet === undefined || options.defaultCutFacet) { + const getContractNameAndArtifact = async ( + defaultName: string, + defaultArtifactData: ArtifactData, + args?: boolean | string | {name: string; artifact?: string | ArtifactData} + ): Promise< + | { + name: string; + artifact: ArtifactData; + } + | undefined + > => { + if (args === false) { + return undefined; + } + + if (args === undefined || args === true) { + return { + name: defaultName, + artifact: defaultArtifactData, + }; + } + + if (typeof args === 'string') { + try { + return { + name: defaultName, + artifact: await partialExtension.getExtendedArtifact(args), + }; + } catch (e) {} + + if (args === defaultName) { + return { + name: defaultName, + artifact: defaultArtifactData, + }; + } else { + throw new Error(`no contract found for ${args}`); + } + } + + const name = args.name; + let artifact: ArtifactData | undefined; + if (args.artifact === undefined) { + artifact = defaultArtifactData; + } else if (typeof args.artifact === 'string') { + artifact = await partialExtension.getExtendedArtifact(args.artifact); + } else { + artifact = args.artifact; + } + + return { + name: name, + artifact: artifact, + }; + }; + + const diamondCutFacetNameAndArtifact = await getContractNameAndArtifact( + '_DefaultDiamondCutFacet', + diamondCutFacet, + options.defaultCutFacetContract + ); + if (diamondCutFacetNameAndArtifact) { facetsSet.push({ - name: '_DefaultDiamondCutFacet', - contract: diamondCutFacet, + name: diamondCutFacetNameAndArtifact.name, + contract: diamondCutFacetNameAndArtifact.artifact, args: [], deterministic: true, }); } - if ( - options.defaultOwnershipFacet === undefined || - options.defaultOwnershipFacet - ) { + + const ownershipFacetNameAndArtifact = await getContractNameAndArtifact( + '_DefaultDiamondOwnershipFacet', + ownershipFacet, + options.defaultOwnershipFacetContract + ); + if (ownershipFacetNameAndArtifact) { facetsSet.push({ - name: '_DefaultDiamondOwnershipFacet', - contract: ownershipFacet, + name: ownershipFacetNameAndArtifact.name, + contract: ownershipFacetNameAndArtifact.artifact, + args: [], + deterministic: true, + }); + } + + const diamondLoupeFacetNameAndArtifact = await getContractNameAndArtifact( + '_DefaultDiamondLoupeFacet', + diamondLoupeFacet, + options.defaultLoupeFacetContract + ); + if (diamondLoupeFacetNameAndArtifact) { + facetsSet.push({ + name: diamondLoupeFacetNameAndArtifact.name, + contract: diamondLoupeFacetNameAndArtifact.artifact, args: [], deterministic: true, }); } - facetsSet.push({ - name: '_DefaultDiamondLoupeFacet', - contract: diamondLoupeFacet, - args: [], - deterministic: true, - }); let changesDetected = !oldDeployment; let abi: any[] = diamondArtifact.abi.concat([]); @@ -2201,20 +2273,30 @@ Note that in this case, the contract deployment will not behave the same if depl // TODO option to add more to the list // else mechanism to set it up differently ? LoupeFacet without supportsInterface const interfaceList = ['0x48e2b093']; - if (options.defaultCutFacet) { + if (options.defaultCutFacetContract) { interfaceList.push('0x1f931c1c'); } - if (options.defaultOwnershipFacet) { + if (options.defaultOwnershipFacetContract) { interfaceList.push('0x7f5828d0'); } if (initializationsArgIndex >= 0 || erc165InitArgIndex >= 0) { + const diamondERC165InitNameAndArtifact = + await getContractNameAndArtifact( + '_DefaultDiamondERC165Init', + diamondERC165Init, + options.defaultERC165InitContract + ); + if (!diamondERC165InitNameAndArtifact) { + throw new Error('no DiamondERC165Init artifact found'); + } + const diamondERC165InitDeployment = await _deployOne( - '_DefaultDiamondERC165Init', + diamondERC165InitNameAndArtifact.name, { from: options.from, deterministicDeployment: true, - contract: diamondERC165Init, + contract: diamondERC165InitNameAndArtifact.artifact, autoMine: options.autoMine, estimateGasExtra: options.estimateGasExtra, estimatedGasLimit: options.estimatedGasLimit, @@ -2784,9 +2866,7 @@ data: ${data} } async function getSigner(address: string): Promise { await init(); - const { - ethersSigner - } = await getFrom(address); + const {ethersSigner} = await getFrom(address); return ethersSigner; } @@ -2802,7 +2882,7 @@ data: ${data} rawTx, read, deterministic, - getSigner + getSigner, }; const utils = { diff --git a/types.ts b/types.ts index 3d4df3ff..0fdbb187 100644 --- a/types.ts +++ b/types.ts @@ -82,9 +82,33 @@ export interface DiamondOptions extends TxOptions { diamondContract?: string | ArtifactData; // TODO diamondContractArgs?: any[]; owner?: Address; - // defaultLoopeFacet?: boolean; // TODO // always there - defaultOwnershipFacet?: boolean; - defaultCutFacet?: boolean; + defaultLoupeFacetContract?: + | boolean + | string + | { + name: string; + artifact?: string | ArtifactData; + }; + defaultOwnershipFacetContract?: + | boolean + | string + | { + name: string; + artifact?: string | ArtifactData; + }; + defaultCutFacetContract?: + | boolean + | string + | { + name: string; + artifact?: string | ArtifactData; + }; + defaultERC165InitContract?: + | string + | { + name: string; + artifact?: string | ArtifactData; + }; facets: DiamondFacets; log?: boolean; libraries?: Libraries;