From be0cddbda6554924674ba4be12f0f10cfbbafe3a Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:14:39 +0000 Subject: [PATCH 1/9] add tenderly and tenderly config --- .devcontainer/Dockerfile | 2 ++ README.md | 9 +++++++++ hardhat.config.ts | 23 +++++++++++++++++++++++ package.json | 7 ++++--- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 6a2d01b3f..61e23cea3 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -30,3 +30,5 @@ RUN curl -L https://foundry.paradigm.xyz | bash RUN echo 'export PATH="$PATH:/home/node/.foundry/bin"' >> ~/.zshrc RUN echo 'export PATH="$PATH:/home/node/.foundry/bin"' >> ~/.bashrc RUN /home/node/.foundry/bin/foundryup + +RUN curl https://raw.githubusercontent.com/Tenderly/tenderly-cli/master/scripts/install-linux.sh | sudo sh \ No newline at end of file diff --git a/README.md b/README.md index fb0ffae35..d0101a6c9 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,10 @@ The deploy script will deploy all required contracts and create a test instance # run deployment on a locally created ganache instance export SKIP_VERIFICATION=true hh run scripts/deploy_all.ts + +# run deployment on tenderly virtual network +export SKIP_VERIFICATION=true +hh run scripts/deploy_all.ts --network vitualMainnet ``` ```bash @@ -86,6 +90,11 @@ Environment variables: - `WALLET_MNEMONIC` the mnemonic of the wallet to use for deployment (required for mumbai and mainnet) - `ETHERSCAN_API_KEY` `POLYGONSCAN_API_KEY` the api key for etherscan/polygonscan (required for mumbai and mainnet) +# https://dashboard.tenderly.co/{TENDERLY_USERNAME}/{TENDERLY_PROJECT}/fork/{FORK_ID} +- `TENDERLY_DEVNET_RPC_URL` +- `TENDERLY_USERNAME` +- `TENDERLY_PROJECT` + ### Create a new instance Requires previous step to be completed. diff --git a/hardhat.config.ts b/hardhat.config.ts index c035d805e..4acf23862 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -8,6 +8,20 @@ import "solidity-docgen"; import { config as dotEnvConfig } from "dotenv"; dotEnvConfig(); +const { TENDERLY_PRIVATE_VERIFICATION, TENDERLY_AUTOMATIC_VERIFICATION } = + process.env; + +const privateVerification = TENDERLY_PRIVATE_VERIFICATION === "true"; +const automaticVerifications = TENDERLY_AUTOMATIC_VERIFICATION === "true";// TODO use default false value -> no automatic verification + +import * as tenderly from "@tenderly/hardhat-tenderly"; + +tenderly.setup({ automaticVerifications }); + +console.log("Using private verification?", privateVerification); +console.log("Using automatic verification?", automaticVerifications); + + const config: HardhatUserConfig = { solidity: { version: "0.8.20", @@ -19,6 +33,11 @@ const config: HardhatUserConfig = { } } }, + tenderly: { + username: process.env.TENDERLY_USERNAME, + project: process.env.TENDERLY_PROJECT, + privateVerification: privateVerification, + }, docgen: require("./docs/config"), networks: { hardhat: { @@ -44,6 +63,10 @@ const config: HardhatUserConfig = { chainId: 1, url: process.env.NETWORK_URL || 'https://mainnet.infura.io/v3/' + process.env.WEB3_INFURA_PROJECT_ID, }, + virtualMainnet: { + url: process.env.TENDERLY_DEVNET_RPC_URL, + chainId: 1 + }, }, etherscan: { apiKey: { diff --git a/package.json b/package.json index 8df1f62d7..870ca06db 100644 --- a/package.json +++ b/package.json @@ -29,9 +29,10 @@ ], "homepage": "https://github.com/etherisc/gif-next#readme", "devDependencies": { - "@nomicfoundation/hardhat-foundry": "^1.1.1", - "@nomicfoundation/hardhat-toolbox": "^3.0.0", - "@nomicfoundation/hardhat-verify": "^1.1.1", + "@nomicfoundation/hardhat-foundry": "^1.1.2", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.7", + "@tenderly/hardhat-tenderly": "^2.2.2", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "dotenv": "^16.3.1", From b0f2dc59c4de9a22e53ab4b492d3fcf97eaac0f0 Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:30:34 +0000 Subject: [PATCH 2/9] verify with tenderly --- scripts/libs/accounts.ts | 2 +- scripts/libs/deployment.ts | 132 +++++-- scripts/libs/deployment_state.ts | 16 +- scripts/libs/instance.ts | 142 +++++-- scripts/libs/libraries.ts | 26 +- scripts/libs/registry.ts | 72 +++- scripts/libs/services.ts | 652 +++++++++++++++++++++++++++++-- 7 files changed, 929 insertions(+), 113 deletions(-) diff --git a/scripts/libs/accounts.ts b/scripts/libs/accounts.ts index c3a1ff011..903545614 100644 --- a/scripts/libs/accounts.ts +++ b/scripts/libs/accounts.ts @@ -20,7 +20,7 @@ export async function getNamedAccounts(): Promise<{ const poolOwner = signers[3]; const distributionOwner = signers[4]; const instanceServiceOwner = signers[5]; - const instanceOwner = signers[10]; + const instanceOwner = signers[6]; await printBalance( ["protocolOwner", protocolOwner] , ["masterInstanceOwner", masterInstanceOwner] , diff --git a/scripts/libs/deployment.ts b/scripts/libs/deployment.ts index f1231e702..15b7b1071 100644 --- a/scripts/libs/deployment.ts +++ b/scripts/libs/deployment.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { AddressLike, BaseContract, Signer, TransactionReceipt, TransactionResponse, resolveAddress } from "ethers"; -import hre, { ethers } from "hardhat"; +import hre, { ethers, tenderly } from "hardhat"; import { logger } from "../logger"; import { deploymentState, isResumeableDeployment } from "./deployment_state"; import { GAS_PRICE, NUMBER_OF_CONFIRMATIONS } from "./constants"; @@ -21,6 +21,7 @@ type DeploymentResult = { * In case of "MissingLibrariesError", fetch library addresses from LIBRARY_ADDRESSES and retry. * @param sourceFileContract the contract name prefixed with file path (e.g. "contracts/types/ObjectType.sol:ObjectTypeLib") */ +// TODO verifyContract() and verifyDeployedContract() -> wrong naming export async function verifyContract(address: AddressLike, constructorArgs: any[], sourceFileContract: string | undefined) { let verified = false; let retries = 3; @@ -92,19 +93,20 @@ export async function verifyContract(address: AddressLike, constructorArgs: any[ * @param constructorArgs a list of constructor arguments to pass to the contract constructor * @param factoryOptions options to pass to the contract factory (libraries, ...) */ -export async function deployContract(contractName: string, signer: Signer, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string): Promise { + // TODO get libraries from artifacts? +export async function deployContract(contractName: string, contractType: string, signer: Signer, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string): Promise { if (! isResumeableDeployment ) { logger.info("Starting new deployment"); - return executeAllDeploymentSteps(contractName, signer, constructorArgs, factoryOptions, sourceFileContract); + return executeAllDeploymentSteps(contractType, signer, constructorArgs, factoryOptions, sourceFileContract); } logger.info(`Trying to resume deployment of ${contractName}`); if (deploymentState.getContractAddress(contractName) === undefined) { if (deploymentState.getDeploymentTransaction(contractName) === undefined) { - return executeAllDeploymentSteps(contractName, signer, constructorArgs, factoryOptions, sourceFileContract); + return executeAllDeploymentSteps(contractName, contractType, signer, constructorArgs, factoryOptions, sourceFileContract); } else { - return awaitDeploymentTxAndVerify(contractName, signer, constructorArgs, sourceFileContract); + return awaitDeploymentTxAndVerify(contractName, contractType, signer, constructorArgs, sourceFileContract); } } else { // fetch persisted data @@ -117,7 +119,7 @@ export async function deployContract(contractName: string, signer: Signer, const } else { logger.info(`Contract ${contractName} is already deployed at ${address}`); if (deploymentTransaction !== null) { - await verifyDeployedContract(contractName, address, deploymentTransaction, constructorArgs, sourceFileContract); + await verifyDeployedContract(contractName, contractType, address, deploymentTransaction, constructorArgs, sourceFileContract); } } @@ -125,43 +127,95 @@ export async function deployContract(contractName: string, signer: Signer, const } } +// Use this function to add to deployemnt state and verify contract deployed by other contract +export async function addDeployedContract(contractName: string, contractType: string, contractAddress: AddressLike, signer: Signer, deploymentTransaction: TransactionResponse, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string) { + + const libraries = factoryOptions?.libraries ?? {}; + if(deploymentTransaction == undefined) { + throw new Error(`Deployment transaction for ${contractName} is not defined`); + } + + if (! isResumeableDeployment ) { + // add contract to deployment state + deploymentState.setDeploymentTransaction(contractName, contractType, deploymentTransaction?.hash || "0x", libraries); + deploymentState.setContractAddress(contractName, contractAddress); + await verifyDeployedContract(contractName, contractType, contractAddress, deploymentTransaction, constructorArgs, sourceFileContract); + return; + } + if (deploymentState.getContractAddress(contractName) === undefined) { + if (deploymentState.getDeploymentTransaction(contractName) === undefined) { + // contract not in deployment state + //throw new Error(`${contractName} deployment transaction is not found in deployment state`); + deploymentState.setDeploymentTransaction(contractName, contractType, deploymentTransaction?.hash || "0x", libraries); + deploymentState.setContractAddress(contractName, contractAddress); + await verifyDeployedContract(contractName, contractType, contractAddress, deploymentTransaction, constructorArgs, sourceFileContract); + } else { + awaitDeploymentTxAndVerify(contractName, contractType, signer, constructorArgs, sourceFileContract); + } + } else { + if (deploymentState.isDeployedAndVerified(contractName)) { + logger.info(`Contract ${contractName} is deployed at ${contractAddress} and verified`); + } else { + logger.info(`Contract ${contractName} is deployed at ${contractAddress}`); + if (deploymentTransaction !== null) { + await verifyDeployedContract(contractName, contractType, contractAddress, deploymentTransaction, constructorArgs, sourceFileContract); + } + } + } +} + export function delay(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } -async function executeAllDeploymentSteps(contractName: string, signer: Signer, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string): Promise { - logger.info(`Deploying ${contractName}...`); - const factoryArgs = factoryOptions != undefined ? { ...factoryOptions, signer } : { signer }; - const contractFactory = await ethers.getContractFactory(contractName, factoryArgs); +async function executeAllDeploymentSteps(contractName: string, contractType: string, signer: Signer, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string): Promise { + logger.info(`Deploying ${contractName}.sol...`); + const factoryArgs = factoryOptions != undefined ? { ...factoryOptions, signer } : { signer }; + const contractFactory = await ethers.getContractFactory(contractType, factoryArgs); - const opts = {} as any; - if (GAS_PRICE !== undefined) { - opts['gasPrice'] = GAS_PRICE; - } - const deployTxResponse = constructorArgs !== undefined - ? await contractFactory.deploy(...constructorArgs, opts) - : await contractFactory.deploy(opts); - deploymentState.setDeploymentTransaction(contractName, deployTxResponse.deploymentTransaction()?.hash || "0x"); - logger.info(`Waiting for deployment transaction ${deployTxResponse.deploymentTransaction()?.hash} to be mined...`); - await deployTxResponse.deploymentTransaction()?.wait(); - logger.debug("... mined"); - - const deployedContractAddress = deployTxResponse.target; - const deploymentReceipt = await ethers.provider.getTransactionReceipt(deployTxResponse.deploymentTransaction()?.hash || "0x"); - deploymentState.setContractAddress(contractName, await resolveAddress(deployedContractAddress)); - logger.info(`${contractName} deployed to ${deployedContractAddress}`); - - await verifyDeployedContract(contractName, deployedContractAddress, deployTxResponse.deploymentTransaction()!, constructorArgs, sourceFileContract); - - return { - address: deployedContractAddress, - deploymentTransaction: deployTxResponse.deploymentTransaction(), - deploymentReceipt: deploymentReceipt, - contract: deployTxResponse - }; + const opts = {} as any; + if (GAS_PRICE !== undefined) { + opts['gasPrice'] = GAS_PRICE; + } + const deployTxResponse = constructorArgs !== undefined + ? await contractFactory.deploy(...constructorArgs, opts) + : await contractFactory.deploy(opts); + const libraries = factoryOptions?.libraries ?? {}; + deploymentState.setDeploymentTransaction(contractName, contractType, deployTxResponse.deploymentTransaction()?.hash || "0x", libraries); + logger.info(`Waiting for deployment transaction ${deployTxResponse.deploymentTransaction()?.hash} to be mined...`); + await deployTxResponse.deploymentTransaction()?.wait(); + logger.debug("... mined"); + + const deployedContractAddress = deployTxResponse.target; + const deploymentReceipt = await ethers.provider.getTransactionReceipt(deployTxResponse.deploymentTransaction()?.hash || "0x"); + deploymentState.setContractAddress(contractName, await resolveAddress(deployedContractAddress)); + logger.info(`${contractName} deployed to ${deployedContractAddress}`); + + await verifyDeployedContract(contractName, contractType, deployedContractAddress, deployTxResponse.deploymentTransaction()!, constructorArgs, sourceFileContract); + + return { + address: deployedContractAddress, + deploymentTransaction: deployTxResponse.deploymentTransaction(), + deploymentReceipt: deploymentReceipt, + contract: deployTxResponse + }; } -async function verifyDeployedContract(contractName: string, address: AddressLike, tx: TransactionResponse, constructorArgs?: any[] | undefined, sourceFileContract?: string) { +async function verifyDeployedContract(contractName: string, contractType: string, address: AddressLike, tx: TransactionResponse, constructorArgs?: any[] | undefined, sourceFileContract?: string) { + + // Tenderly verification + // TODO skip if not tenderly network.. + // TODO libraries are in `${ARTIFACTS_PATH}${contractName}.json` + const libraries = deploymentState.getLibraries(contractName); + logger.info(`Verifing ${contractName}`) + await tenderly.verify({ + name: contractType, + address: address, + libraries: libraries}); + + deploymentState.setVerified(contractName, true); + + // Etherscan verification if (process.env.SKIP_VERIFICATION?.toLowerCase() !== "true") { logger.debug(`Waiting for ${NUMBER_OF_CONFIRMATIONS} confirmations`); await tx.wait(NUMBER_OF_CONFIRMATIONS); @@ -170,11 +224,11 @@ async function verifyDeployedContract(contractName: string, address: AddressLike : await verifyContract(address, [], sourceFileContract); deploymentState.setVerified(contractName, true); } else { - logger.debug("Skipping verification"); + logger.debug("Skipping verification (etherscan)"); } } -async function awaitDeploymentTxAndVerify(contractName: string, signer: Signer, constructorArgs?: any[] | undefined, sourceFileContract?: string): Promise { +async function awaitDeploymentTxAndVerify(contractName: string, contractType: string, signer: Signer, constructorArgs?: any[] | undefined, sourceFileContract?: string): Promise { const deploymentTx = deploymentState.getDeploymentTransaction(contractName)! logger.info(`Deployment transaction ${deploymentTx} exists, waiting for it to be mined...`); const deploymentTransaction = await ethers.provider.getTransaction(deploymentTx); @@ -196,7 +250,7 @@ async function awaitDeploymentTxAndVerify(contractName: string, signer: Signer, deploymentState.setContractAddress(contractName, await resolveAddress(address)); - await verifyDeployedContract(contractName, address, deploymentTransaction, constructorArgs, sourceFileContract); + await verifyDeployedContract(contractName, contractType, address, deploymentTransaction, constructorArgs, sourceFileContract); return { address, deploymentTransaction, contract }; } \ No newline at end of file diff --git a/scripts/libs/deployment_state.ts b/scripts/libs/deployment_state.ts index 581ec2b48..42a2f3636 100644 --- a/scripts/libs/deployment_state.ts +++ b/scripts/libs/deployment_state.ts @@ -12,8 +12,10 @@ type State = { export type ContractState = { name: string; + type: string; deploymentTransaction: string | undefined; address: string | undefined; + libraries?: any | undefined; verified: boolean; } @@ -49,6 +51,14 @@ export class DeploymentState { return contractState.deploymentTransaction; } + public getLibraries(contractName: string): any | undefined { + const contractState = this.state.contracts.find(c => c.name === contractName); + if (contractState === undefined) { + return undefined; + } + return contractState.libraries; + } + public isContractDeployed(contractName: string): boolean { const contractState = this.state.contracts.find(c => c.name === contractName); if (contractState === undefined) { @@ -57,18 +67,22 @@ export class DeploymentState { return contractState.address !== undefined; } - public setDeploymentTransaction(contractName: string, deploymentTransaction: string): void { + public setDeploymentTransaction(contractName: string, contractType: string, deploymentTransaction: string, libraries?: any | undefined): void { const contractState = this.state.contracts.find(c => c.name === contractName); if (contractState === undefined) { logger.debug(`Contract state not found for ${contractName}`); this.state.contracts.push({ name: contractName, + type: contractType, deploymentTransaction: deploymentTransaction, address: undefined, + libraries: libraries, verified: false }); } else { contractState.deploymentTransaction = deploymentTransaction; + contractState.libraries = libraries; + contractState.type = contractType; } this.persistState(); } diff --git a/scripts/libs/instance.ts b/scripts/libs/instance.ts index 7dda5db69..40ac6b050 100644 --- a/scripts/libs/instance.ts +++ b/scripts/libs/instance.ts @@ -1,14 +1,16 @@ +import { tenderly } from "hardhat"; import { AddressLike, Signer, ethers, resolveAddress } from "ethers"; -import { BundleManager, IRegistry__factory, Instance, InstanceAdmin, InstanceService__factory, InstanceReader, AccessManagerExtendedInitializeable, InstanceStore, TimestampLib__factory } from "../../typechain-types"; +import { BundleManager, IRegistry__factory, Instance, Instance__factory, InstanceAdmin, InstanceService__factory, InstanceReader, AccessManagerExtendedInitializeable, InstanceStore, TimestampLib__factory } from "../../typechain-types"; import { logger } from "../logger"; import { deployContract } from "./deployment"; +import { deploymentState } from "./deployment_state"; import { LibraryAddresses } from "./libraries"; import { RegistryAddresses } from "./registry"; import { executeTx, getFieldFromLogs, getFieldFromTxRcptLogs } from "./transaction"; import { ServiceAddresses } from "./services"; export type InstanceAddresses = { - accessManagerAddress: AddressLike, + instanceAccessManagerAddress: AddressLike, instanceAdminAddress: AddressLike, instanceReaderAddress: AddressLike, instanceBundleManagerAddress: AddressLike, @@ -27,7 +29,8 @@ export async function deployAndRegisterMasterInstance( ): Promise { logger.info("======== Starting deployment of master instance ========"); - const { address: accessManagerAddress, contract: accessManagerBaseContract } = await deployContract( + const { address: instanceAccessManagerAddress, contract: accessManagerBaseContract } = await deployContract( + "InstanceAccessManager", "AccessManagerExtendedInitializeable", owner, [], @@ -41,6 +44,7 @@ export async function deployAndRegisterMasterInstance( await executeTx(() => accessManager.initialize(resolveAddress(owner))); const { address: instanceAddress, contract: masterInstanceBaseContract } = await deployContract( + "Instance", "Instance", owner, undefined, @@ -53,9 +57,10 @@ export async function deployAndRegisterMasterInstance( } ); const instance = masterInstanceBaseContract as Instance; - await executeTx(() => instance.initialize(accessManagerAddress, registry.registryAddress, resolveAddress(owner))); + await executeTx(() => instance.initialize(instanceAccessManagerAddress, registry.registryAddress, resolveAddress(owner))); const { address: instanceStoreAddress, contract: masterInstanceStoreContract } = await deployContract( + "InstanceStore", "InstanceStore", owner, [], @@ -80,6 +85,7 @@ export async function deployAndRegisterMasterInstance( await executeTx(() => instance.setInstanceStore(instanceStore)); const { address: instanceReaderAddress, contract: masterReaderBaseContract } = await deployContract( + "InstanceReader", "InstanceReader", owner, [], @@ -102,6 +108,7 @@ export async function deployAndRegisterMasterInstance( await executeTx(() => instance.setInstanceReader(instanceReaderAddress)); const {address: bundleManagerAddress, contract: bundleManagerBaseContrat} = await deployContract( + "BundleManager", "BundleManager", owner, [], @@ -117,6 +124,7 @@ export async function deployAndRegisterMasterInstance( await executeTx(() => instance.setBundleManager(bundleManagerAddress)); const { address: instanceAdminAddress, contract: instanceAdminBaseContract } = await deployContract( + "InstanceAdmin", "InstanceAdmin", owner, [], @@ -152,7 +160,7 @@ export async function deployAndRegisterMasterInstance( logger.info("======== Finished deployment of master instance ========"); return { - accessManagerAddress: accessManagerAddress, + instanceAccessManagerAddress: instanceAccessManagerAddress, instanceAdminAddress: instanceAdminAddress, instanceReaderAddress: instanceReaderAddress, instanceBundleManagerAddress: bundleManagerAddress, @@ -162,47 +170,117 @@ export async function deployAndRegisterMasterInstance( } as InstanceAddresses; } -export async function cloneInstance(masterInstance: InstanceAddresses, libraries: LibraryAddresses, registry: RegistryAddresses, services: ServiceAddresses, instanceOwner: Signer): Promise { +// !!! TODO in addition: DO NOT DEPLOY WHOLE FRAMEWORK EACH TIME, RESUME DEPLOYMENT BASED ON DEPLOYMENT STATE OR ONCHAIN STATE +// if onchain state: +// then each chain must have at same predefined address with/which .... info about +// deployment script knows where to start resumable deployment +export async function cloneInstance(instanceServiceAddress: AddressLike, instanceOwner: Signer, releaseVersion : string) : Promise { logger.info("======== Starting cloning of instance ========"); - const instanceServiceAsClonedInstanceOwner = InstanceService__factory.connect(await resolveAddress(services.instanceServiceAddress), instanceOwner); - logger.debug(`cloning instance ${masterInstance.instanceAddress} ...`); - const cloneTx = await executeTx(async () => await instanceServiceAsClonedInstanceOwner.createInstanceClone()); - const clonedOzAccessManagerAddress = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedOzAccessManager"); - const clonedInstanceAdminAddress = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedInstanceAdmin"); - const clonedInstanceAddress = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedInstance"); - const clonedBundleManagerAddress = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedBundleManager"); - const clonedInstanceReaderAddress = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedInstanceReader"); - const clonedInstanceNftId = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedInstanceNftId"); + const instanceService = InstanceService__factory.connect(await resolveAddress(instanceServiceAddress), instanceOwner); + const instanceServiceVersion = await instanceService.getMajorVersion(); + const masterInstanceAddress = await instanceService.getMasterInstanceAddress(); + + logger.info(`instance service address: ${instanceServiceAddress}`); + logger.info(`instance service major version: ${instanceServiceVersion}`); + logger.info(`master instance address: ${masterInstanceAddress}`); + + logger.debug(`------- cloning instance ${masterInstanceAddress} --------`); + const cloneTx = await executeTx(async () => await instanceService.createInstanceClone()); + const clonedInstanceAccessManagerAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedOzAccessManager"); + const clonedInstanceAdminAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceAdmin") as AddressLike; + const clonedInstanceAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstance") as string; + const clonedBundleManagerAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedBundleManager"); + const clonedInstanceReaderAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceReader"); + const clonedInstanceNftId = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceNftId"); + + const clonedInstance = Instance__factory.connect(clonedInstanceAddress, instanceOwner); + const clonedlInstanceVersion = await clonedInstance.getMajorVersion(); + const clonedInstanceOwner = await clonedInstance.getOwner(); + logger.info(`cloned instance major version: ${clonedlInstanceVersion}`); + logger.info(`cloned instance owner: ${clonedInstanceOwner}`); + logger.info("Verifying cloned instance access manager"); + const libraries = deploymentState.getLibraries("AccessManagerExtendedInitializeable"); + if(libraries === undefined) { + throw new Error("Libraries not found in deployment state"); + } + + logger.info("Verifying cloned instance access manager"); + await tenderly.verify({ + name: "AccessManagerExtendedInitializeable", + address: clonedInstanceAccessManagerAddress, + libraries: { + TimestampLib: libraries.timestampLibAddress, + } + }); + logger.info("Verifying cloned instance admin"); + /*await deployContract( + "InstanceAdmin", + owner, + [], + { libraries: { + RoleIdLib: libraries.roleIdLibAddress + }});*/ + await tenderly.verify({ + name: "InstanceAdmin", + address: clonedInstanceAdminAddress, + libraries: { + RoleIdLib: libraries.roleIdLibAddress + }}); + logger.info("Verifying cloned instance"); + await tenderly.verify({ + name: "Instance", + address: clonedInstanceAddress, + libraries: { + NftIdLib: libraries.nftIdLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + } + }); + logger.info("Verifying cloned instance reader"); + await tenderly.verify({ + name: "InstanceReader", + address: clonedInstanceReaderAddress, + libraries: { + AmountLib: libraries.amountLibAddress, + ClaimIdLib: libraries.claimIdLibAddress, + DistributorTypeLib: libraries.distributorTypeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + PayoutIdLib: libraries.payoutIdLibAddress, + ReferralLib: libraries.referralLibAddress, + RiskIdLib: libraries.riskIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + UFixedLib: libraries.uFixedLibAddress, + } + }); + logger.info("Verifying cloned bundle manager"); + await tenderly.verify({ + name: "BundleManager", + address: clonedBundleManagerAddress, + libraries: { + NftIdLib: libraries.nftIdLibAddress, + LibNftIdSet: libraries.libNftIdSetAddress, + } + }); + logger.info(`instance cloned - clonedInstanceNftId: ${clonedInstanceNftId}`); logger.info("======== Finished cloning of instance ========"); return { - accessManagerAddress: clonedOzAccessManagerAddress, + instanceAccessManagerAddress: clonedInstanceAccessManagerAddress, instanceAdminAddress: clonedInstanceAdminAddress, instanceAddress: clonedInstanceAddress, instanceBundleManagerAddress: clonedBundleManagerAddress, instanceReaderAddress: clonedInstanceReaderAddress, instanceNftId: clonedInstanceNftId as string, - } as InstanceAddresses; + } as InstanceAddresses;*/ } -export async function cloneInstanceFromRegistry(registryAddress: AddressLike, instanceOwner: Signer): Promise { +export async function cloneInstanceFromRegistry(registryAddress: AddressLike, instanceOwner: Signer/*, releaseVersion: string*/): Promise { const registry = IRegistry__factory.connect(await resolveAddress(registryAddress), instanceOwner); - const instanceServiceAddress = await registry.getServiceAddress("InstanceService", "3"); - const instanceServiceAsClonedInstanceOwner = InstanceService__factory.connect(await resolveAddress(instanceServiceAddress), instanceOwner); - const masterInstanceAddress = await instanceServiceAsClonedInstanceOwner.getMasterInstance(); - logger.debug(`cloning instance ${masterInstanceAddress} ...`); - const cloneTx = await executeTx(async () => await instanceServiceAsClonedInstanceOwner.createInstanceClone()); - const clonedInstanceAddress = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedInstanceAddress"); - const clonedInstanceNftId = getFieldFromLogs(cloneTx.logs, instanceServiceAsClonedInstanceOwner.interface, "LogInstanceCloned", "clonedInstanceNftId"); - - logger.info(`instance cloned - clonedInstanceNftId: ${clonedInstanceNftId}`); - - return { - instanceAddress: clonedInstanceAddress, - instanceNftId: clonedInstanceNftId as string, - } as InstanceAddresses; + const instanceServiceDomain = 70; + const instanceServiceAddress = await registry.getServiceAddress(instanceServiceDomain, "3"); + return cloneInstance(instanceServiceAddress, instanceOwner); } \ No newline at end of file diff --git a/scripts/libs/libraries.ts b/scripts/libs/libraries.ts index 4599b5f26..3a5cf996c 100644 --- a/scripts/libs/libraries.ts +++ b/scripts/libs/libraries.ts @@ -31,14 +31,16 @@ export type LibraryAddresses = { export const LIBRARY_ADDRESSES: Map = new Map(); -export async function deployLibraries(owner: Signer): Promise { +export async function deployLibraries(owner: Signer): Promise { logger.info("======== Starting deployment of libraries ========"); const { address: key32LibAddress } = await deployContract( + "Key32Lib", "Key32Lib", owner); LIBRARY_ADDRESSES.set("Key32Lib", key32LibAddress); const { address: nftIdLibAddress } = await deployContract( + "NftIdLib", "NftIdLib", owner, undefined, @@ -50,11 +52,13 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("NftIdLib", nftIdLibAddress); const { address: uFixedLibAddress } = await deployContract( + "UFixedLib", "UFixedLib", owner); LIBRARY_ADDRESSES.set("UFixedLib", uFixedLibAddress); const { address: amountLibAddress } = await deployContract( + "AmountLib", "AmountLib", owner, undefined, @@ -66,6 +70,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("AmountLib", amountLibAddress); const { address: claimIdLibAddress } = await deployContract( + "ClaimIdLib", "ClaimIdLib", owner, undefined, @@ -77,6 +82,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("ClaimIdLib", claimIdLibAddress); const { address: payoutIdLibAddress } = await deployContract( + "PayoutIdLib", "PayoutIdLib", owner, undefined, @@ -88,11 +94,13 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("PayoutIdLib", payoutIdLibAddress); const { address: mathLibAddress } = await deployContract( + "MathLib", "MathLib", owner); LIBRARY_ADDRESSES.set("MathLib", mathLibAddress); const { address: objectTypeLibAddress } = await deployContract( + "ObjectTypeLib", "ObjectTypeLib", owner, undefined, @@ -101,26 +109,31 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("ObjectTypeLib", objectTypeLibAddress); const { address: blockNumberLibAddress } = await deployContract( + "BlocknumberLib", "BlocknumberLib", owner); LIBRARY_ADDRESSES.set("BlocknumberLib", blockNumberLibAddress); const { address: versionLibAddress } = await deployContract( + "VersionLib", "VersionLib", owner); LIBRARY_ADDRESSES.set("VersionLib", versionLibAddress); const { address: versionPartLibAddress } = await deployContract( + "VersionPartLib", "VersionPartLib", owner); LIBRARY_ADDRESSES.set("VersionPartLib", versionPartLibAddress); const { address: secondsLibAddress } = await deployContract( + "SecondsLib", "SecondsLib", owner); LIBRARY_ADDRESSES.set("SecondsLib", secondsLibAddress); const { address: timestampLibAddress } = await deployContract( + "TimestampLib", "TimestampLib", owner, undefined, @@ -132,6 +145,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("TimestampLib", timestampLibAddress); const { address: targetManagerLibAddress } = await deployContract( + "TargetManagerLib", "TargetManagerLib", owner, undefined, @@ -145,6 +159,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("TargetManagerLib", targetManagerLibAddress); const { address: stakeManagerLibAddress } = await deployContract( + "StakeManagerLib", "StakeManagerLib", owner, undefined, @@ -159,6 +174,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("StaketManagerLib", stakeManagerLibAddress); const { address: stateIdLibAddress } = await deployContract( + "StateIdLib", "StateIdLib", owner, undefined, @@ -167,11 +183,13 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("StateIdLib", stateIdLibAddress); const { address: libNftIdSetAddress } = await deployContract( + "LibNftIdSet", "LibNftIdSet", owner); LIBRARY_ADDRESSES.set("LibNftIdSet", libNftIdSetAddress); const { address: roleIdLibAddress } = await deployContract( + "RoleIdLib", "RoleIdLib", owner, undefined, @@ -183,6 +201,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("RoleIdLib", roleIdLibAddress); const { address: riskIdLibAddress } = await deployContract( + "RiskIdLib", "RiskIdLib", owner, undefined, @@ -194,6 +213,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("RiskIdLib", riskIdLibAddress); const { address: feeLibAddress } = await deployContract( + "FeeLib", "FeeLib", owner, undefined, @@ -206,6 +226,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("FeeLib", feeLibAddress); const { address: distributorTypeLibAddress } = await deployContract( + "DistributorTypeLib", "DistributorTypeLib", owner, undefined, @@ -218,6 +239,7 @@ export async function deployLibraries(owner: Signer): Promise // ReferralLib const { address: referralLibAddress } = await deployContract( + "ReferralLib", "ReferralLib", owner, undefined, @@ -229,6 +251,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("ReferralLib", referralLibAddress); const { address: instanceAuthorizationsLibAddress } = await deployContract( + "InstanceAuthorizationsLib", "InstanceAuthorizationsLib", owner, undefined, @@ -240,6 +263,7 @@ export async function deployLibraries(owner: Signer): Promise LIBRARY_ADDRESSES.set("InstanceAuthorizationsLib", instanceAuthorizationsLibAddress); const { address: serviceAuthorizationsLibAddress } = await deployContract( + "ServiceAuthorizationsLib", "ServiceAuthorizationsLib", owner, undefined, diff --git a/scripts/libs/registry.ts b/scripts/libs/registry.ts index edf5373d8..bf713e647 100644 --- a/scripts/libs/registry.ts +++ b/scripts/libs/registry.ts @@ -1,4 +1,4 @@ -import { AddressLike, Signer, resolveAddress } from "ethers"; +import { AddressLike, Signer, TransactionResponse, resolveAddress } from "ethers"; import { Dip, ChainNft, ChainNft__factory, @@ -13,9 +13,11 @@ import { RegistryAccessManager__factory, } from "../../typechain-types"; import { logger } from "../logger"; -import { deployContract, verifyContract } from "./deployment"; +import { deployContract, addDeployedContract, verifyContract } from "./deployment"; +import { deploymentState } from "./deployment_state"; import { LibraryAddresses } from "./libraries"; import { getFieldFromTxRcptLogs, executeTx } from "./transaction"; +import { tenderly } from "hardhat"; export type RegistryAddresses = { @@ -59,6 +61,7 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info("-------- Starting deployment DIP ----------------"); const { address: dipAddress, contract: dipBaseContract } = await deployContract( + "Dip", "Dip", owner, // GIF_ADMIN_ROLE [], @@ -73,7 +76,12 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info("-------- Starting deployment Registry Admin ----------------"); - const { address: registryAdminAddress, contract: registryAdminBaseContract } = await deployContract( + const { + address: registryAdminAddress, + contract: registryAdminBaseContract, + deploymentTransaction: registryAdminDeploymentTransaction + } = await deployContract( + "RegistryAdmin", "RegistryAdmin", owner, // GIF_ADMIN_ROLE [], @@ -85,10 +93,29 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr }); const registryAdmin = registryAdminBaseContract as RegistryAdmin; + const accessManagerAddress = await registryAdmin.authority(); + + await addDeployedContract( + "RegistryAccessManager", + "AccessManagerExtendedInitializeable", + accessManagerAddress, + owner, //signer + registryAdminDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + TimestampLib: libraries.timestampLibAddress, + } + }); logger.info("-------- Starting deployment Registry ----------------"); - const { address: registryAddress, contract: registryBaseContract } = await deployContract( + const { + address: registryAddress, + contract: registryBaseContract, + deploymentTransaction: registryDeploymentTransaction + } = await deployContract( + "Registry", "Registry", owner, // GIF_ADMIN_ROLE [registryAdminAddress], @@ -104,10 +131,23 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr const chainNftAddress = await registry.getChainNftAddress(); const chainNft = ChainNft__factory.connect(chainNftAddress, owner); - + + await addDeployedContract( + "ChainNft", + "ChainNft", + chainNftAddress, + owner, //signer + registryDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + logger.info("-------- Starting deployment Release Manager ----------------"); const { address: releaseManagerAddress, contract: releaseManagerBaseContract } = await deployContract( + "ReleaseManager", "ReleaseManager", owner, [registryAddress], @@ -127,6 +167,7 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info("-------- Starting deployment Token Registry ----------------"); const { address: tokenRegistryAddress, contract: tokenRegistryBaseContract } = await deployContract( + "TokenRegistry", "TokenRegistry", owner, [ @@ -144,6 +185,7 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info("-------- Starting deployment Staking Reader ----------------"); const { address: stakingReaderAddress, contract: stakingReaderBaseContract } = await deployContract( + "StakingReader", "StakingReader", owner, [registryAddress], @@ -158,6 +200,7 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info("-------- Starting deployment Staking Store ----------------"); const { address: stakingStoreAddress, } = await deployContract( + "StakingStore", "StakingStore", owner, [ @@ -182,6 +225,7 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info("-------- Starting deployment Staking Manager ----------------"); const { address: stakingManagerAddress, contract: stakingManagerBaseContract, } = await deployContract( + "StakingManager", "StakingManager", owner, [ @@ -202,17 +246,21 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr }); const stakingManager = stakingManagerBaseContract as StakingManager; + logger.info(`StakingManager deployed at ${stakingManagerAddress}`); const stakingAddress = await stakingManager.getStaking(); + logger.info(`Staking deployed at ${stakingAddress}`); const staking = Staking__factory.connect(stakingAddress, owner); - const stakingNftId = await registry["getNftId(address)"](stakingAddress); - await stakingReader.initialize(stakingAddress, stakingStoreAddress); + const stakingNftId = await registry["getNftId(address)"](stakingAddress); + logger.info(`StakingReader deployed at ${stakingReaderAddress}`); + // revert here if resumable deployment is true -> can be already intialized + await executeTx(async () => await stakingReader.initialize(stakingAddress, stakingStoreAddress)); - await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress); + await executeTx(async () => await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress)); - await registryAdmin.initialize(registry, owner, owner); + await executeTx(async () =>await registryAdmin.initialize(registry, owner, owner)); - await verifyRegistryComponents(registryAddress, owner) + //await verifyRegistryComponents(registryAddress, owner) logger.info(`Dip deployed at ${dipAddress}`); logger.info(`RegistryAdmin deployeqd at ${registryAdmin}`); @@ -225,6 +273,10 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr logger.info(`StakingManager deployed at ${stakingManagerAddress}`); logger.info(`Staking deployed at ${stakingAddress}`); + logger.info("protocol nftId: " + await registry._protocolNftId()); + logger.info("registry nftId: " + await registry._registryNftId()); + logger.info("staking nftId: " + await registry._stakingNftId()); + logger.info("======== Finished deployment of registry ========"); return { diff --git a/scripts/libs/services.ts b/scripts/libs/services.ts index 83f4e7997..49dfa72be 100644 --- a/scripts/libs/services.ts +++ b/scripts/libs/services.ts @@ -1,5 +1,6 @@ -import { AddressLike, BytesLike, Signer, resolveAddress, id } from "ethers"; +import { AddressLike, BytesLike, Signer, resolveAddress, id, TransactionResponse } from "ethers"; +import { tenderly } from "hardhat"; import { ReleaseManager__factory, DistributionService, DistributionServiceManager, DistributionService__factory, @@ -16,7 +17,7 @@ import { StakingService, StakingServiceManager, StakingService__factory } from "../../typechain-types"; import { logger } from "../logger"; -import { deployContract } from "./deployment"; +import { deployContract, addDeployedContract } from "./deployment"; import { LibraryAddresses } from "./libraries"; import { RegistryAddresses } from "./registry"; import { executeTx, getFieldFromTxRcptLogs } from "./transaction"; @@ -29,6 +30,11 @@ export type ServiceAddresses = { registryService: RegistryService, registryServiceManagerAddress: AddressLike, + stakingServiceNftId : string, + stakingServiceAddress: AddressLike, + stakingService: StakingService, + stakingServiceManagerAddress: AddressLike + instanceServiceNftId: string, instanceServiceAddress: AddressLike, instanceService: InstanceService, @@ -78,11 +84,6 @@ export type ServiceAddresses = { bundleServiceAddress: AddressLike, bundleService: BundleService, bundleServiceManagerAddress: AddressLike - - stakingServiceNftId : string, - stakingServiceAddress: AddressLike, - stakingService: StakingService, - stakingServiceManagerAddress: AddressLike } export async function deployAndRegisterServices(owner: Signer, registry: RegistryAddresses, libraries: LibraryAddresses): Promise @@ -96,8 +97,13 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info("======== Starting deployment of services ========"); const releaseManager = await registry.releaseManager.connect(owner); - logger.info("-------- regtistry service --------"); - const { address: registryServiceManagerAddress, contract: registryServiceManagerBaseContract } = await deployContract( + logger.info("-------- registry service --------"); + const { + address: registryServiceManagerAddress, + contract: registryServiceManagerBaseContract, + deploymentTransaction: registryServiceManagerDeploymentTransaction + } = await deployContract( + "RegistryServiceManager", "RegistryServiceManager", owner, [ @@ -114,19 +120,51 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const registryServiceManager = registryServiceManagerBaseContract as RegistryServiceManager; const registryServiceAddress = await registryServiceManager.getRegistryService(); + const registryServiceImplementationAddress = await registryServiceManager.getImplementation(); const registryService = RegistryService__factory.connect(registryServiceAddress, owner); + logger.info("Verifying registry service implementation"); + // TODO + await addDeployedContract( + "RegistryService", + "RegistryService", + registryServiceImplementationAddress, + owner, //signer + registryServiceManagerDeploymentTransaction as TransactionResponse,// deploymentTransaction, + [],// constructor args + { + libraries: { + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying registry service proxy"); + await addDeployedContract( + "RegistryServiceProxy", + "UpgradableProxyWithAdmin", + registryServiceAddress, + owner, //signer + registryServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptRs = await executeTx(async () => await releaseManager.registerService(registryServiceAddress)); const logRegistrationInfoRs = getFieldFromTxRcptLogs(rcptRs!, registry.registry.interface, "LogRegistration", "nftId"); const registryServiceNfdId = (logRegistrationInfoRs as unknown); - - // is not NftOwnable - //await registry.tokenRegistry.linkToRegistryService(); - logger.info(`registryServiceManager deployed - registryServiceAddress: ${registryServiceAddress} registryServiceManagerAddress: ${registryServiceManagerAddress} nftId: ${registryServiceNfdId}`); logger.info("-------- staking service --------"); - const { address: stakingServiceManagerAddress, contract: stakingServiceManagerBaseContract, } = await deployContract( + const { + address: stakingServiceManagerAddress, + contract: stakingServiceManagerBaseContract, + deploymentTransaction: stakingServiceManagerDeploymentTransaction + } = await deployContract( + "StakingServiceManager", "StakingServiceManager", owner, [ @@ -145,8 +183,53 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const stakingServiceManager = stakingServiceManagerBaseContract as StakingServiceManager; const stakingServiceAddress = await stakingServiceManager.getStakingService(); + const stakingServiceImplementationAddress = await stakingServiceManager.getImplementation(); const stakingService = StakingService__factory.connect(stakingServiceAddress, owner); + logger.info("Verifying staking service implementation"); + /* + await deployContract( + "StakingService", + owner, + [], + { libraries: { + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + StakeManagerLib: libraries.stakeManagerLibAddress, + TargetManagerLib: libraries.targetManagerLibAddress, + }}); + */ + await addDeployedContract( + "StakingService", + "StakingService", + stakingServiceImplementationAddress, + owner, //signer + stakingServiceManagerDeploymentTransaction as TransactionResponse,// deploymentTransaction, + [],// constructor args + { + libraries: { + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + StakeManagerLib: libraries.stakeManagerLibAddress, + TargetManagerLib: libraries.targetManagerLibAddress, + } + }); + + logger.info("Verifying staking service proxy"); + await addDeployedContract( + "StakingServiceProxy", + "UpgradableProxyWithAdmin", + stakingServiceAddress, + owner, //signer + stakingServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptStk = await executeTx(async () => await releaseManager.registerService(stakingServiceAddress)); const logRegistrationInfoStk = getFieldFromTxRcptLogs(rcptStk!, registry.registry.interface, "LogRegistration", "nftId"); const stakingServiceNftId = (logRegistrationInfoStk as unknown); @@ -154,7 +237,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`stakingServiceManager deployed - stakingServiceAddress: ${stakingServiceAddress} stakingServiceManagerAddress: ${stakingServiceManagerAddress} nftId: ${stakingServiceNftId}`); logger.info("-------- instance service --------"); - const { address: instanceServiceManagerAddress, contract: instanceServiceManagerBaseContract, } = await deployContract( + const { + address: instanceServiceManagerAddress, + contract: instanceServiceManagerBaseContract, + deploymentTransaction: instanceServiceManagerDeploymentTransaction + } = await deployContract( + "InstanceServiceManager", "InstanceServiceManager", owner, [ @@ -174,8 +262,55 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const instanceServiceManager = instanceServiceManagerBaseContract as InstanceServiceManager; const instanceServiceAddress = await instanceServiceManager.getInstanceService(); + const instanceServiceImplementationAddress = await instanceServiceManager.getImplementation(); const instanceService = InstanceService__factory.connect(instanceServiceAddress, owner); + logger.info("Verifying instance service implementation"); + /* + await deployContract( + "InstanceService", + owner, + [], + { libraries: { + NftIdLib: libraries.nftIdLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + InstanceAuthorizationsLib: libraries.instanceAuthorizationsLibAddress, + TargetManagerLib: libraries.targetManagerLibAddress, + }}); + */ + await addDeployedContract( + "InstanceService", + "InstanceService", + instanceServiceImplementationAddress, + owner, //signer + instanceServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + NftIdLib: libraries.nftIdLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + InstanceAuthorizationsLib: libraries.instanceAuthorizationsLibAddress, + TargetManagerLib: libraries.targetManagerLibAddress, + } + }); + + logger.info("Verifying instance service proxy"); + await addDeployedContract( + "InstanceServiceProxy", + "UpgradableProxyWithAdmin", + instanceServiceAddress, + owner, //signer + instanceServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptInst = await executeTx(async () => await releaseManager.registerService(instanceServiceAddress)); const logRegistrationInfoInst = getFieldFromTxRcptLogs(rcptInst!, registry.registry.interface, "LogRegistration", "nftId"); const instanceServiceNfdId = (logRegistrationInfoInst as unknown); @@ -183,7 +318,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`instanceServiceManager deployed - instanceServiceAddress: ${instanceServiceAddress} instanceServiceManagerAddress: ${instanceServiceManagerAddress} nftId: ${instanceServiceNfdId}`); logger.info("-------- component service --------"); - const { address: componentServiceManagerAddress, contract: componentServiceManagerBaseContract, } = await deployContract( + const { + address: componentServiceManagerAddress, + contract: componentServiceManagerBaseContract, + deploymentTransaction: componentServiceManagerDeploymentTransaction + } = await deployContract( + "ComponentServiceManager", "ComponentServiceManager", owner, [registry.registryAddress], @@ -199,15 +339,66 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const componentServiceManager = componentServiceManagerBaseContract as ComponentServiceManager; const componentServiceAddress = await componentServiceManager.getComponentService(); + const componentServiceImplementationAddress = await componentServiceManager.getImplementation(); const componentService = ComponentService__factory.connect(componentServiceAddress, owner); + logger.info("Verifying component service implementation"); + /*await deployContract( + "ComponentService", + owner, + [], + { libraries: { + NftIdLib: libraries.nftIdLibAddress, + AmountLib: libraries.amountLibAddress, + FeeLib: libraries.feeLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }});*/ + await addDeployedContract( + "ComponentService", + "ComponentService", + componentServiceImplementationAddress, + owner, //signer + componentServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + NftIdLib: libraries.nftIdLibAddress, + AmountLib: libraries.amountLibAddress, + FeeLib: libraries.feeLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying component service proxy"); + await addDeployedContract( + "ComponentServiceProxy", + "UpgradableProxyWithAdmin", + componentServiceAddress, + owner, //signer + componentServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + + const rcptCmpt = await executeTx(async () => await releaseManager.registerService(componentServiceAddress)); const logRegistrationInfoCmpt = getFieldFromTxRcptLogs(rcptCmpt!, registry.registry.interface, "LogRegistration", "nftId"); const componentServiceNftId = (logRegistrationInfoCmpt as unknown); logger.info(`componentServiceManager deployed - componentServiceAddress: ${componentServiceAddress} componentServiceManagerAddress: ${componentServiceManagerAddress} nftId: ${componentServiceNftId}`); logger.info("-------- distribution service --------"); - const { address: distributionServiceManagerAddress, contract: distributionServiceManagerBaseContract, } = await deployContract( + const { + address: distributionServiceManagerAddress, + contract: distributionServiceManagerBaseContract, + deploymentTransaction: distributionServiceManagerDeploymentTransaction + } = await deployContract( + "DistributionServiceManager", "DistributionServiceManager", owner, [ @@ -228,8 +419,59 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const distributionServiceManager = distributionServiceManagerBaseContract as DistributionServiceManager; const distributionServiceAddress = await distributionServiceManager.getDistributionService(); + const distributionServiceImplementationAddress = await distributionServiceManager.getImplementation(); const distributionService = DistributionService__factory.connect(distributionServiceAddress, owner); + logger.info("Verifying distribution service implementation"); + /* + await deployContract( + "DistributionService", + owner, + [], + { libraries: { + AmountLib: libraries.amountLibAddress, + DistributorTypeLib: libraries.distributorTypeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + ReferralLib: libraries.referralLibAddress, + TimestampLib: libraries.timestampLibAddress, + UFixedLib: libraries.uFixedLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "DistributionService", + "DistributionService", + distributionServiceImplementationAddress, + owner, //signer + distributionServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + AmountLib: libraries.amountLibAddress, + DistributorTypeLib: libraries.distributorTypeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + ReferralLib: libraries.referralLibAddress, + TimestampLib: libraries.timestampLibAddress, + UFixedLib: libraries.uFixedLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying distribution service proxy"); + await addDeployedContract( + "DistributionServiceProxy", + "UpgradableProxyWithAdmin", + distributionServiceAddress, + owner, //signer + distributionServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptDs = await executeTx(async () => await releaseManager.registerService(distributionServiceAddress)); const logRegistrationInfoDs = getFieldFromTxRcptLogs(rcptDs!, registry.registry.interface, "LogRegistration", "nftId"); const distributionServiceNftId = (logRegistrationInfoDs as unknown); @@ -237,7 +479,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`distributionServiceManager deployed - distributionServiceAddress: ${distributionServiceAddress} distributionServiceManagerAddress: ${distributionServiceManagerAddress} nftId: ${distributionServiceNftId}`); logger.info("-------- pricing service --------"); - const { address: pricingServiceManagerAddress, contract: pricingServiceManagerBaseContract, } = await deployContract( + const { + address: pricingServiceManagerAddress, + contract: pricingServiceManagerBaseContract, + deploymentTransaction: pricingServiceManagerDeploymentTransaction + } = await deployContract( + "PricingServiceManager", "PricingServiceManager", owner, [ @@ -256,8 +503,53 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const pricingServiceManager = pricingServiceManagerBaseContract as PricingServiceManager; const pricingServiceAddress = await pricingServiceManager.getPricingService(); + const pricingServiceImplementationAddress = await pricingServiceManager.getImplementation(); const pricingService = PricingService__factory.connect(pricingServiceAddress, owner); + logger.info("Verifying pricing service implementation"); + /* + await deployContract( + "PricingService", + owner, + [], + { libraries: { + NftIdLib: libraries.nftIdLibAddress, + AmountLib: libraries.amountLibAddress, + UFixedLib: libraries.uFixedLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "PricingService", + "PricingService", + pricingServiceImplementationAddress, + owner, //signer + pricingServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + NftIdLib: libraries.nftIdLibAddress, + AmountLib: libraries.amountLibAddress, + UFixedLib: libraries.uFixedLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying pricing service proxy"); + await addDeployedContract( + "PricingServiceProxy", + "UpgradableProxyWithAdmin", + pricingServiceAddress, + owner, //signer + pricingServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptPrs = await executeTx(async () => await releaseManager.registerService(pricingServiceAddress)); const logRegistrationInfoPrs = getFieldFromTxRcptLogs(rcptPrs!, registry.registry.interface, "LogRegistration", "nftId"); const pricingServiceNftId = (logRegistrationInfoPrs as unknown); @@ -265,7 +557,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`pricingServiceManager deployed - pricingServiceAddress: ${pricingServiceAddress} pricingServiceManagerAddress: ${pricingServiceManagerAddress} nftId: ${pricingServiceNftId}`); logger.info("-------- bundle service --------"); - const { address: bundleServiceManagerAddress, contract: bundleServiceManagerBaseContract, } = await deployContract( + const { + address: bundleServiceManagerAddress, + contract: bundleServiceManagerBaseContract, + deploymentTransaction: bundleServiceManagerDeploymentTransaction + } = await deployContract( + "BundleServiceManager", "BundleServiceManager", owner, [ @@ -283,8 +580,53 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const bundleServiceManager = bundleServiceManagerBaseContract as BundleServiceManager; const bundleServiceAddress = await bundleServiceManager.getBundleService(); + const bundleServiceImplementationAddress = await bundleServiceManager.getImplementation(); const bundleService = BundleService__factory.connect(bundleServiceAddress, owner); + logger.info("Verifying bundle service implementation"); + /* + await deployContract( + "BundleService", + owner, + [], + { libraries: { + AmountLib: libraries.amountLibAddress, + NftIdLib: libraries.nftIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "BundleService", + "BundleService", + bundleServiceImplementationAddress, + owner, //signer + bundleServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + AmountLib: libraries.amountLibAddress, + NftIdLib: libraries.nftIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying bundle service proxy"); + await addDeployedContract( + "BundleServiceProxy", + "UpgradableProxyWithAdmin", + bundleServiceAddress, + owner, //signer + bundleServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptBdl = await executeTx(async () => await releaseManager.registerService(bundleServiceAddress)); const logRegistrationInfoBdl = getFieldFromTxRcptLogs(rcptBdl!, registry.registry.interface, "LogRegistration", "nftId"); const bundleServiceNftId = (logRegistrationInfoBdl as unknown); @@ -292,7 +634,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`bundleServiceManager deployed - bundleServiceAddress: ${bundleServiceAddress} bundleServiceManagerAddress: ${bundleServiceManagerAddress} nftId: ${bundleServiceNftId}`); logger.info("-------- pool service --------"); - const { address: poolServiceManagerAddress, contract: poolServiceManagerBaseContract, } = await deployContract( + const { + address: poolServiceManagerAddress, + contract: poolServiceManagerBaseContract, + deploymentTransaction: poolServiceManagerDeploymentTransaction + } = await deployContract( + "PoolServiceManager", "PoolServiceManager", owner, [ @@ -312,8 +659,55 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const poolServiceManager = poolServiceManagerBaseContract as PoolServiceManager; const poolServiceAddress = await poolServiceManager.getPoolService(); + const poolServiceImplementationAddress = await poolServiceManager.getImplementation(); const poolService = PoolService__factory.connect(poolServiceAddress, owner); + logger.info("Verifying pool service implementation"); + /* + await deployContract( + "PoolService", + owner, + [], + { libraries: { + AmountLib: libraries.amountLibAddress, + FeeLib: libraries.feeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "PoolService", + "PoolService", + poolServiceImplementationAddress, + owner, //signer + poolServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + AmountLib: libraries.amountLibAddress, + FeeLib: libraries.feeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + RoleIdLib: libraries.roleIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying pool service proxy"); + await addDeployedContract( + "PoolServiceProxy", + "UpgradableProxyWithAdmin", + poolServiceAddress, + owner, //signer + poolServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptPs = await executeTx(async () => await releaseManager.registerService(poolServiceAddress)); const logRegistrationInfoPs = getFieldFromTxRcptLogs(rcptPs!, registry.registry.interface, "LogRegistration", "nftId"); const poolServiceNftId = (logRegistrationInfoPs as unknown); @@ -321,7 +715,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`poolServiceManager deployed - poolServiceAddress: ${poolServiceAddress} poolServiceManagerAddress: ${poolServiceManagerAddress} nftId: ${poolServiceNftId}`); logger.info("-------- product service --------"); - const { address: productServiceManagerAddress, contract: productServiceManagerBaseContract, } = await deployContract( + const { + address: productServiceManagerAddress, + contract: productServiceManagerBaseContract, + deploymentTransaction: productServiceManagerDeploymentTransaction + } = await deployContract( + "ProductServiceManager", "ProductServiceManager", owner, [ @@ -338,8 +737,49 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const productServiceManager = productServiceManagerBaseContract as ProductServiceManager; const productServiceAddress = await productServiceManager.getProductService(); + const productServiceImplementationAddress = await productServiceManager.getImplementation(); const productService = ProductService__factory.connect(productServiceAddress, owner); + logger.info("Verifying product service implementation"); + /* + await deployContract( + "ProductService", + owner, + [], + { libraries: { + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "ProductService", + "ProductService", + productServiceImplementationAddress, + owner, //signer + productServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying product service proxy"); + await addDeployedContract( + "ProductServiceProxy", + "UpgradableProxyWithAdmin", + productServiceAddress, + owner, //signer + productServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptPrd = await executeTx(async () => await releaseManager.registerService(productServiceAddress)); const logRegistrationInfoPrd = getFieldFromTxRcptLogs(rcptPrd!, registry.registry.interface, "LogRegistration", "nftId"); const productServiceNftId = (logRegistrationInfoPrd as unknown); @@ -347,7 +787,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`productServiceManager deployed - productServiceAddress: ${productServiceAddress} productServiceManagerAddress: ${productServiceManagerAddress} nftId: ${productServiceNftId}`); logger.info("-------- claim service --------"); - const { address: claimServiceManagerAddress, contract: claimServiceManagerBaseContract, } = await deployContract( + const { + address: claimServiceManagerAddress, + contract: claimServiceManagerBaseContract, + deploymentTransaction: claimServiceManagerDeploymentTransaction + } = await deployContract( + "ClaimServiceManager", "ClaimServiceManager", owner, [ @@ -368,8 +813,59 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const claimServiceManager = claimServiceManagerBaseContract as ClaimServiceManager; const claimServiceAddress = await claimServiceManager.getClaimService(); + const claimServiceImplementationAddress = await claimServiceManager.getImplementation(); const claimService = ClaimService__factory.connect(claimServiceAddress, owner); + logger.info("Verifying claim service implementation"); + /* + await deployContract( + "ClaimService", + owner, + [], + { libraries: { + AmountLib: libraries.amountLibAddress, + ClaimIdLib: libraries.claimIdLibAddress, + FeeLib: libraries.feeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + PayoutIdLib: libraries.payoutIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "ClaimService", + "ClaimService", + claimServiceImplementationAddress, + owner, //signer + claimServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + AmountLib: libraries.amountLibAddress, + ClaimIdLib: libraries.claimIdLibAddress, + FeeLib: libraries.feeLibAddress, + NftIdLib: libraries.nftIdLibAddress, + PayoutIdLib: libraries.payoutIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying claim service proxy"); + await addDeployedContract( + "ClaimServiceProxy", + "UpgradableProxyWithAdmin", + claimServiceAddress, + owner, //signer + claimServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptClm = await executeTx(async () => await releaseManager.registerService(claimServiceAddress)); const logRegistrationInfoClm = getFieldFromTxRcptLogs(rcptClm!, registry.registry.interface, "LogRegistration", "nftId"); const claimServiceNftId = (logRegistrationInfoClm as unknown); @@ -377,7 +873,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`claimServiceManager deployed - claimServiceAddress: ${claimServiceAddress} claimServiceManagerAddress: ${claimServiceManagerAddress} nftId: ${claimServiceNftId}`); logger.info("-------- application service --------"); - const { address: applicationServiceManagerAddress, contract: applicationServiceManagerBaseContract, } = await deployContract( + const { + address: applicationServiceManagerAddress, + contract: applicationServiceManagerBaseContract, + deploymentTransaction: applicationServiceManagerDeploymentTransaction + } = await deployContract( + "ApplicationServiceManager", "ApplicationServiceManager", owner, [ @@ -395,8 +896,51 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const applicationServiceManager = applicationServiceManagerBaseContract as ApplicationServiceManager; const applicationServiceAddress = await applicationServiceManager.getApplicationService(); + const applicationServiceImplementationAddress = await applicationServiceManager.getImplementation(); const applicationService = ApplicationService__factory.connect(applicationServiceAddress, owner); + logger.info("Verifying application service implementation"); + /* + await deployContract( + "ApplicationService", + owner, + [], + { libraries: { + AmountLib: libraries.amountLibAddress, + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "ApplicationService", + "ApplicationService", + applicationServiceImplementationAddress, + owner, //signer + applicationServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + AmountLib: libraries.amountLibAddress, + NftIdLib: libraries.nftIdLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying application service proxy"); + await addDeployedContract( + "ApplicationServiceProxy", + "UpgradableProxyWithAdmin", + applicationServiceAddress, + owner, //signer + applicationServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptAppl = await executeTx(async () => await releaseManager.registerService(applicationServiceAddress)); const logRegistrationInfoAppl = getFieldFromTxRcptLogs(rcptAppl!, registry.registry.interface, "LogRegistration", "nftId"); const applicationServiceNftId = (logRegistrationInfoAppl as unknown); @@ -404,7 +948,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr logger.info(`applicationServiceManager deployed - applicationServiceAddress: ${applicationServiceAddress} policyServiceManagerAddress: ${applicationServiceManagerAddress} nftId: ${applicationServiceNftId}`); logger.info("-------- policy service --------"); - const { address: policyServiceManagerAddress, contract: policyServiceManagerBaseContract, } = await deployContract( + const { + address: policyServiceManagerAddress, + contract: policyServiceManagerBaseContract, + deploymentTransaction: policyServiceManagerDeploymentTransaction + } = await deployContract( + "PolicyServiceManager", "PolicyServiceManager", owner, [ @@ -422,8 +971,53 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const policyServiceManager = policyServiceManagerBaseContract as PolicyServiceManager; const policyServiceAddress = await policyServiceManager.getPolicyService(); + const policyServiceImplementationAddress = await policyServiceManager.getImplementation(); const policyService = PolicyService__factory.connect(policyServiceAddress, owner); + logger.info("Verifying policy service implementation"); + /* + await deployContract( + "PolicyService", + owner, + [], + { libraries: { + AmountLib: libraries.amountLibAddress, + NftIdLib: libraries.nftIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + }}); + */ + await addDeployedContract( + "PolicyService", + "PolicyService", + policyServiceImplementationAddress, + owner, //signer + policyServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + AmountLib: libraries.amountLibAddress, + NftIdLib: libraries.nftIdLibAddress, + TimestampLib: libraries.timestampLibAddress, + VersionLib: libraries.versionLibAddress, + VersionPartLib: libraries.versionPartLibAddress, + } + }); + + logger.info("Verifying policy service proxy"); + await addDeployedContract( + "PolicyServiceProxy", + "UpgradableProxyWithAdmin", + policyServiceAddress, + owner, //signer + policyServiceManagerDeploymentTransaction as TransactionResponse, + [],// constructor args + { + libraries: { + } + }); + const rcptPol = await executeTx(async () => await releaseManager.registerService(policyServiceAddress)); const logRegistrationInfoPol = getFieldFromTxRcptLogs(rcptPol!, registry.registry.interface, "LogRegistration", "nftId"); const policyServiceNftId = (logRegistrationInfoPol as unknown); @@ -442,6 +1036,11 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr registryService: registryService, registryServiceManagerAddress: registryServiceManagerAddress, + stakingServiceNftId: stakingServiceNftId as string, + stakingServiceAddress: stakingServiceAddress, + stakingService: stakingService, + stakingServiceManagerAddress: stakingServiceManagerAddress, + instanceServiceNftId: instanceServiceNfdId as string, instanceServiceAddress: instanceServiceAddress, instanceService: instanceService, @@ -491,10 +1090,5 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr bundleServiceAddress: bundleServiceAddress, bundleService: bundleService, bundleServiceManagerAddress: bundleServiceManagerAddress, - - stakingServiceNftId: stakingServiceNftId as string, - stakingServiceAddress: stakingServiceAddress, - stakingService: stakingService, - stakingServiceManagerAddress: stakingServiceManagerAddress }; } \ No newline at end of file From 0723d8a2f607315148b3ce8d23666c11b864ee99 Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:32:21 +0000 Subject: [PATCH 3/9] add master instance getters --- contracts/instance/IInstanceService.sol | 7 ++ contracts/instance/InstanceService.sol | 131 +++++++++++++----------- 2 files changed, 80 insertions(+), 58 deletions(-) diff --git a/contracts/instance/IInstanceService.sol b/contracts/instance/IInstanceService.sol index de155245f..b5f25b87a 100644 --- a/contracts/instance/IInstanceService.sol +++ b/contracts/instance/IInstanceService.sol @@ -78,4 +78,11 @@ interface IInstanceService is IService { ) external; function setComponentLocked(bool locked) external; + + + function getMasterInstanceAddress() external view returns (address); + function getMasterInstanceAdminAddress() external view returns (address); + function getMasterInstanceReaderAddress() external view returns (address); + function getMasterBundleManagerAddress() external view returns (address); + function getMasterInstanceStoreAddress() external view returns (address); } \ No newline at end of file diff --git a/contracts/instance/InstanceService.sol b/contracts/instance/InstanceService.sol index 367976ce5..411d998a3 100644 --- a/contracts/instance/InstanceService.sol +++ b/contracts/instance/InstanceService.sol @@ -39,7 +39,6 @@ contract InstanceService is Service, IInstanceService { - // TODO update to real hash when instance is stable bytes32 public constant INSTANCE_CREATION_CODE_HASH = bytes32(0); @@ -68,6 +67,51 @@ contract InstanceService is _; } + function setAndRegisterMasterInstance(address instanceAddress) + external + onlyOwner + returns(NftId masterInstanceNftId) + { + if(_masterInstance != address(0)) { revert ErrorInstanceServiceMasterInstanceAlreadySet(); } + if(_masterAccessManager != address(0)) { revert ErrorInstanceServiceMasterInstanceAccessManagerAlreadySet(); } + if(_masterInstanceAdmin != address(0)) { revert ErrorInstanceServiceMasterInstanceAdminAlreadySet(); } + if(_masterInstanceBundleManager != address(0)) { revert ErrorInstanceServiceMasterBundleManagerAlreadySet(); } + + if(instanceAddress == address(0)) { revert ErrorInstanceServiceInstanceAddressZero(); } + + IInstance instance = IInstance(instanceAddress); + InstanceAdmin instanceAdmin = instance.getInstanceAdmin(); + address instanceAdminAddress = address(instanceAdmin); + InstanceReader instanceReader = instance.getInstanceReader(); + address instanceReaderAddress = address(instanceReader); + BundleManager bundleManager = instance.getBundleManager(); + address bundleManagerAddress = address(bundleManager); + InstanceStore instanceStore = instance.getInstanceStore(); + address instanceStoreAddress = address(instanceStore); + + if(instanceAdminAddress == address(0)) { revert ErrorInstanceServiceInstanceAdminZero(); } + if(instanceReaderAddress == address(0)) { revert ErrorInstanceServiceInstanceReaderZero(); } + if(bundleManagerAddress == address(0)) { revert ErrorInstanceServiceBundleManagerZero(); } + if(instanceStoreAddress == address(0)) { revert ErrorInstanceServiceInstanceStoreZero(); } + + if(instance.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceAuthorityMismatch(); } + if(bundleManager.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceBundleManagerAuthorityMismatch(); } + if(instanceStore.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceStoreAuthorityMismatch(); } + if(bundleManager.getInstance() != instance) { revert ErrorInstanceServiceBundleMangerInstanceMismatch(); } + if(instanceReader.getInstance() != instance) { revert ErrorInstanceServiceInstanceReaderInstanceMismatch2(); } + + _masterAccessManager = instance.authority(); + _masterInstanceAdmin = instanceAdminAddress; + _masterInstance = instanceAddress; + _masterInstanceReader = instanceReaderAddress; + _masterInstanceBundleManager = bundleManagerAddress; + _masterInstanceStore = instanceStoreAddress; + + IInstance masterInstance = IInstance(_masterInstance); + IRegistry.ObjectInfo memory info = _registryService.registerInstance(masterInstance, getOwner()); + masterInstanceNftId = info.nftId; + } + function createInstanceClone() external returns ( @@ -167,61 +211,6 @@ contract InstanceService is locked); } - - function getMasterInstanceReader() external view returns (address) { - return _masterInstanceReader; - } - - // From IService - function getDomain() public pure override returns(ObjectType) { - return INSTANCE(); - } - - function setAndRegisterMasterInstance(address instanceAddress) - external - onlyOwner - returns(NftId masterInstanceNftId) - { - if(_masterInstance != address(0)) { revert ErrorInstanceServiceMasterInstanceAlreadySet(); } - if(_masterAccessManager != address(0)) { revert ErrorInstanceServiceMasterInstanceAccessManagerAlreadySet(); } - if(_masterInstanceAdmin != address(0)) { revert ErrorInstanceServiceMasterInstanceAdminAlreadySet(); } - if(_masterInstanceBundleManager != address(0)) { revert ErrorInstanceServiceMasterBundleManagerAlreadySet(); } - - if(instanceAddress == address(0)) { revert ErrorInstanceServiceInstanceAddressZero(); } - - IInstance instance = IInstance(instanceAddress); - InstanceAdmin instanceAdmin = instance.getInstanceAdmin(); - address instanceAdminAddress = address(instanceAdmin); - InstanceReader instanceReader = instance.getInstanceReader(); - address instanceReaderAddress = address(instanceReader); - BundleManager bundleManager = instance.getBundleManager(); - address bundleManagerAddress = address(bundleManager); - InstanceStore instanceStore = instance.getInstanceStore(); - address instanceStoreAddress = address(instanceStore); - - if(instanceAdminAddress == address(0)) { revert ErrorInstanceServiceInstanceAdminZero(); } - if(instanceReaderAddress == address(0)) { revert ErrorInstanceServiceInstanceReaderZero(); } - if(bundleManagerAddress == address(0)) { revert ErrorInstanceServiceBundleManagerZero(); } - if(instanceStoreAddress == address(0)) { revert ErrorInstanceServiceInstanceStoreZero(); } - - if(instance.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceAuthorityMismatch(); } - if(bundleManager.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceBundleManagerAuthorityMismatch(); } - if(instanceStore.authority() != instanceAdmin.authority()) { revert ErrorInstanceServiceInstanceStoreAuthorityMismatch(); } - if(bundleManager.getInstance() != instance) { revert ErrorInstanceServiceBundleMangerInstanceMismatch(); } - if(instanceReader.getInstance() != instance) { revert ErrorInstanceServiceInstanceReaderInstanceMismatch2(); } - - _masterAccessManager = instance.authority(); - _masterInstanceAdmin = instanceAdminAddress; - _masterInstance = instanceAddress; - _masterInstanceReader = instanceReaderAddress; - _masterInstanceBundleManager = bundleManagerAddress; - _masterInstanceStore = instanceStoreAddress; - - IInstance masterInstance = IInstance(_masterInstance); - IRegistry.ObjectInfo memory info = _registryService.registerInstance(masterInstance, getOwner()); - masterInstanceNftId = info.nftId; - } - function upgradeMasterInstanceReader(address instanceReaderAddress) external onlyOwner { if(_masterInstanceReader == address(0)) { revert ErrorInstanceServiceMasterInstanceReaderNotSet(); } if(instanceReaderAddress == address(0)) { revert ErrorInstanceServiceInstanceReaderAddressZero(); } @@ -246,7 +235,6 @@ contract InstanceService is instance.setInstanceReader(upgradedInstanceReaderClone); } - function createGifTarget( NftId instanceNftId, address targetAddress, @@ -267,7 +255,6 @@ contract InstanceService is ); } - function createComponentTarget( NftId instanceNftId, address targetAddress, @@ -288,6 +275,34 @@ contract InstanceService is ); } + function getMasterInstanceAddress() external view returns (address) { + return _masterInstance; + } + + function getMasterInstanceAdminAddress() external view returns (address) { + return _masterInstanceAdmin; + } + + function getMasterBundleManagerAddress() external view returns (address) { + return _masterInstanceBundleManager; + } + + function getMasterInstanceStoreAddress() external view returns (address) { + return _masterInstanceStore; + } + + function getMasterInstanceReaderAddress() external view returns (address) { + return _masterInstanceReader; + } + + // From IService + + function getDomain() public pure override returns(ObjectType) { + return INSTANCE(); + } + + // ----------- internal functions ------------- + /// all gif targets MUST be children of instanceNftId function _createGifTarget( From a26128e170d133319460dbbf197cac8de2191de3 Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:33:47 +0000 Subject: [PATCH 4/9] cleanup access manager --- contracts/shared/AccessManagerCustom.sol | 53 +++++++++---------- contracts/shared/AccessManagerExtended.sol | 49 +++++++++-------- .../AccessManagerExtendedWithDisable.sol | 4 +- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/contracts/shared/AccessManagerCustom.sol b/contracts/shared/AccessManagerCustom.sol index a68ebb87c..f773650bc 100644 --- a/contracts/shared/AccessManagerCustom.sol +++ b/contracts/shared/AccessManagerCustom.sol @@ -59,8 +59,8 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult uint64 public constant ADMIN_ROLE = type(uint64).min; // 0 uint64 public constant PUBLIC_ROLE = type(uint64).max; // 2**64-1 - /// @custom:storage-location erc7201:openzeppelin.storage.AccessManagerCustom - struct AccessManagerStorage { + /// @custom:storage-location erc7201:etherisc.storage.AccessManagerCustom + struct AccessManagerCustomStorage { mapping(address target => TargetConfig mode) _targets; mapping(uint64 roleId => Role) _roles; mapping(bytes32 operationId => Schedule) _schedules; @@ -70,11 +70,10 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult bytes32 _executionId; } - // TODO compute address // keccak256(abi.encode(uint256(keccak256("etherisc.storage.AccessManagerCustom")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant AccessManagerCustomStorageLocation = 0x77301bc69e8248c80abb894217605b71fa89ea6a9e8bdf359d9e8aa1dd62bf00; - function _getAccessManagerCustomStorage() private pure returns (AccessManagerStorage storage $) { + function _getAccessManagerCustomStorage() private pure returns (AccessManagerCustomStorage storage $) { assembly { $.slot := AccessManagerCustomStorageLocation } @@ -134,37 +133,37 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult /// @inheritdoc IAccessManager function isTargetClosed(address target) public view virtual returns (bool) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._targets[target].closed; } /// @inheritdoc IAccessManager function getTargetFunctionRole(address target, bytes4 selector) public view virtual returns (uint64) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._targets[target].allowedRoles[selector]; } /// @inheritdoc IAccessManager function getTargetAdminDelay(address target) public view virtual returns (uint32) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._targets[target].adminDelay.get(); } /// @inheritdoc IAccessManager function getRoleAdmin(uint64 roleId) public view virtual returns (uint64) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._roles[roleId].admin; } /// @inheritdoc IAccessManager function getRoleGuardian(uint64 roleId) public view virtual returns (uint64) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._roles[roleId].guardian; } /// @inheritdoc IAccessManager function getRoleGrantDelay(uint64 roleId) public view virtual returns (uint32) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._roles[roleId].grantDelay.get(); } @@ -173,7 +172,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult uint64 roleId, address account ) public view virtual returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); Access storage access = $._roles[roleId].members[account]; since = access.since; @@ -248,7 +247,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult uint32 grantDelay, uint32 executionDelay ) internal virtual returns (bool) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); if (roleId == PUBLIC_ROLE) { revert AccessManagerLockedRole(roleId); } @@ -279,7 +278,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * Emits a {RoleRevoked} event if the account had the role. */ function _revokeRole(uint64 roleId, address account) internal virtual returns (bool) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); if (roleId == PUBLIC_ROLE) { revert AccessManagerLockedRole(roleId); } @@ -303,7 +302,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * anyone to set grant or revoke such role. */ function _setRoleAdmin(uint64 roleId, uint64 admin) internal virtual { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) { revert AccessManagerLockedRole(roleId); } @@ -322,7 +321,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * anyone to cancel any scheduled operation for such role. */ function _setRoleGuardian(uint64 roleId, uint64 guardian) internal virtual { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) { revert AccessManagerLockedRole(roleId); } @@ -338,7 +337,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * Emits a {RoleGrantDelayChanged} event. */ function _setGrantDelay(uint64 roleId, uint32 newDelay) internal virtual { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); if (roleId == PUBLIC_ROLE) { revert AccessManagerLockedRole(roleId); } @@ -367,7 +366,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * Emits a {TargetFunctionRoleUpdated} event. */ function _setTargetFunctionRole(address target, bytes4 selector, uint64 roleId) internal virtual { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); $._targets[target].allowedRoles[selector] = roleId; emit TargetFunctionRoleUpdated(target, selector, roleId); } @@ -383,7 +382,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * Emits a {TargetAdminDelayUpdated} event. */ function _setTargetAdminDelay(address target, uint32 newDelay) internal virtual { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); uint48 effect; ($._targets[target].adminDelay, effect) = $._targets[target].adminDelay.withUpdate(newDelay, minSetback()); emit TargetAdminDelayUpdated(target, newDelay, effect); @@ -401,7 +400,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * Emits a {TargetClosed} event. */ function _setTargetClosed(address target, bool closed) internal virtual { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); if (target == address(this)) { revert AccessManagerLockedAccount(target); } @@ -412,14 +411,14 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult // ============================================== DELAYED OPERATIONS ============================================== /// @inheritdoc IAccessManager function getSchedule(bytes32 id) public view virtual returns (uint48) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); uint48 timepoint = $._schedules[id].timepoint; return _isExpired(timepoint) ? 0 : timepoint; } /// @inheritdoc IAccessManager function getNonce(bytes32 id) public view virtual returns (uint32) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._schedules[id].nonce; } @@ -429,7 +428,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult bytes calldata data, uint48 when ) public virtual returns (bytes32 operationId, uint32 nonce) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); address caller = _msgSender(); // Fetch restrictions that apply to the caller on the targeted function @@ -466,7 +465,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * (Note: This function was introduced due to stack too deep errors in schedule.) */ function _checkNotScheduled(bytes32 operationId) private view { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); uint48 prevTimepoint = $._schedules[operationId].timepoint; if (prevTimepoint != 0 && !_isExpired(prevTimepoint)) { revert AccessManagerAlreadyScheduled(operationId); @@ -478,7 +477,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult // _consumeScheduledOp guarantees a scheduled operation is only executed once. // slither-disable-next-line reentrancy-no-eth function execute(address target, bytes calldata data) public payable virtual returns (uint32) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); address caller = _msgSender(); // Fetch restrictions that apply to the caller on the targeted function @@ -513,7 +512,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult /// @inheritdoc IAccessManager function cancel(address caller, address target, bytes calldata data) public virtual returns (uint32) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); address msgsender = _msgSender(); bytes4 selector = _checkSelector(data); @@ -551,7 +550,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * Returns the nonce of the scheduled operation that is consumed. */ function _consumeScheduledOp(bytes32 operationId) internal virtual returns (uint32) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); uint48 timepoint = $._schedules[operationId].timepoint; uint32 nonce = $._schedules[operationId].nonce; @@ -709,7 +708,7 @@ abstract contract AccessManagerCustom is Initializable, ContextUpgradeable, Mult * @dev Returns true if a call with `target` and `selector` is being executed via {executed}. */ function _isExecuting(address target, bytes4 selector) private view returns (bool) { - AccessManagerStorage storage $ = _getAccessManagerCustomStorage(); + AccessManagerCustomStorage storage $ = _getAccessManagerCustomStorage(); return $._executionId == _hashExecutionId(target, selector); } diff --git a/contracts/shared/AccessManagerExtended.sol b/contracts/shared/AccessManagerExtended.sol index 25717e985..b0e8cce41 100644 --- a/contracts/shared/AccessManagerExtended.sol +++ b/contracts/shared/AccessManagerExtended.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.20; @@ -64,7 +64,7 @@ contract AccessManagerExtended is AccessManagerCustom, IAccessManagerExtended { __AccessManagerCustom_init(initialAdmin); } - // =================================================== GETTERS ==================================================== + // ==================================== TARGET GETTERS ================================================== // function isTargetExists(address target) public view returns (bool) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); @@ -81,24 +81,28 @@ contract AccessManagerExtended is AccessManagerCustom, IAccessManagerExtended { return $._targetAddressForName[name]; } + // by name? function getTargetInfo(address target) public view returns (TargetInfo memory) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); return $._targetInfo[target]; } - function getRoleInfo(uint64 roleId) public view returns (RoleInfo memory) { + // ==================================== ROLE GETTERS ==================================================== // + + function isRoleExists(uint64 roleId) public view returns (bool exists) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return $._roleInfo[roleId]; + return $._roleInfo[roleId].createdAt.gtz(); } - function getRoleMembers(uint64 roleId) public view returns (uint256 numberOfMembers) { + function isRoleNameExists(string memory name) public view returns (bool exists) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return EnumerableSet.length($._roleMembers[roleId]); + return $._roleIdForName[name] != 0; } - function getRoleMember(uint64 roleId, uint256 idx) public view returns (address member) { + // TODO returns ADMIN_ROLE id for non existent name + function getRoleId(string memory name) public view returns (uint64 roleId) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return EnumerableSet.at($._roleMembers[roleId], idx); + return $._roleIdForName[name]; } function getRoleId(uint256 idx) public view returns (uint64 roleId) { @@ -106,25 +110,24 @@ contract AccessManagerExtended is AccessManagerCustom, IAccessManagerExtended { return $._roleIds[idx]; } - // TODO returns ADMIN_ROLE id for non existent name - function getRoleId(string memory name) public view returns (uint64 roleId) { + function getRoleInfo(uint64 roleId) public view returns (RoleInfo memory) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return $._roleIdForName[name]; + return $._roleInfo[roleId]; } - function getRoles() public view returns (uint256 numberOfRoles) { + function getRoleMembers(uint64 roleId) public view returns (uint256 numberOfMembers) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return $._roleIds.length; + return EnumerableSet.length($._roleMembers[roleId]); } - function isRoleExists(uint64 roleId) public view returns (bool exists) { + function getRoleMember(uint64 roleId, uint256 idx) public view returns (address member) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return $._roleInfo[roleId].createdAt.gtz(); + return EnumerableSet.at($._roleMembers[roleId], idx); } - function isRoleNameExists(string memory name) public view returns (bool exists) { + function getRoles() public view returns (uint256 numberOfRoles) { AccessManagerExtendedStorage storage $ = _getAccessManagerExtendedStorage(); - return $._roleIdForName[name] != 0; + return $._roleIds.length; } // =============================================== ROLE MANAGEMENT =============================================== @@ -320,12 +323,14 @@ contract AccessManagerExtended is AccessManagerCustom, IAccessManagerExtended { if(target == address(0)) { revert AccessManagerTargetAddressZero(); } - // panic if not contract - //address authority = IAccessManaged(target).authority(); - //if(authority != address(this)) { - // revert AccessManagerTargetAuthorityInvalid(target, authority); - //} + // panic if not contract or call reverts + //try/catch here? + address authority = IAccessManaged(target).authority(); + + if(authority != address(this)) { + revert AccessManagerTargetAuthorityInvalid(target, authority); + } if(bytes(name).length == 0) { revert AccessManagerTargetNameEmpty(target); diff --git a/contracts/shared/AccessManagerExtendedWithDisable.sol b/contracts/shared/AccessManagerExtendedWithDisable.sol index 05bdc3aef..64272a898 100644 --- a/contracts/shared/AccessManagerExtendedWithDisable.sol +++ b/contracts/shared/AccessManagerExtendedWithDisable.sol @@ -1,6 +1,4 @@ -// SPDX-License-Identifier: MIT -// OpenZeppelin Contracts (last updated v5.0.0) (access/manager/AccessManager.sol) - +// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.20; import {IAccessManager} from "@openzeppelin/contracts/access/manager/IAccessManager.sol"; From 87e56add502d61a94543cdc825cf3406b33cd468 Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:34:37 +0000 Subject: [PATCH 5/9] add implementation to proxy manager --- contracts/shared/ProxyManager.sol | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contracts/shared/ProxyManager.sol b/contracts/shared/ProxyManager.sol index f47ec987f..5c9da8e8d 100644 --- a/contracts/shared/ProxyManager.sol +++ b/contracts/shared/ProxyManager.sol @@ -35,6 +35,7 @@ contract ProxyManager is error ErrorProxyManagerZeroVersion(); error ErrorProxyManagerNextVersionNotIncreasing(Version nextVersion); + address internal _implementation; UpgradableProxyWithAdmin internal _proxy; // state to keep version history @@ -68,6 +69,7 @@ contract ProxyManager is address currentProxyOwner = getOwner(); // used by implementation address initialProxyAdminOwner = address(this); // used by proxy + _implementation = initialImplementation; _proxy = new UpgradableProxyWithAdmin( initialImplementation, initialProxyAdminOwner, @@ -93,6 +95,7 @@ contract ProxyManager is address currentProxyOwner = getOwner(); address initialProxyAdminOwner = address(this); + _implementation = initialImplementation; _proxy = new UpgradableProxyWithAdmin{salt: salt}( initialImplementation, initialProxyAdminOwner, @@ -120,6 +123,7 @@ contract ProxyManager is ProxyAdmin proxyAdmin = getProxy().getProxyAdmin(); ITransparentUpgradeableProxy proxy = ITransparentUpgradeableProxy(address(_proxy)); + _implementation = newImplementation; proxyAdmin.upgradeAndCall( proxy, newImplementation, @@ -153,6 +157,10 @@ contract ProxyManager is return _proxy; } + function getImplementation() public view returns (address) { + return _implementation; + } + function getVersion() external view virtual returns(Version) { return IVersionable(address(_proxy)).getVersion(); } From 97a4cc1c8a09fd9544e90cae5bdcd74daf9455fa Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:35:19 +0000 Subject: [PATCH 6/9] add getMajorVersion() to service --- contracts/shared/Service.sol | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/contracts/shared/Service.sol b/contracts/shared/Service.sol index f516974e4..208d9b48e 100644 --- a/contracts/shared/Service.sol +++ b/contracts/shared/Service.sol @@ -24,19 +24,8 @@ abstract contract Service is AccessManagedUpgradeable, IService { - uint8 private constant GIF_MAJOR_VERSION = 3; - // from Versionable - function getVersion() - public - pure - virtual override (IVersionable, Versionable) - returns(Version) - { - return VersionLib.toVersion(GIF_MAJOR_VERSION,0,0); - } - function initializeService( address registry, address authority, // real authority for registry service adress(0) for other services @@ -70,6 +59,25 @@ abstract contract Service is registerInterface(type(IService).interfaceId); } + // from Versionable + function getVersion() + public + pure + virtual override (IVersionable, Versionable) + returns(Version) + { + return VersionLib.toVersion(GIF_MAJOR_VERSION,0,0); + } + + function getMajorVersion() + public + pure + virtual + returns(VersionPart) + { + return VersionLib.toVersionPart(GIF_MAJOR_VERSION); + } + function _getServiceAddress(ObjectType domain) internal view returns (address) { return getRegistry().getServiceAddress(domain, getVersion().toMajorPart()); From 7351cf078348689d331ea663816261ee3e76310c Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Mon, 20 May 2024 06:44:56 +0000 Subject: [PATCH 7/9] fix test --- test/base/GifDeployer.sol | 4 ++-- test/instance/TestInstanceService.t .sol | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/base/GifDeployer.sol b/test/base/GifDeployer.sol index 56dcb122d..319973a0a 100644 --- a/test/base/GifDeployer.sol +++ b/test/base/GifDeployer.sol @@ -36,10 +36,10 @@ contract GifDeployer is Test { // 1) deploy dip token dip = new Dip(); - // 2) deploy registry admin + // 2) deploy registry admin and registry access manager registryAdmin = new RegistryAdmin(); - // 3) deploy registry + // 3) deploy registry and chainNft registry = new Registry(registryAdmin); // 4) deploy release manager diff --git a/test/instance/TestInstanceService.t .sol b/test/instance/TestInstanceService.t .sol index d0f4ea72c..0620c30b9 100644 --- a/test/instance/TestInstanceService.t .sol +++ b/test/instance/TestInstanceService.t .sol @@ -19,7 +19,7 @@ contract TestInstanceService is GifTest { instanceService.upgradeMasterInstanceReader(address(newMasterInstanceReader)); // THEN - assertEq(address(newMasterInstanceReader), instanceService.getMasterInstanceReader(), "master instance reader not set"); + assertEq(address(newMasterInstanceReader), instanceService.getMasterInstanceReaderAddress(), "master instance reader not set"); } function test_upgradeMasterInstanceReader_not_master_instance() public { From 5b23cbd6b79a0c7fe4d746d2dd880d5b9b4d0c8f Mon Sep 17 00:00:00 2001 From: rapiddenis <41779817+rapidddenis@users.noreply.github.com> Date: Wed, 22 May 2024 23:40:42 +0000 Subject: [PATCH 8/9] resumable deployment option, renamings --- .github/workflows/build.yml | 2 +- README.md | 34 +- contracts/instance/InstanceReader.sol | 10 +- hardhat.config.ts | 2 +- package-lock.json | 2195 +++++++++++++++++++++++-- scripts/deploy_all.ts | 82 +- scripts/libs/deployment.ts | 174 +- scripts/libs/deployment_state.ts | 60 +- scripts/libs/instance.ts | 306 +++- scripts/libs/libraries.ts | 4 +- scripts/libs/registry.ts | 111 +- scripts/libs/release.ts | 106 +- scripts/libs/services.ts | 422 ++--- 13 files changed, 2832 insertions(+), 676 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bba68c089..e81282caa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -145,6 +145,6 @@ jobs: - name: Run deployment script env: - SKIP_VERIFICATION: true + ENABLE_ETHERSCAN_VERIFICATION: true run: hh run scripts/deploy_all.ts \ No newline at end of file diff --git a/README.md b/README.md index d0101a6c9..bd244537b 100644 --- a/README.md +++ b/README.md @@ -68,16 +68,13 @@ The deploy script will deploy all required contracts and create a test instance ```bash # run deployment on a locally created ganache instance -export SKIP_VERIFICATION=true +export ENABLE_ETHERSCAN_VERIFICATION=false +export ENABLE_TENDERLY_VERIFICATION=false hh run scripts/deploy_all.ts - -# run deployment on tenderly virtual network -export SKIP_VERIFICATION=true -hh run scripts/deploy_all.ts --network vitualMainnet ``` ```bash -# set appropriate values vor env variables (see below) +# set appropriate values for env variables (see below) # run deployment on another network hh run --network scripts/deploy_all.ts @@ -85,22 +82,37 @@ hh run --network scripts/deploy_all.ts Environment variables: -- `SKIP_VERIFICATION` set to `true` to skip etherscan verification (required for ganacht and anvil) +- `RESUMEABLE_DEPLOYMENT`set to `true` to skip deployment/verification of already deployed/verified contracts (based on ./deployment_state_.json) +- `ENABLE_ETHERSCAN_VERIFICATION` set to `true` to skip etherscan verification (required for ganacht and anvil) - `WEB3_INFURA_PROJECT_ID` set to infura project id (required for mumbai and mainnet) - `WALLET_MNEMONIC` the mnemonic of the wallet to use for deployment (required for mumbai and mainnet) - `ETHERSCAN_API_KEY` `POLYGONSCAN_API_KEY` the api key for etherscan/polygonscan (required for mumbai and mainnet) + +```bash +# run deployment and verify on tendrely network + +export ENABLE_ETHERSCAN_VERIFICATION=false +export ENABLE_TENDERLY_VERIFICATION=true +tenderly login +hh run --network scripts/deploy_all.ts +``` + +Environment variables: + +- `RESUMEABLE_DEPLOYMENT` set to `true` to skip deployment/verification of already deployed/verified contracts (based on ./deployment_state_.json) +- `ENABLE_TENDERLY_VERIFICATION` set to `true` to perform verification of deployed contracts # https://dashboard.tenderly.co/{TENDERLY_USERNAME}/{TENDERLY_PROJECT}/fork/{FORK_ID} -- `TENDERLY_DEVNET_RPC_URL` -- `TENDERLY_USERNAME` -- `TENDERLY_PROJECT` +- `TENDERLY_DEVNET_RPC_URL` is the RPC_URL of a Tenderly Devnet, found on the devnet UI info tab +- `TENDERLY_USERNAME` is username, {TENDERLY_USERNAME} in the URL +- `TENDERLY_PROJECT` is project slug, {TENDERLY_PROJECT} in the URL ### Create a new instance Requires previous step to be completed. ```bash -# set appropriate values vor env variables (see below) +# set appropriate values for env variables (see below) hh run --network scripts/new_instance.ts ``` diff --git a/contracts/instance/InstanceReader.sol b/contracts/instance/InstanceReader.sol index 315bcc7a6..d1701ae09 100644 --- a/contracts/instance/InstanceReader.sol +++ b/contracts/instance/InstanceReader.sol @@ -16,16 +16,18 @@ import {RiskId} from "../type/RiskId.sol"; import {UFixed, MathLib, UFixedLib} from "../type/UFixed.sol"; import {Version} from "../type/Version.sol"; import {StateId} from "../type/StateId.sol"; +import {TimestampLib} from "../type/Timestamp.sol"; + +import {IKeyValueStore} from "../shared/IKeyValueStore.sol"; +import {IRisk} from "../instance/module/IRisk.sol"; +import {IPolicy} from "../instance/module/IPolicy.sol"; import {IRegistry} from "../registry/IRegistry.sol"; import {IBundle} from "../instance/module/IBundle.sol"; import {IComponents} from "../instance/module/IComponents.sol"; import {IDistribution} from "../instance/module/IDistribution.sol"; import {IInstance} from "./IInstance.sol"; -import {IKeyValueStore} from "../shared/IKeyValueStore.sol"; -import {IPolicy} from "../instance/module/IPolicy.sol"; -import {IRisk} from "../instance/module/IRisk.sol"; -import {TimestampLib} from "../type/Timestamp.sol"; + import {InstanceStore} from "./InstanceStore.sol"; diff --git a/hardhat.config.ts b/hardhat.config.ts index 4acf23862..65e5fe3f0 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -17,7 +17,7 @@ const automaticVerifications = TENDERLY_AUTOMATIC_VERIFICATION === "true";// TOD import * as tenderly from "@tenderly/hardhat-tenderly"; tenderly.setup({ automaticVerifications }); - +console.log("Tenderly setup:"); console.log("Using private verification?", privateVerification); console.log("Using automatic verification?", automaticVerifications); diff --git a/package-lock.json b/package-lock.json index 7b4c4e4da..0d90afb26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,9 +17,10 @@ "winston": "^3.10.0" }, "devDependencies": { - "@nomicfoundation/hardhat-foundry": "^1.1.1", - "@nomicfoundation/hardhat-toolbox": "^3.0.0", - "@nomicfoundation/hardhat-verify": "^1.1.1", + "@nomicfoundation/hardhat-foundry": "^1.1.2", + "@nomicfoundation/hardhat-toolbox": "^5.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.7", + "@tenderly/hardhat-tenderly": "^2.2.2", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "dotenv": "^16.3.1", @@ -44,6 +45,62 @@ "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" }, + "node_modules/@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + "dev": true, + "dependencies": { + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.567.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.567.0.tgz", + "integrity": "sha512-JBznu45cdgQb8+T/Zab7WpBmfEAh77gsk99xuF4biIb2Sw1mdseONdoGDjEJX57a25TzIv/WUJ2oABWumckz1A==", + "dev": true, + "dependencies": { + "@smithy/types": "^2.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-sdk/types/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/util-utf8-browser/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/@colors/colors": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", @@ -57,7 +114,6 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "devOptional": true, - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -326,6 +382,26 @@ "@ethersproject/bytes": "^5.7.0" } }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, "node_modules/@ethersproject/bignumber": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", @@ -382,6 +458,34 @@ "@ethersproject/bignumber": "^5.7.0" } }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, "node_modules/@ethersproject/hash": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", @@ -408,6 +512,73 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true + }, "node_modules/@ethersproject/keccak256": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", @@ -460,6 +631,26 @@ "@ethersproject/logger": "^5.7.0" } }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, "node_modules/@ethersproject/properties": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", @@ -478,6 +669,85 @@ "@ethersproject/logger": "^5.7.0" } }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, "node_modules/@ethersproject/rlp": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", @@ -497,6 +767,27 @@ "@ethersproject/logger": "^5.7.0" } }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, "node_modules/@ethersproject/signing-key": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", @@ -520,6 +811,30 @@ "hash.js": "1.1.7" } }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, "node_modules/@ethersproject/strings": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", @@ -566,10 +881,11 @@ "@ethersproject/signing-key": "^5.7.0" } }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "dev": true, "funding": [ { "type": "individual", @@ -581,23 +897,99 @@ } ], "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@fastify/busboy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", - "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", - "engines": { - "node": ">=14" + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", + "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, @@ -634,7 +1026,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "devOptional": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -643,15 +1034,13 @@ "version": "1.4.15", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "devOptional": true, - "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -1006,7 +1395,6 @@ "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.4.tgz", "integrity": "sha512-k9qbLoY7qn6C6Y1LI0gk2kyHXil2Tauj4kGzQ8pgxYXIGw8lWn8tuuL72E11CrlKaXRUvOgF0EXrv/msPI2SbA==", "dev": true, - "peer": true, "dependencies": { "debug": "^4.1.1", "lodash.isequal": "^4.5.0" @@ -1017,9 +1405,9 @@ } }, "node_modules/@nomicfoundation/hardhat-foundry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.1.1.tgz", - "integrity": "sha512-cXGCBHAiXas9Pg9MhMOpBVQCkWRYoRFG7GJJAph+sdQsfd22iRs5U5Vs9XmpGEQd1yEvYISQZMeE68Nxj65iUQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.1.2.tgz", + "integrity": "sha512-f5Vhj3m2qvKGpr6NAINYwNgILDsai8dVCsFb1rAVLkJxOmD2pAtfCmOH5SBVr9yUI5B1z9rbTwPBJVrqnb+PXQ==", "dev": true, "dependencies": { "chalk": "^2.4.2" @@ -1028,6 +1416,153 @@ "hardhat": "^2.17.2" } }, + "node_modules/@nomicfoundation/hardhat-ignition": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.4.tgz", + "integrity": "sha512-x1lhLN9ZRSJ9eiNY9AoinMdeQeU4LDQSQOIw90W9DiZIG/g9YUzcTEIY58QTi2TZOF8YFiF6vJqLSePCpi8R1Q==", + "dev": true, + "peer": true, + "dependencies": { + "@nomicfoundation/ignition-core": "^0.15.4", + "@nomicfoundation/ignition-ui": "^0.15.4", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "prompts": "^2.4.2" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.1", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition-ethers": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.4.tgz", + "integrity": "sha512-vY30V4b788GSziW/nOd0L/4IPw6mwpluahLs4+gPUUKWaHHGMA8OIeHaYpRRljM1i0M/Kg1yIozrDM/aeRebkg==", + "dev": true, + "peer": true, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@nomicfoundation/hardhat-ignition": "^0.15.4", + "@nomicfoundation/ignition-core": "^0.15.4", + "ethers": "^6.7.0", + "hardhat": "^2.18.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "peer": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "peer": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "peer": true + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nomicfoundation/hardhat-ignition/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@nomicfoundation/hardhat-network-helpers": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz", @@ -1083,34 +1618,35 @@ } }, "node_modules/@nomicfoundation/hardhat-toolbox": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-3.0.0.tgz", - "integrity": "sha512-MsteDXd0UagMksqm9KvcFG6gNKYNa3GGNCy73iQ6bEasEgg2v8Qjl6XA5hjs8o5UD5A3153B6W2BIVJ8SxYUtA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", + "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", "dev": true, "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "^0.15.0", "@nomicfoundation/hardhat-network-helpers": "^1.0.0", - "@nomicfoundation/hardhat-verify": "^1.0.0", - "@typechain/ethers-v6": "^0.4.0", - "@typechain/hardhat": "^8.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", - "@types/node": ">=12.0.0", + "@types/node": ">=18.0.0", "chai": "^4.2.0", "ethers": "^6.4.0", "hardhat": "^2.11.0", "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.1", "ts-node": ">=8.0.0", - "typechain": "^8.2.0", + "typechain": "^8.3.0", "typescript": ">=4.5.0" } }, "node_modules/@nomicfoundation/hardhat-verify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-1.1.1.tgz", - "integrity": "sha512-9QsTYD7pcZaQFEA3tBb/D/oCStYDiEVDN7Dxeo/4SCyHRSm86APypxxdOMEPlGmXsAvd+p1j/dTODcpxb8aztA==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.7.tgz", + "integrity": "sha512-jiYHBX+K6bBN0YhwFHQ5SWWc3dQZliM3pdgpH33C7tnsVACsX1ubZn6gZ9hfwlzG0tyjFM72XQhpaXQ56cE6Ew==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -1127,6 +1663,106 @@ "hardhat": "^2.0.4" } }, + "node_modules/@nomicfoundation/ignition-core": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.4.tgz", + "integrity": "sha512-i379lH+xOLFdaDv0KiNma550ZXCHc5ZkmKYhM44xyLMKBlvX6skUVFkgUjjN1gvprgOIxc17GVQXlR1R5FhGZA==", + "dev": true, + "peer": true, + "dependencies": { + "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "cbor": "^9.0.0", + "debug": "^4.3.2", + "ethers": "^6.7.0", + "fs-extra": "^10.0.0", + "immer": "10.0.2", + "lodash": "4.17.21", + "ndjson": "2.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/@ethersproject/address": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.1.tgz", + "integrity": "sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/bignumber": "^5.6.2", + "@ethersproject/bytes": "^5.6.1", + "@ethersproject/keccak256": "^5.6.1", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.1" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "peer": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nomicfoundation/ignition-core/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@nomicfoundation/ignition-ui": { + "version": "0.15.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.4.tgz", + "integrity": "sha512-cHbmuxmhso5n2zdIaaIW4p8NNzrFj0mrnv8ufhAZfM3s3IFrRoGc1zo8hI/n1CiOTPuqUbdZcB79d+2tCKtCNw==", + "dev": true, + "peer": true + }, "node_modules/@nomicfoundation/solidity-analyzer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", @@ -1267,47 +1903,293 @@ "node": ">= 10" } }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", - "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@nomicfoundation/solidity-analyzer-win32-ia32-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.1.tgz", + "integrity": "sha512-JnFkYuyCSA70j6Si6cS1A9Gh1aHTEb8kOTBApp/c7NRTFGNMH8eaInKlyuuiIbvYFhlXW4LicqyYuWNNq9hkpQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", + "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@openzeppelin/contracts": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.0.tgz", + "integrity": "sha512-bv2sdS6LKqVVMLI5+zqnNrNU/CA+6z6CmwFXm/MzmOPBRSO5reEJN7z0Gbzvs0/bv/MZZXNklubpwy3v2+azsw==" + }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.0.tgz", + "integrity": "sha512-D54RHzkOKHQ8xUssPgQe2d/U92mwaiBDY7qCCVGq6VqwQjsT3KekEQ3bonev+BLP30oZ0R1U6YC8/oLpizgC5Q==", + "peerDependencies": { + "@openzeppelin/contracts": "5.0.0" + } + }, + "node_modules/@openzeppelin/defender-admin-client": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-admin-client/-/defender-admin-client-1.54.1.tgz", + "integrity": "sha512-kRpSUdTsnSqntp4FOXIm95t+6VKHc8CUY2Si71VDuxs0q7HSPZkdpRPSntcolwEzWy9L4a8NS/QMwDF5NJ4X1g==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-base-client": "1.54.1", + "axios": "^1.4.0", + "ethers": "^5.7.2", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + } + }, + "node_modules/@openzeppelin/defender-admin-client/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/@openzeppelin/defender-base-client": { + "version": "1.54.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-base-client/-/defender-base-client-1.54.1.tgz", + "integrity": "sha512-DRGz/7KN3ZQwu28YWMOaojrC7jjPkz/uCwkC8/C8B11qwZhA5qIVvyhYHhhFOCl0J84+E3TNdvkPD2q3p2WaJw==", + "dev": true, + "dependencies": { + "amazon-cognito-identity-js": "^6.0.1", + "async-retry": "^1.3.3", + "axios": "^1.4.0", + "lodash": "^4.17.19", + "node-fetch": "^2.6.0" + } + }, + "node_modules/@openzeppelin/defender-sdk-base-client": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-1.13.0.tgz", + "integrity": "sha512-XyCHF4Q//rInmJG6XM9x4JDiERJTCjmGX7FOmtbXYAKTTE5ygUvFU7gXJ5oxtbB2anPU3OJIPM25Shkd3+7dKw==", + "dev": true, + "dependencies": { + "amazon-cognito-identity-js": "^6.3.6", + "async-retry": "^1.3.3" + } + }, + "node_modules/@openzeppelin/defender-sdk-deploy-client": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-1.13.0.tgz", + "integrity": "sha512-igLut1lIV52DWV9Bn8MrESgCvCQSOunqRZkSLC/KGCbEUTEyNoAHNsGMu9Z+K11RYCD0CHGnfAi0ODLsbrq6QA==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^1.13.0", + "axios": "^1.6.7", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/defender-sdk-network-client": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-1.13.0.tgz", + "integrity": "sha512-Rv9QBEBvEi407zZzCPnOrL8y8ByyQo7fwni5EBoRJQPj1HeM4uhZkLRNpq8YZOjjNhu648SP+L4F8Bbtdzmd9w==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^1.13.0", + "axios": "^1.6.7", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.33.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.33.1.tgz", + "integrity": "sha512-YRxIRhTY1b+j7+NUUu8Uuem5ugxKexEMVd8dBRWNgWeoN1gS1OCrhgUg0ytL+54vzQ+SGWZDfNnzjVuI1Cj1Zw==", + "dev": true, + "dependencies": { + "cbor": "^9.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.51" + }, + "bin": { + "openzeppelin-upgrades-core": "dist/cli/cli.js" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/cbor": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-9.0.2.tgz", + "integrity": "sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==", + "dev": true, + "dependencies": { + "nofilter": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@openzeppelin/upgrades-core/node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, "engines": { - "node": ">= 10" + "node": ">=10.0.0" } }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.1.tgz", - "integrity": "sha512-HrVJr6+WjIXGnw3Q9u6KQcbZCtk0caVWhCdFADySvRyUxJ8PnzlaP+MhwNE8oyT8OZ6ejHBRrrgjSqDCFXGirw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], + "node_modules/@openzeppelin/upgrades-core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/@openzeppelin/contracts": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.0.0.tgz", - "integrity": "sha512-bv2sdS6LKqVVMLI5+zqnNrNU/CA+6z6CmwFXm/MzmOPBRSO5reEJN7z0Gbzvs0/bv/MZZXNklubpwy3v2+azsw==" - }, - "node_modules/@openzeppelin/contracts-upgradeable": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.0.tgz", - "integrity": "sha512-D54RHzkOKHQ8xUssPgQe2d/U92mwaiBDY7qCCVGq6VqwQjsT3KekEQ3bonev+BLP30oZ0R1U6YC8/oLpizgC5Q==", - "peerDependencies": { - "@openzeppelin/contracts": "5.0.0" + "node_modules/@openzeppelin/upgrades-core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, "node_modules/@scure/base": { @@ -1447,6 +2329,24 @@ "node": ">=6" } }, + "node_modules/@smithy/types": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", + "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@smithy/types/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/@solidity-parser/parser": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", @@ -1457,38 +2357,244 @@ "antlr4ts": "^0.5.0-alpha.4" } }, + "node_modules/@tenderly/hardhat-tenderly": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@tenderly/hardhat-tenderly/-/hardhat-tenderly-2.2.2.tgz", + "integrity": "sha512-JZINDVHW0ob+tCtNppgXMKiVcpbtcdEeHGaIsRFDXGeVQ1061asouf1lILvyWSfhv5ZeIkEX/LmeOo9IlC7rkw==", + "dev": true, + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@nomicfoundation/hardhat-ethers": "^3.0.4", + "@openzeppelin/hardhat-upgrades": "^3.0.1", + "@openzeppelin/upgrades-core": "^1.32.2", + "axios": "^1.6.7", + "ethers": "^6.8.1", + "fs-extra": "^10.1.0", + "hardhat-deploy": "^0.11.43", + "tenderly": "^0.9.1", + "ts-node": "^10.9.1", + "tslog": "^4.3.1", + "typescript": "^5.2.2" + }, + "peerDependencies": { + "ethers": "^6.8.1", + "hardhat": "^2.19.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@openzeppelin/hardhat-upgrades": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.1.0.tgz", + "integrity": "sha512-CQ5Cg2kE8WeW6qajUTacBsmkntiAwJd7f6p+BUtd1fEvEv7si4H2lmAqvjOjkFc9ihIEQxMBy50IsBXSZGktmg==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-admin-client": "^1.52.0", + "@openzeppelin/defender-base-client": "^1.52.0", + "@openzeppelin/defender-sdk-base-client": "^1.10.0", + "@openzeppelin/defender-sdk-deploy-client": "^1.10.0", + "@openzeppelin/defender-sdk-network-client": "^1.10.0", + "@openzeppelin/upgrades-core": "^1.32.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.1.5", + "proper-lockfile": "^4.1.1", + "undici": "^6.11.1" + }, + "bin": { + "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.0", + "@nomicfoundation/hardhat-verify": "^2.0.0", + "ethers": "^6.6.0", + "hardhat": "^2.0.2" + }, + "peerDependenciesMeta": { + "@nomicfoundation/hardhat-verify": { + "optional": true + } + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@openzeppelin/hardhat-upgrades/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/@openzeppelin/hardhat-upgrades/node_modules/undici": { + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.16.1.tgz", + "integrity": "sha512-NeNiTT7ixpeiL1qOIU/xTVpHpVP0svmI6PwoCKaMGaI5AsHOaRdwqU/f7Fi9eyU4u03nd5U/BC8wmRMnS9nqoA==", + "dev": true, + "engines": { + "node": ">=18.17" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@tenderly/hardhat-tenderly/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/@typechain/ethers-v6": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.4.3.tgz", - "integrity": "sha512-TrxBsyb4ryhaY9keP6RzhFCviWYApcLCIRMPyWaKp2cZZrfaM3QBoxXTnw/eO4+DAY3l+8O0brNW0WgeQeOiDA==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@typechain/ethers-v6/-/ethers-v6-0.5.1.tgz", + "integrity": "sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==", "dev": true, "peer": true, "dependencies": { @@ -1497,24 +2603,24 @@ }, "peerDependencies": { "ethers": "6.x", - "typechain": "^8.3.1", + "typechain": "^8.3.2", "typescript": ">=4.7.0" } }, "node_modules/@typechain/hardhat": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-8.0.3.tgz", - "integrity": "sha512-MytSmJJn+gs7Mqrpt/gWkTCOpOQ6ZDfRrRT2gtZL0rfGe4QrU4x9ZdW15fFbVM/XTa+5EsKiOMYXhRABibNeng==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@typechain/hardhat/-/hardhat-9.1.0.tgz", + "integrity": "sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==", "dev": true, "peer": true, "dependencies": { "fs-extra": "^9.1.0" }, "peerDependencies": { - "@typechain/ethers-v6": "^0.4.3", + "@typechain/ethers-v6": "^0.5.1", "ethers": "^6.1.0", "hardhat": "^2.9.9", - "typechain": "^8.3.1" + "typechain": "^8.3.2" } }, "node_modules/@typechain/hardhat/node_modules/fs-extra": { @@ -1547,9 +2653,9 @@ } }, "node_modules/@typechain/hardhat/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "peer": true, "engines": { @@ -1661,8 +2767,7 @@ "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/secp256k1": { "version": "4.0.3", @@ -2340,7 +3445,6 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "devOptional": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -2407,6 +3511,19 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/amazon-cognito-identity-js": { + "version": "6.3.12", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.12.tgz", + "integrity": "sha512-s7NKDZgx336cp+oDeUtB2ZzT8jWJp/v2LWuYl+LQtMEODe22RF1IJ4nRiDATp+rp1pTffCZcm44Quw4jx2bqNg==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + } + }, "node_modules/amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", @@ -2490,8 +3607,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/argparse": { "version": "2.0.1", @@ -2649,12 +3765,29 @@ "dev": true, "peer": true }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dev": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/async-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "peer": true + "dev": true }, "node_modules/at-least-node": { "version": "1.0.0", @@ -2694,6 +3827,31 @@ "dev": true, "peer": true }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2707,6 +3865,26 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -2724,6 +3902,12 @@ "dev": true, "peer": true }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -2899,6 +4083,17 @@ "safe-buffer": "^5.1.2" } }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -2918,12 +4113,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3221,7 +4422,6 @@ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "peer": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -3291,6 +4491,12 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==" }, + "node_modules/compare-versions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", + "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3382,8 +4588,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -3500,6 +4705,31 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/define-properties": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", @@ -3520,7 +4750,6 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -3645,6 +4874,12 @@ "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, + "node_modules/encode-utf8": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", + "dev": true + }, "node_modules/enquirer": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", @@ -3741,6 +4976,25 @@ "dev": true, "peer": true }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", @@ -5042,6 +6296,12 @@ ], "peer": true }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -5180,6 +6440,15 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/fmix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", + "integrity": "sha512-Y6hyofImk9JdzU8k5INtTXX1cu8LDlePWDFU5sftm9H+zKCr5SGrVjdhkvsim646cw5zD0nADj8oHyXMZmCZ9w==", + "dev": true, + "dependencies": { + "imul": "^1.0.0" + } + }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", @@ -5332,14 +6601,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5643,16 +6916,249 @@ "hardhat": "internal/cli/bootstrap.js" }, "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-deploy": { + "version": "0.11.45", + "resolved": "https://registry.npmjs.org/hardhat-deploy/-/hardhat-deploy-0.11.45.tgz", + "integrity": "sha512-aC8UNaq3JcORnEUIwV945iJuvBwi65tjHVDU3v6mOcqik7WAzHVCJ7cwmkkipsHrWysrB5YvGF1q9S1vIph83w==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/contracts": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/solidity": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wallet": "^5.7.0", + "@types/qs": "^6.9.7", + "axios": "^0.21.1", + "chalk": "^4.1.2", + "chokidar": "^3.5.2", + "debug": "^4.3.2", + "enquirer": "^2.3.6", + "ethers": "^5.7.0", + "form-data": "^4.0.0", + "fs-extra": "^10.0.0", + "match-all": "^1.2.6", + "murmur-128": "^0.2.1", + "qs": "^6.9.4", + "zksync-web3": "^0.14.3" + } + }, + "node_modules/hardhat-deploy/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/hardhat-deploy/node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, + "node_modules/hardhat-deploy/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/hardhat-deploy/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/hardhat-deploy/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/hardhat-deploy/node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/hardhat-deploy/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hardhat-deploy/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/hardhat-deploy/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-deploy/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/hardhat-deploy/node_modules/qs": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hardhat-deploy/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/hardhat-deploy/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/hardhat-deploy/node_modules/zksync-web3": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/zksync-web3/-/zksync-web3-0.14.4.tgz", + "integrity": "sha512-kYehMD/S6Uhe1g434UnaMN+sBr9nQm23Ywn0EUP5BfQCsbjcr3ORuS68PosZw8xUTu3pac7G6YMSnNHk+fwzvg==", + "deprecated": "This package has been deprecated in favor of zksync-ethers@5.0.0", + "dev": true, + "peerDependencies": { + "ethers": "^5.7.0" } }, "node_modules/hardhat-gas-reporter": { @@ -5698,11 +7204,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5908,6 +7414,26 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -5917,6 +7443,17 @@ "node": ">= 4" } }, + "node_modules/immer": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.2.tgz", + "integrity": "sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==", + "dev": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.2.tgz", @@ -5947,6 +7484,15 @@ "node": ">=4" } }, + "node_modules/imul": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", + "integrity": "sha512-WFAgfwPLAjU66EKt6vRdTlKj4nAgIDQzh29JonLa4Bqtl6D8JrIMvWjCnx7xEjVNmP3U0fM5o8ZObk7d0f62bA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6120,6 +7666,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6314,12 +7875,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -6327,6 +7899,16 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -6334,6 +7916,12 @@ "dev": true, "peer": true }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "dev": true + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -6464,6 +8052,15 @@ "graceful-fs": "^4.1.9" } }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/kuler": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", @@ -6517,8 +8114,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -6646,8 +8242,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/markdown-table": { "version": "1.1.3", @@ -6656,6 +8251,12 @@ "dev": true, "peer": true }, + "node_modules/match-all": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/match-all/-/match-all-1.2.6.tgz", + "integrity": "sha512-0EESkXiTkWzrQQntBu2uzKvLu6vVkUGz40nGPbSZuegcfE5UuSzNjLaIu76zJWuaT/2I3Z/8M06OlUOZLGwLlQ==", + "dev": true + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -6708,7 +8309,6 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -6718,7 +8318,6 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, - "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -6950,6 +8549,17 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/murmur-128": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/murmur-128/-/murmur-128-0.2.1.tgz", + "integrity": "sha512-WseEgiRkI6aMFBbj8Cg9yBj/y+OdipwVC7zUo3W2W1JAJITwouUOtpqsmGSg67EQmwwSyod7hsVsWY5LsrfQVg==", + "dev": true, + "dependencies": { + "encode-utf8": "^1.0.2", + "fmix": "^0.1.0", + "imul": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", @@ -6967,6 +8577,26 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/ndjson": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ndjson/-/ndjson-2.0.0.tgz", + "integrity": "sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==", + "dev": true, + "peer": true, + "dependencies": { + "json-stringify-safe": "^5.0.1", + "minimist": "^1.2.5", + "readable-stream": "^3.6.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "ndjson": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -7008,6 +8638,26 @@ "semver": "bin/semver" } }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-gyp-build": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz", @@ -7091,9 +8741,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7163,6 +8813,23 @@ "fn.name": "1.x.x" } }, + "node_modules/open": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -7443,6 +9110,36 @@ "asap": "~2.0.6" } }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -7736,6 +9433,15 @@ "node": ">=4" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8006,6 +9712,22 @@ "dev": true, "peer": true }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -8082,18 +9804,28 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -8102,6 +9834,12 @@ "is-arrayish": "^0.3.1" } }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8827,6 +10565,16 @@ "source-map": "^0.6.0" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -9145,6 +10893,91 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/tenderly": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/tenderly/-/tenderly-0.9.1.tgz", + "integrity": "sha512-EGhYYbOgIC0EUebrMIwCRIL9NrGrC8q3gTY/3JNSqvQrNX4RLUgMHungTG4bkgGAwJoehC57vsAeKqR1PVIyjw==", + "dev": true, + "dependencies": { + "axios": "^0.27.2", + "cli-table3": "^0.6.2", + "commander": "^9.4.0", + "js-yaml": "^4.1.0", + "open": "^8.4.0", + "prompts": "^2.4.2", + "tslog": "^4.4.0" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/tenderly/node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/tenderly/node_modules/axios": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", + "dev": true, + "dependencies": { + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/tenderly/node_modules/cli-table3": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.4.tgz", + "integrity": "sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/tenderly/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/tenderly/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/text-hex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", @@ -9186,6 +11019,16 @@ "dev": true, "peer": true }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "peer": true, + "dependencies": { + "readable-stream": "3" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -9230,6 +11073,12 @@ "node": ">=0.8" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, "node_modules/triple-beam": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", @@ -9357,7 +11206,6 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "devOptional": true, - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -9401,7 +11249,6 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "devOptional": true, - "peer": true, "engines": { "node": ">=0.3.1" } @@ -9411,6 +11258,18 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/tslog": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.9.2.tgz", + "integrity": "sha512-wBM+LRJoNl34Bdu8mYEFxpvmOUedpNUwMNQB/NcuPIZKwdDde6xLHUev3bBjXQU7gdurX++X/YE7gLH8eXYsiQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/fullstack-build/tslog?sponsor=1" + } + }, "node_modules/tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", @@ -9474,9 +11333,9 @@ } }, "node_modules/typechain": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.1.tgz", - "integrity": "sha512-fA7clol2IP/56yq6vkMTR+4URF1nGjV82Wx6Rf09EsqD4tkzMAvEaqYxVFCavJm/1xaRga/oD55K+4FtuXwQOQ==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/typechain/-/typechain-8.3.2.tgz", + "integrity": "sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==", "dev": true, "peer": true, "dependencies": { @@ -9676,6 +11535,12 @@ "node": ">=14.0" } }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", + "dev": true + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -9725,8 +11590,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "devOptional": true, - "peer": true + "devOptional": true }, "node_modules/verror": { "version": "1.10.0", @@ -9818,6 +11682,22 @@ "@scure/bip39": "1.2.1" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -10161,7 +12041,6 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "devOptional": true, - "peer": true, "engines": { "node": ">=6" } diff --git a/scripts/deploy_all.ts b/scripts/deploy_all.ts index 689e47165..597a6859d 100644 --- a/scripts/deploy_all.ts +++ b/scripts/deploy_all.ts @@ -3,24 +3,28 @@ import { ethers } from "hardhat"; import { ChainNft__factory, IRegistry__factory } from "../typechain-types"; import { getNamedAccounts, printBalance, validateNftOwnerhip } from "./libs/accounts"; import { LibraryAddresses, deployLibraries } from "./libs/libraries"; -import { RegistryAddresses, deployAndInitializeRegistry } from "./libs/registry"; +import { CoreAddresses, deployCore } from "./libs/registry"; import { logger } from "./logger"; -import { InstanceAddresses, MASTER_INSTANCE_OWNER, cloneInstance, deployAndRegisterMasterInstance } from "./libs/instance"; -import { ServiceAddresses, authorizeServices, deployAndRegisterServices } from "./libs/services"; +import { InstanceAddresses, MASTER_INSTANCE_OWNER, cloneInstance, deployAndRegisterMasterInstance, verifyInstance } from "./libs/instance"; +import { ServiceAddresses, authorizeServices, deployRelease } from "./libs/services"; +import { deploymentState, isResumeableDeployment } from "./libs/deployment_state"; async function main() { + console.info("Resumeable deployment?", isResumeableDeployment); + logger.info("deploying new GIF instance..."); const { protocolOwner, masterInstanceOwner, instanceOwner } = await getNamedAccounts(); // deploy protocol contracts const libraries = await deployLibraries(protocolOwner); - const registry = await deployAndInitializeRegistry(protocolOwner, libraries); - const services = await deployAndRegisterServices(protocolOwner, registry, libraries); + const core = await deployCore(protocolOwner, libraries); + const services = await deployRelease(protocolOwner, core, libraries); - // // deploy instance contracts - const masterInstance = await deployAndRegisterMasterInstance(protocolOwner, libraries, registry, services); - const clonedInstance = await cloneInstance(masterInstance, libraries, registry, services, instanceOwner); + // deploy instance contracts + const masterInstance = await deployAndRegisterMasterInstance(protocolOwner, libraries, core, services); + const clonedInstance = await cloneInstance(instanceOwner, services); + await verifyInstance(clonedInstance, libraries); // await grantRole(instanceOwner, libraries, instance, Role.POOL_OWNER_ROLE, poolOwner); // await grantRole(instanceOwner, libraries, instance, Role.DISTRIBUTION_OWNER_ROLE, distributionOwner); @@ -32,12 +36,12 @@ async function main() { // const { distributionAddress, distributionNftId } = await deployDistribution(distributionOwner, libraries, registry, instance, tokenAddress); // const { productAddress, productNftId } = await deployProduct(productOwner, libraries, registry, instance, tokenAddress, poolAddress, distributionAddress); - printAddresses(libraries, registry, services, masterInstance, clonedInstance); + printAddresses(libraries, core, services, masterInstance, clonedInstance); await verifyOwnership( protocolOwner, masterInstanceOwner, //, productOwner, poolOwner, distributionOwner, - libraries, registry, //services, + libraries, core, //services, masterInstance, // tokenAddress, // poolAddress, poolNftId, @@ -66,7 +70,7 @@ async function main() { async function verifyOwnership( protocolOwner: AddressLike, masterInstanceOwner: AddressLike, // productOwner: AddressLike, poolOwner: AddressLike, distributionOwner: AddressLike, - libraries: LibraryAddresses, registry: RegistryAddresses, //services: ServiceAddresses, + libraries: LibraryAddresses, core: CoreAddresses, //services: ServiceAddresses, masterInstance: InstanceAddresses, // tokenAddress: AddressLike, // poolAddress: AddressLike, poolNftId: string, @@ -74,12 +78,12 @@ async function verifyOwnership( // productAddress: AddressLike, productNftId: string, ) { logger.debug("validating ownerships ..."); - const chainNft = ChainNft__factory.connect(await resolveAddress(registry.chainNftAddress), ethers.provider); - if (await chainNft.getRegistryAddress() !== resolveAddress(registry.registryAddress)) { + //const chainNft = ChainNft__factory.connect(await resolveAddress(core.chainNftAddress), ethers.provider); + if (await core.chainNft.getRegistryAddress() !== resolveAddress(core.registryAddress)) { throw new Error("chainNft registry address mismatch"); } - const registryC = IRegistry__factory.connect(await resolveAddress(registry.registryAddress), ethers.provider); - if (await registryC.getChainNftAddress() !== registry.chainNftAddress) { + //const registry = IRegistry__factory.connect(await resolveAddress(core.registryAddress), ethers.provider); + if (await core.registry.getChainNftAddress() !== core.chainNftAddress) { throw new Error("registry chainNft address mismatch"); } @@ -87,31 +91,31 @@ async function verifyOwnership( // await validateOwnership(protocolOwner, services.productServiceAddress); // await validateOwnership(protocolOwner, services.poolServiceAddress); - // await validateNftOwnerhip(registry.chainNftAddress, registry.registryNftId, protocolOwner); - // await validateNftOwnerhip(registry.chainNftAddress, services.componentOwnerServiceNftId, protocolOwner); - // await validateNftOwnerhip(registry.chainNftAddress, services.distributionServiceNftId, protocolOwner); - // await validateNftOwnerhip(registry.chainNftAddress, services.productServiceNftId, protocolOwner); - // await validateNftOwnerhip(registry.chainNftAddress, services.poolServiceNftId, protocolOwner); + // await validateNftOwnerhip(core.chainNftAddress, core.registryNftId, protocolOwner); + // await validateNftOwnerhip(core.chainNftAddress, services.componentOwnerServiceNftId, protocolOwner); + // await validateNftOwnerhip(core.chainNftAddress, services.distributionServiceNftId, protocolOwner); + // await validateNftOwnerhip(core.chainNftAddress, services.productServiceNftId, protocolOwner); + // await validateNftOwnerhip(core.chainNftAddress, services.poolServiceNftId, protocolOwner); if (masterInstance.instanceNftId === undefined) { throw new Error("instance masterInstanceNftId undefined"); } - const masterInstanceNftIdFromReg = await registry.registry["getNftId(address)"](masterInstance.instanceAddress); + const masterInstanceNftIdFromReg = await core.registry["getNftId(address)"](masterInstance.instanceAddress); if (BigInt(masterInstance.instanceNftId) !== masterInstanceNftIdFromReg) { throw new Error(`instance masterInstanceNftId (${masterInstance.instanceNftId}) mismatch: ${masterInstanceNftIdFromReg}`); } - await validateNftOwnerhip(registry.chainNftAddress, masterInstance.instanceNftId, MASTER_INSTANCE_OWNER); + await validateNftOwnerhip(core.chainNftAddress, masterInstance.instanceNftId, MASTER_INSTANCE_OWNER); - // await validateNftOwnerhip(registry.chainNftAddress, instance.instanceNftId, instanceOwner); + // await validateNftOwnerhip(core.chainNftAddress, instance.instanceNftId, instanceOwner); - // await validateNftOwnerhip(registry.chainNftAddress, poolNftId, poolOwner); - // await validateNftOwnerhip(registry.chainNftAddress, distributionNftId, distributionOwner); - // await validateNftOwnerhip(registry.chainNftAddress, productNftId, productOwner); + // await validateNftOwnerhip(core.chainNftAddress, poolNftId, poolOwner); + // await validateNftOwnerhip(core.chainNftAddress, distributionNftId, distributionOwner); + // await validateNftOwnerhip(core.chainNftAddress, productNftId, productOwner); logger.info("ownerships verified"); } function printAddresses( - libraries: LibraryAddresses, registry: RegistryAddresses, + libraries: LibraryAddresses, core: CoreAddresses, services: ServiceAddresses, masterInstance: InstanceAddresses, clonedInstance: InstanceAddresses, // tokenAddress: AddressLike, @@ -119,7 +123,7 @@ function printAddresses( // distributionAddress: AddressLike, distributionNftId: string, // productAddress: AddressLike, productNftId: string, ) { - let addresses = "\nAddresses of deployed smart contracts:\n==========\n"; + let addresses = "\nAddresses of deployed smart contracts:\n==========\n"; addresses += `amountLibAddress: ${libraries.amountLibAddress}\n`; addresses += `blockNumberLibAddress: ${libraries.blockNumberLibAddress}\n`; addresses += `feeLibAddress: ${libraries.feeLibAddress}\n`; @@ -138,15 +142,15 @@ function printAddresses( addresses += `versionPartLibAddress: ${libraries.versionPartLibAddress}\n`; addresses += `instanceAuthorizationsLibAddress: ${libraries.instanceAuthorizationsLibAddress}\n`; addresses += `--------\n`; - addresses += `registryAdminAddress: ${registry.registryAdminAddress}\n`; - addresses += `releaseManagerAddress: ${registry.releaseManagerAddress}\n`; - addresses += `registryAddress: ${registry.registryAddress}\n`; - addresses += `registryNftId: ${registry.registryNftId}\n`; - addresses += `chainNftAddress: ${registry.chainNftAddress}\n`; - addresses += `tokenRegistryAddress: ${registry.tokenRegistryAddress}\n`; - addresses += `stakingNftId: ${registry.stakingNftId}\n`; - addresses += `stakingAddress: ${registry.stakingAddress}\n`; - addresses += `dipAddress: ${registry.dipAddress}\n`; + addresses += `registryAdminAddress: ${core.registryAdminAddress}\n`; + addresses += `releaseManagerAddress: ${core.releaseManagerAddress}\n`; + addresses += `registryAddress: ${core.registryAddress}\n`; + addresses += `registryNftId: ${core.registryNftId}\n`; + addresses += `chainNftAddress: ${core.chainNftAddress}\n`; + addresses += `tokenRegistryAddress: ${core.tokenRegistryAddress}\n`; + addresses += `stakingNftId: ${core.stakingNftId}\n`; + addresses += `stakingAddress: ${core.stakingAddress}\n`; + addresses += `dipAddress: ${core.dipAddress}\n`; addresses += `--------\n`; addresses += `registryServiceManagerAddress: ${services.registryServiceManagerAddress}\n`; addresses += `registryServiceAddress: ${services.registryServiceAddress}\n`; @@ -194,7 +198,7 @@ function printAddresses( addresses += `--------\n`; addresses += `masterInstanceAddress: ${masterInstance.instanceAddress}\n`; addresses += `masterInstanceNftId: ${masterInstance.instanceNftId}\n`; - addresses += `masterInstanceAccessManagerAddress: ${masterInstance.accessManagerAddress}\n`; + addresses += `masterInstanceAccessManagerAddress: ${masterInstance.instanceAccessManagerAddress}\n`; addresses += `masterInstanceAdminAddress: ${masterInstance.instanceAdminAddress}\n`; addresses += `masterBundleManagerAddress: ${masterInstance.instanceBundleManagerAddress}\n`; addresses += `masterInstanceReaderAddress: ${masterInstance.instanceReaderAddress}\n`; @@ -202,7 +206,7 @@ function printAddresses( addresses += `--------\n`; addresses += `clonedInstanceAddress: ${clonedInstance.instanceAddress}\n`; addresses += `clonedInstanceNftId: ${clonedInstance.instanceNftId}\n`; - addresses += `clonedInstanceAccessManagerAddress: ${clonedInstance.accessManagerAddress}\n`; + addresses += `clonedInstanceAccessManagerAddress: ${clonedInstance.instanceAccessManagerAddress}\n`; addresses += `clonedInstanceAdminAddress: ${clonedInstance.instanceAdminAddress}\n`; addresses += `clonedBundleManagerAddress: ${clonedInstance.instanceBundleManagerAddress}\n`; addresses += `clonedInstanceReaderAddress: ${clonedInstance.instanceReaderAddress}\n`; diff --git a/scripts/libs/deployment.ts b/scripts/libs/deployment.ts index 15b7b1071..b7f4cdf9f 100644 --- a/scripts/libs/deployment.ts +++ b/scripts/libs/deployment.ts @@ -95,73 +95,127 @@ export async function verifyContract(address: AddressLike, constructorArgs: any[ */ // TODO get libraries from artifacts? export async function deployContract(contractName: string, contractType: string, signer: Signer, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string): Promise { + // TODO use static variable as isResumeableDeployment -> set only at the first call in script run if (! isResumeableDeployment ) { logger.info("Starting new deployment"); - return executeAllDeploymentSteps(contractType, signer, constructorArgs, factoryOptions, sourceFileContract); + return executeAllDeploymentSteps(contractType, contractType, signer, constructorArgs, factoryOptions, sourceFileContract); } logger.info(`Trying to resume deployment of ${contractName}`); - if (deploymentState.getContractAddress(contractName) === undefined) { - if (deploymentState.getDeploymentTransaction(contractName) === undefined) { - return executeAllDeploymentSteps(contractName, contractType, signer, constructorArgs, factoryOptions, sourceFileContract); - } else { - return awaitDeploymentTxAndVerify(contractName, contractType, signer, constructorArgs, sourceFileContract); - } + const isDeploying = deploymentState.isDeploying(contractName); + if(isDeploying) { + return awaitDeploymentTxAndVerify(contractName, contractType, signer, constructorArgs, sourceFileContract); + } + + const isDeployed = deploymentState.isDeployed(contractName); + if (!isDeployed) { + return executeAllDeploymentSteps(contractName, contractType, signer, constructorArgs, factoryOptions, sourceFileContract); + } + + // assume contract was deployed + // fetch local persisted deployment state + const deployedContractAddress = deploymentState.getContractAddress(contractName)!; + const deploymentTransactionHash = deploymentState.getDeploymentTransaction(contractName)!; + + // fetch onchain state -> gives error on local chain + const contract = await ethers.getContractAt(contractType, deployedContractAddress, signer) as BaseContract; + const deploymentTransaction = await ethers.provider.getTransaction(deploymentTransactionHash); + const deploymentTransactionReceipt = await ethers.provider.getTransactionReceipt(deploymentTransactionHash); +/* + // check onchain state for existance -> gives error on local chain + if(contract === null) { + throw new Error(`Onchain state: ${contractName} not found at ${deployedContractAddress}`); + } + + if(deploymentTransaction === null) { + throw new Error(`Onchain state: ${contractName} deployment transaction ${deploymentTransactionHash} not found`); + } + + if(deploymentTransactionReceipt === null) { + throw new Error(`Onchain state: ${contractName} deployment transaction receipt ${deploymentTransactionHash} not found`); + } +*/ + logger.info(`${contractName} already deployed at ${deployedContractAddress}`); + + const isVerified = deploymentState.isDeployedAndVerified(contractName); + if(!isVerified) { + await verifyDeployedContract(contractName, contractType, deployedContractAddress, deploymentTransaction, constructorArgs, sourceFileContract); } else { - // fetch persisted data - const address = deploymentState.getContractAddress(contractName)!; - const deploymentTransaction = await ethers.provider.getTransaction(deploymentState.getDeploymentTransaction(contractName)!)!; - const contract = await ethers.getContractAt(contractName, address, signer); - - if (deploymentState.isDeployedAndVerified(contractName)) { - logger.info(`Contract ${contractName} is already deployed at ${address} and verified`); - } else { - logger.info(`Contract ${contractName} is already deployed at ${address}`); - if (deploymentTransaction !== null) { - await verifyDeployedContract(contractName, contractType, address, deploymentTransaction, constructorArgs, sourceFileContract); - } - } + logger.info(`Contract ${contractName} already verified`); + } - return { address, deploymentTransaction, contract }; + return { + address: deployedContractAddress, + deploymentTransaction: deploymentTransaction, + deploymentReceipt: deploymentTransactionReceipt, + contract: contract } } -// Use this function to add to deployemnt state and verify contract deployed by other contract -export async function addDeployedContract(contractName: string, contractType: string, contractAddress: AddressLike, signer: Signer, deploymentTransaction: TransactionResponse, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string) { - +// Use this function to add to deployment state (and verify) a deployed contract (e.g. contract deployed by other contract) +export async function addDeployedContract(contractName: string, contractType: string, deployedContractAddress: AddressLike, deploymentTransaction: TransactionResponse, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string) { const libraries = factoryOptions?.libraries ?? {}; if(deploymentTransaction == undefined) { - throw new Error(`Deployment transaction for ${contractName} is not defined`); + throw new Error(`Deployment transaction of ${contractName} is not provided`); } - + + // fetch onchain state\ +/* + const contract = await ethers.getContractAt(contractType, deployedContractAddress) as BaseContract; + const actualDeploymentTransaction = await ethers.provider.getTransaction(deploymentTransaction.hash); + const actualDeploymentTransactionReceipt = await ethers.provider.getTransactionReceipt(deploymentTransaction.hash); + check given tx and oncahin tx are the same + if(deploymentTransaction != actualDeploymentTransaction) { + throw new Error(`Deployment transaction hash of ${contractName} is wrong, provided ${deploymentTransaction.hash}, actual ${actualDeploymentTransaction.hash}`); + } + + if(contract === null) { + throw new Error(`Onchain state: ${contractName} not found at ${deployedContractAddress}`); + } + + if(actualDeploymentTransaction === null) { + throw new Error(`Onchain state: ${contractName} deployment transaction ${deploymentTransaction.hash} not found`); + } + + if(actualDeploymentTransactionReceipt === null) { + throw new Error(`Onchain state: ${contractName} deployment transaction receipt ${deploymentTransaction.hash} not found`); + } +*/ if (! isResumeableDeployment ) { - // add contract to deployment state + logger.info(`Adding new ${contractName} of type ${contractType} to deployment state...`); + // create new / overwrite existing deployment state deploymentState.setDeploymentTransaction(contractName, contractType, deploymentTransaction?.hash || "0x", libraries); - deploymentState.setContractAddress(contractName, contractAddress); - await verifyDeployedContract(contractName, contractType, contractAddress, deploymentTransaction, constructorArgs, sourceFileContract); + deploymentState.setContractAddress(contractName, deployedContractAddress); + logger.info(`Contract ${contractName} set deployed at ${deployedContractAddress}`); + await verifyDeployedContract(contractName, contractType, deployedContractAddress, deploymentTransaction, constructorArgs, sourceFileContract); return; } - if (deploymentState.getContractAddress(contractName) === undefined) { - if (deploymentState.getDeploymentTransaction(contractName) === undefined) { - // contract not in deployment state - //throw new Error(`${contractName} deployment transaction is not found in deployment state`); - deploymentState.setDeploymentTransaction(contractName, contractType, deploymentTransaction?.hash || "0x", libraries); - deploymentState.setContractAddress(contractName, contractAddress); - await verifyDeployedContract(contractName, contractType, contractAddress, deploymentTransaction, constructorArgs, sourceFileContract); - } else { - awaitDeploymentTxAndVerify(contractName, contractType, signer, constructorArgs, sourceFileContract); - } - } else { - if (deploymentState.isDeployedAndVerified(contractName)) { - logger.info(`Contract ${contractName} is deployed at ${contractAddress} and verified`); - } else { - logger.info(`Contract ${contractName} is deployed at ${contractAddress}`); - if (deploymentTransaction !== null) { - await verifyDeployedContract(contractName, contractType, contractAddress, deploymentTransaction, constructorArgs, sourceFileContract); - } - } + + logger.info(`Checking ${contractName} deployment state...`); + + const isDeployed = deploymentState.isDeployed(contractName); + if(!isDeployed) { + logger.info(`Adding ${contractName} of type ${contractType} to deployment state...`); + // deploymet state is not set yet + deploymentState.setDeploymentTransaction(contractName, contractType, deploymentTransaction?.hash || "0x", libraries); + deploymentState.setContractAddress(contractName, deployedContractAddress); + logger.info(`${contractName} set deployed at ${deployedContractAddress}`); + await verifyDeployedContract(contractName, contractType, deployedContractAddress, deploymentTransaction, constructorArgs, sourceFileContract); + return; + } + + logger.info(`${contractName} is already in deployment state`); + logger.info(`${contractName} deployed at ${deployedContractAddress}`); + //logger.info(`Checking ${contractName} verification...`); + + const isVerified = deploymentState.isDeployedAndVerified(contractName); + if(!isVerified) { + await verifyDeployedContract(contractName, contractType, deployedContractAddress, deploymentTransaction, constructorArgs, sourceFileContract); + return; } + + logger.info(`${contractName} is already verified`); } export function delay(ms: number): Promise { @@ -169,7 +223,7 @@ export function delay(ms: number): Promise { } async function executeAllDeploymentSteps(contractName: string, contractType: string, signer: Signer, constructorArgs?: any[] | undefined, factoryOptions?: any | undefined, sourceFileContract?: string): Promise { - logger.info(`Deploying ${contractName}.sol...`); + logger.info(`Deploying ${contractName} of type ${contractType}...`); const factoryArgs = factoryOptions != undefined ? { ...factoryOptions, signer } : { signer }; const contractFactory = await ethers.getContractFactory(contractType, factoryArgs); @@ -204,19 +258,17 @@ async function executeAllDeploymentSteps(contractName: string, contractType: str async function verifyDeployedContract(contractName: string, contractType: string, address: AddressLike, tx: TransactionResponse, constructorArgs?: any[] | undefined, sourceFileContract?: string) { // Tenderly verification - // TODO skip if not tenderly network.. - // TODO libraries are in `${ARTIFACTS_PATH}${contractName}.json` - const libraries = deploymentState.getLibraries(contractName); - logger.info(`Verifing ${contractName}`) - await tenderly.verify({ - name: contractType, - address: address, - libraries: libraries}); - - deploymentState.setVerified(contractName, true); + if (process.env.ENABLE_TENDERLY_VERIFICATION?.toLowerCase() === "true") { + const libraries = deploymentState.getLibraries(contractName); + logger.info(`Verifing ${contractName}`) + await tenderly.verify({name: contractType, address: address, libraries: libraries}); + deploymentState.setVerified(contractName, true); + } else { + logger.debug("Skipping Tenderly verification"); + } // Etherscan verification - if (process.env.SKIP_VERIFICATION?.toLowerCase() !== "true") { + if (process.env.ENABLE_ETHERSCAN_VERIFICATION?.toLowerCase() === "true") { logger.debug(`Waiting for ${NUMBER_OF_CONFIRMATIONS} confirmations`); await tx.wait(NUMBER_OF_CONFIRMATIONS); constructorArgs !== undefined @@ -224,7 +276,7 @@ async function verifyDeployedContract(contractName: string, contractType: string : await verifyContract(address, [], sourceFileContract); deploymentState.setVerified(contractName, true); } else { - logger.debug("Skipping verification (etherscan)"); + logger.debug("Skipping Etherscan verification"); } } diff --git a/scripts/libs/deployment_state.ts b/scripts/libs/deployment_state.ts index 42a2f3636..e5871867c 100644 --- a/scripts/libs/deployment_state.ts +++ b/scripts/libs/deployment_state.ts @@ -27,12 +27,39 @@ export class DeploymentState { this.state = preloadedState ?? { contracts: [] }; } + // Contract deployment states: + // Not deployed -> name and deployment transaction not exists, it can be perfectlly valid) + // Deploying -> name and deployment transaction exists -> tx sent + // Deployed -> name, deployment transaction, address exists > tx mined + // Verified -> name, deployment transaction, address exists, verified set to true + public isDeploying(contractName: string): boolean { + const contractState = this.state.contracts.find(c => c.name === contractName); + if (contractState === undefined) { + return false; + } + return contractState.deploymentTransaction !== undefined && contractState.address === undefined; + } + + public isDeployed(contractName: string): boolean { + const contractState = this.state.contracts.find(c => c.name === contractName); + if (contractState === undefined) { + return false; + } + return contractState.deploymentTransaction !== undefined && contractState.address !== undefined; + } + public isDeployedAndVerified(contractName: string): boolean { const contractState = this.state.contracts.find(c => c.name === contractName); if (contractState === undefined) { return false; } - return contractState.address !== undefined && contractState.verified && contractState.deploymentTransaction !== undefined; + return contractState.deploymentTransaction !== undefined && contractState.address !== undefined && contractState.verified; + } + + public requireDeployed(contractName: string) { + if(!this.isDeployed(contractName)) { + throw new Error(`DeploymentState: ${contractName} is not deployed`); + } } public getContractAddress(contractName: string): string | undefined { @@ -58,19 +85,16 @@ export class DeploymentState { } return contractState.libraries; } - - public isContractDeployed(contractName: string): boolean { - const contractState = this.state.contracts.find(c => c.name === contractName); - if (contractState === undefined) { - return false; - } - return contractState.address !== undefined; +/* TODO consider taking libraries from artifacts + public getLibrariesFromArtifacts(contractName: string): any | undefined { + } +*/ - public setDeploymentTransaction(contractName: string, contractType: string, deploymentTransaction: string, libraries?: any | undefined): void { + public setDeploymentTransaction(contractName: string, contractType: string, deploymentTransaction: string, libraries?: any | undefined, initializable?: boolean | undefined): void + { const contractState = this.state.contracts.find(c => c.name === contractName); if (contractState === undefined) { - logger.debug(`Contract state not found for ${contractName}`); this.state.contracts.push({ name: contractName, type: contractType, @@ -79,30 +103,40 @@ export class DeploymentState { libraries: libraries, verified: false }); + logger.debug(`DeploymentState: ${contractName} state is created`); } else { + logger.debug(`DeploymentState: ${contractName} state already exists`); + if(contractState.type != contractType) { + throw new Error(`DeploymentState: ${contractName} type mismatch, expected ${contractState.type}, got ${contractType}`); + } contractState.deploymentTransaction = deploymentTransaction; contractState.libraries = libraries; - contractState.type = contractType; + // set rest params to initial values? -> new transaction means new address and new verification + logger.debug(`DeploymentState: ${contractName} state is updated`); } this.persistState(); } public setContractAddress(contractName: string, contractAddress: string): void { const contractState = this.state.contracts.find(c => c.name === contractName); + // TODO check deploymentTransaction is set if (contractState === undefined) { - throw new Error("Contract state not found"); + throw new Error(`DeploymentState: ${contractName} state not found`); } else { contractState.address = contractAddress; + logger.debug(`DeploymentState: ${contractName} address updated`); } this.persistState(); } public setVerified(contractName: string, verified: boolean): void { const contractState = this.state.contracts.find(c => c.name === contractName); + // TODO check deploymentTransaction is set if (contractState === undefined) { - throw new Error("Contract state not found"); + throw new Error(`DeploymentState: ${contractName} state not found`); } else { contractState.verified = verified; + logger.debug(`DeploymentState: ${contractName} verifiacation updated`); } this.persistState(); } diff --git a/scripts/libs/instance.ts b/scripts/libs/instance.ts index 40ac6b050..bb7a73167 100644 --- a/scripts/libs/instance.ts +++ b/scripts/libs/instance.ts @@ -1,11 +1,11 @@ import { tenderly } from "hardhat"; import { AddressLike, Signer, ethers, resolveAddress } from "ethers"; -import { BundleManager, IRegistry__factory, Instance, Instance__factory, InstanceAdmin, InstanceService__factory, InstanceReader, AccessManagerExtendedInitializeable, InstanceStore, TimestampLib__factory } from "../../typechain-types"; +import { BundleManager, Instance, Instance__factory, InstanceAdmin, InstanceReader, AccessManagerExtendedInitializeable, InstanceStore } from "../../typechain-types"; import { logger } from "../logger"; import { deployContract } from "./deployment"; import { deploymentState } from "./deployment_state"; import { LibraryAddresses } from "./libraries"; -import { RegistryAddresses } from "./registry"; +import { CoreAddresses } from "./registry"; import { executeTx, getFieldFromLogs, getFieldFromTxRcptLogs } from "./transaction"; import { ServiceAddresses } from "./services"; @@ -16,19 +16,86 @@ export type InstanceAddresses = { instanceBundleManagerAddress: AddressLike, instanceStoreAddress: AddressLike, instanceAddress: AddressLike, - instanceNftId: string, + instanceNftId: bigint, } export const MASTER_INSTANCE_OWNER = ethers.getAddress("0x0000000000000000000000000000000000000001"); +async function tryInitializeInstanceAccessManager(instanceAccessManager: AccessManagerExtendedInitializeable, owner: AddressLike) { + try { + await executeTx(() => instanceAccessManager.initialize(owner)); + } catch (error) { + logger.error(`Error initializing InstanceAccessManager at ${await instanceAccessManager.getAddress()}\n ${error}`); + } +} + +async function _tryInitializeInstance(instance: Instance, authority: AddressLike, registryAddress: AddressLike, owner: AddressLike) { + try { + await executeTx(() => instance.initialize(authority, registryAddress, owner)); + } catch (error) { + logger.error(`Error initializing Instance at ${await instance.getAddress()}\n ${error}`); + } +} + +async function _tryInitializeInstanceStore(instanceStore: InstanceStore, instanceAddress: AddressLike) { + try { + await executeTx(() => instanceStore.initialize(instanceAddress)); + } catch (error) { + logger.error(`Error initializing InstanceStore at ${await instanceStore.getAddress()}\n ${error}`); + } +} + +async function _tryInitializeInstanceReader(instanceReader: InstanceReader, instanceAddress: AddressLike) { + try { + await executeTx(() => instanceReader.initialize(instanceAddress)); + } catch (error) { + logger.error(`Error initializing InstanceStore at ${await instanceReader.getAddress()}\n ${error}`); + } +} + +async function _tryInitializeBundleManager(bundleManager: BundleManager, instanceAddress: AddressLike) { + try { + await executeTx(() => bundleManager.initialize(instanceAddress)); + } catch (error) { + logger.error(`Error initializing InstanceStore at ${await bundleManager.getAddress()}\n ${error}`); + } +} + +async function _trySetInstanceStore(instance: Instance, instanceStoreAddress: AddressLike) { + try { + await executeTx(() => instance.setInstanceStore(instanceStoreAddress)); + } catch (error) { + logger.error(`Error setting InstanceStore at ${instanceStoreAddress} in Instance ${await instance.getAddress()}\n ${error}`); + } +} + +async function _trySetInstanceReader(instance: Instance, instanceReaderAddress: AddressLike) { + try { + await executeTx(() => instance.setInstanceReader(instanceReaderAddress)); + } catch (error) { + logger.error(`Error setting InstanceStore at ${instanceReaderAddress} in Instance ${await instance.getAddress()}\n ${error}`); + } +} + +async function _trySetBundleManager(instance: Instance, bundleManagerAddress: AddressLike) { + try { + await executeTx(() => instance.setBundleManager(bundleManagerAddress)); + } catch (error) { + logger.error(`Error setting InstanceStore at ${bundleManagerAddress} in Instance ${await instance.getAddress()}\n ${error}`); + } +} + export async function deployAndRegisterMasterInstance( owner: Signer, libraries: LibraryAddresses, - registry: RegistryAddresses, + core: CoreAddresses, services: ServiceAddresses, ): Promise { + logger.info("======== Starting deployment of master instance ========"); + deploymentState.requireDeployed("InstanceServiceProxy"); + logger.info("---------- Master instance access manager ----------"); const { address: instanceAccessManagerAddress, contract: accessManagerBaseContract } = await deployContract( "InstanceAccessManager", "AccessManagerExtendedInitializeable", @@ -40,9 +107,13 @@ export async function deployAndRegisterMasterInstance( } } ) - const accessManager = accessManagerBaseContract as AccessManagerExtendedInitializeable; - await executeTx(() => accessManager.initialize(resolveAddress(owner))); + const instanceAccessManager = accessManagerBaseContract as AccessManagerExtendedInitializeable; + //await executeTx(() => instanceAccessManager.initialize(resolveAddress(owner))); + await tryInitializeInstanceAccessManager(instanceAccessManager, owner); + + + logger.info("---------- Master instance ----------"); const { address: instanceAddress, contract: masterInstanceBaseContract } = await deployContract( "Instance", "Instance", @@ -57,8 +128,12 @@ export async function deployAndRegisterMasterInstance( } ); const instance = masterInstanceBaseContract as Instance; - await executeTx(() => instance.initialize(instanceAccessManagerAddress, registry.registryAddress, resolveAddress(owner))); + //await executeTx(() => instance.initialize(instanceAccessManagerAddress, registry.registryAddress, resolveAddress(owner))); + await _tryInitializeInstance(instance, instanceAccessManagerAddress, core.registryAddress, owner); + + + logger.info("---------- Master instance store ----------"); const { address: instanceStoreAddress, contract: masterInstanceStoreContract } = await deployContract( "InstanceStore", "InstanceStore", @@ -81,9 +156,16 @@ export async function deployAndRegisterMasterInstance( } ); const instanceStore = masterInstanceStoreContract as InstanceStore; - await executeTx(() => instanceStore.initialize(instanceAddress)); - await executeTx(() => instance.setInstanceStore(instanceStore)); + //await executeTx(() => instanceStore.initialize(instanceAddress)); + await _tryInitializeInstanceStore(instanceStore, instanceAddress); + + //await executeTx(() => instance.setInstanceStore(instanceStore)); + await _trySetInstanceStore(instance, instanceStoreAddress); + + + + logger.info("---------- Master instance reader ----------"); const { address: instanceReaderAddress, contract: masterReaderBaseContract } = await deployContract( "InstanceReader", "InstanceReader", @@ -104,9 +186,16 @@ export async function deployAndRegisterMasterInstance( } ); const instanceReader = masterReaderBaseContract as InstanceReader; - await executeTx(() => instanceReader.initialize(instanceAddress)); - await executeTx(() => instance.setInstanceReader(instanceReaderAddress)); + //await executeTx(() => instanceReader.initialize(instanceAddress)); + await _tryInitializeInstanceReader(instanceReader, instanceAddress); + + //await executeTx(() => instance.setInstanceReader(instanceReaderAddress)); + await _trySetInstanceReader(instance, instanceReaderAddress); + + + + logger.info("---------- Master instance bundle manager ----------"); const {address: bundleManagerAddress, contract: bundleManagerBaseContrat} = await deployContract( "BundleManager", "BundleManager", @@ -120,9 +209,13 @@ export async function deployAndRegisterMasterInstance( } ); const bundleManager = bundleManagerBaseContrat as BundleManager; - await executeTx(() => bundleManager["initialize(address)"](instanceAddress)); - await executeTx(() => instance.setBundleManager(bundleManagerAddress)); + //await executeTx(() => bundleManager["initialize(address)"](instanceAddress)); + await _tryInitializeBundleManager(bundleManager, instanceAddress); + + //await executeTx(() => instance.setBundleManager(bundleManagerAddress)); + await _trySetBundleManager(instance, bundleManagerAddress) + logger.info("---------- Master instance admin ----------"); const { address: instanceAdminAddress, contract: instanceAdminBaseContract } = await deployContract( "InstanceAdmin", "InstanceAdmin", @@ -136,23 +229,49 @@ export async function deployAndRegisterMasterInstance( ); const instanceAdmin = instanceAdminBaseContract as InstanceAdmin; // grant admin role to master instance admin - await executeTx(() => accessManager.grantRole(0, instanceAdminAddress, 0)); - await executeTx(() => instanceAdmin.initialize(instanceAddress)); - await executeTx(() => instance.setInstanceAdmin(instanceAdmin)); + try{ + await executeTx(() => instanceAccessManager.grantRole(0, instanceAdminAddress, 0)); + } catch (error) { + logger.error(`Error granting admin role to InstanceAdmin at ${instanceAdminAddress}\n ${error}`); + } + + try{ + await executeTx(() => instanceAdmin.initialize(instanceAddress)); + } catch (error) { + logger.error(`Error initializing InstanceAdmin at ${instanceAdminAddress}\n ${error}`); + } + + try { + await executeTx(() => instance.setInstanceAdmin(instanceAdmin)); + } catch (error) { + logger.error(`Error setting InstanceAdmin at ${instanceAdminAddress} in Instance ${instanceAddress}\n ${error}`); + } - logger.debug(`setting master addresses into instance service and registering master instance`); - const rcpt = await executeTx(() => services.instanceService.setAndRegisterMasterInstance(instanceAddress)); - // this extracts the ObjectInfo struct from the LogRegistration event - const logRegistrationInfo = getFieldFromTxRcptLogs(rcpt!, registry.registry.interface, "LogRegistration", "nftId"); - // nftId is the first field of the ObjectInfo struct - const masterInstanceNfdId = (logRegistrationInfo as unknown); + logger.debug(`Setting master addresses for InstanceService and registering master Instance`); + let masterInstanceNfdId; + try { + const rcpt = await executeTx(() => services.instanceService.setAndRegisterMasterInstance(instanceAddress)); + // this extracts the ObjectInfo struct from the LogRegistration event + const logRegistrationInfo = getFieldFromTxRcptLogs(rcpt!, core.registry.interface, "LogRegistration", "nftId"); + // nftId is the first field of the ObjectInfo struct + masterInstanceNfdId = logRegistrationInfo as bigint; + } catch(error) { + logger.error(`Error setting and registering master instance at ${instanceAddress}\n ${error}`); + logger.error(`Trying to get master instance nftId from registry`); + masterInstanceNfdId = await core.registry["getNftId(address)"]( + services.instanceService.getMasterInstanceAddress()); + } - await executeTx(() => registry.chainNft.transferFrom(resolveAddress(owner), MASTER_INSTANCE_OWNER, BigInt(masterInstanceNfdId as string))); + try{ + // transfer NFT to master instance owner + await executeTx(() => core.chainNft.transferFrom(resolveAddress(owner), MASTER_INSTANCE_OWNER, BigInt(masterInstanceNfdId))); - // revoke admin role for master instance admin - await executeTx(() => accessManager.revokeRole(0, instanceAdminAddress)); - // revoke admin role for protocol owner - await executeTx(() => accessManager.renounceRole(0, owner)); + // revoke admin role from all members + await executeTx(() => instanceAccessManager.revokeRole(0, instanceAdminAddress)); + await executeTx(() => instanceAccessManager.renounceRole(0, owner)); + } catch(error) { + logger.error(`Error transferring NFT to master instance owner\n ${error}`); + } logger.info(`master instance registered - masterInstanceNftId: ${masterInstanceNfdId}`); logger.info(`master addresses set`); @@ -171,25 +290,34 @@ export async function deployAndRegisterMasterInstance( } // !!! TODO in addition: DO NOT DEPLOY WHOLE FRAMEWORK EACH TIME, RESUME DEPLOYMENT BASED ON DEPLOYMENT STATE OR ONCHAIN STATE -// if onchain state: +// if onchain state use for resumable deployment: // then each chain must have at same predefined address with/which .... info about // deployment script knows where to start resumable deployment -export async function cloneInstance(instanceServiceAddress: AddressLike, instanceOwner: Signer, releaseVersion : string) : Promise { +// can receive release object and extract instance service from there +export async function cloneInstance( + instanceOwner: Signer, + services: ServiceAddresses, +) : Promise { logger.info("======== Starting cloning of instance ========"); - const instanceService = InstanceService__factory.connect(await resolveAddress(instanceServiceAddress), instanceOwner); + const instanceService = services.instanceService.connect(instanceOwner); + const instanceServiceAddress = services.instanceServiceAddress; const instanceServiceVersion = await instanceService.getMajorVersion(); + const instanceServiceOwner = await instanceService.getOwner(); const masterInstanceAddress = await instanceService.getMasterInstanceAddress(); logger.info(`instance service address: ${instanceServiceAddress}`); logger.info(`instance service major version: ${instanceServiceVersion}`); + logger.info(`instance service owner: ${instanceServiceOwner}`); logger.info(`master instance address: ${masterInstanceAddress}`); logger.debug(`------- cloning instance ${masterInstanceAddress} --------`); const cloneTx = await executeTx(async () => await instanceService.createInstanceClone()); - const clonedInstanceAccessManagerAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedOzAccessManager"); + // get whole InstanceAddresses object in one call..? + const clonedInstanceAccessManagerAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceAccessManager"); const clonedInstanceAdminAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceAdmin") as AddressLike; const clonedInstanceAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstance") as string; + const clonedInstanceStoreAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceStore") as string; const clonedBundleManagerAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedBundleManager"); const clonedInstanceReaderAddress = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceReader"); const clonedInstanceNftId = getFieldFromLogs(cloneTx.logs, instanceService.interface, "LogInstanceCloned", "clonedInstanceNftId"); @@ -197,90 +325,122 @@ export async function cloneInstance(instanceServiceAddress: AddressLike, instanc const clonedInstance = Instance__factory.connect(clonedInstanceAddress, instanceOwner); const clonedlInstanceVersion = await clonedInstance.getMajorVersion(); const clonedInstanceOwner = await clonedInstance.getOwner(); + + logger.info(`cloned instance address: ${clonedInstanceAddress}`); logger.info(`cloned instance major version: ${clonedlInstanceVersion}`); - logger.info(`cloned instance owner: ${clonedInstanceOwner}`); + logger.info(`cloned instance initial owner: ${clonedInstanceOwner}`); + logger.info(`cloned instance nftId: ${clonedInstanceNftId}`); + + logger.info("======== Finished cloning of instance ========"); - logger.info("Verifying cloned instance access manager"); + return { + instanceAccessManagerAddress: clonedInstanceAccessManagerAddress, + instanceAdminAddress: clonedInstanceAdminAddress, + instanceAddress: clonedInstanceAddress, + instanceStoreAddress: clonedInstanceStoreAddress, + instanceBundleManagerAddress: clonedBundleManagerAddress, + instanceReaderAddress: clonedInstanceReaderAddress, + instanceNftId: clonedInstanceNftId, + } as InstanceAddresses; +} + +export async function verifyInstance(instanceAddresses: InstanceAddresses, libraries: LibraryAddresses) { + const { + instanceAccessManagerAddress, + instanceAdminAddress, + instanceAddress, + instanceStoreAddress, + instanceBundleManagerAddress, + instanceReaderAddress, + instanceNftId + } = instanceAddresses; + + // move all verifications into separate function used here and in master instance verification + /*logger.info("Verifying cloned instance access manager"); const libraries = deploymentState.getLibraries("AccessManagerExtendedInitializeable"); if(libraries === undefined) { throw new Error("Libraries not found in deployment state"); - } + }*/ logger.info("Verifying cloned instance access manager"); - await tenderly.verify({ - name: "AccessManagerExtendedInitializeable", - address: clonedInstanceAccessManagerAddress, + /*verifyDeployedContract( + "InstanceAccessMnager", + "AccessManagerExtendedInitializeable"// contractType - minimal proxy + instanceAccessManagerAddress, + tx: TransactionResponse, + constructorArgs?: any[] | undefined, + sourceFileContract?: string + );*/ + /*await tenderly.verify({ + name: "InstanceAccessMnager", + address: instanceAccessManagerAddress, libraries: { TimestampLib: libraries.timestampLibAddress, } }); + logger.info("Verifying cloned instance admin"); - /*await deployContract( - "InstanceAdmin", - owner, - [], - { libraries: { - RoleIdLib: libraries.roleIdLibAddress - }});*/ await tenderly.verify({ name: "InstanceAdmin", - address: clonedInstanceAdminAddress, + address: instanceAdminAddress, libraries: { RoleIdLib: libraries.roleIdLibAddress }}); + logger.info("Verifying cloned instance"); await tenderly.verify({ name: "Instance", - address: clonedInstanceAddress, + address: instanceAddress, libraries: { NftIdLib: libraries.nftIdLibAddress, VersionPartLib: libraries.versionPartLibAddress, RoleIdLib: libraries.roleIdLibAddress, } }); - logger.info("Verifying cloned instance reader"); + + logger.info("Verify cloned instance store"); await tenderly.verify({ - name: "InstanceReader", - address: clonedInstanceReaderAddress, + name: "InstanceStore", + address: instanceStoreAddress, libraries: { AmountLib: libraries.amountLibAddress, + BlocknumberLib: libraries.blockNumberLibAddress, + Key32Lib: libraries.key32LibAddress, + NftIdLib: libraries.nftIdLibAddress, + ObjectTypeLib: libraries.objectTypeLibAddress, + RiskIdLib: libraries.riskIdLibAddress, + StateIdLib: libraries.stateIdLibAddress, ClaimIdLib: libraries.claimIdLibAddress, DistributorTypeLib: libraries.distributorTypeLibAddress, - NftIdLib: libraries.nftIdLibAddress, PayoutIdLib: libraries.payoutIdLibAddress, - ReferralLib: libraries.referralLibAddress, - RiskIdLib: libraries.riskIdLibAddress, - TimestampLib: libraries.timestampLibAddress, - UFixedLib: libraries.uFixedLibAddress, + ReferralLib: libraries.referralLibAddress + } + }); + + logger.info("Verifying cloned instance reader"); + await tenderly.verify({ + name: "InstanceReader", + address: instanceReaderAddress, + libraries: { + AmountLib: libraries.amountLibAddress, + ClaimIdLib: libraries.claimId } }); + logger.info("Verifying cloned bundle manager"); await tenderly.verify({ name: "BundleManager", - address: clonedBundleManagerAddress, + address: instanceBundleManagerAddress, libraries: { NftIdLib: libraries.nftIdLibAddress, LibNftIdSet: libraries.libNftIdSetAddress, } }); - - logger.info(`instance cloned - clonedInstanceNftId: ${clonedInstanceNftId}`); - - logger.info("======== Finished cloning of instance ========"); - - return { - instanceAccessManagerAddress: clonedInstanceAccessManagerAddress, - instanceAdminAddress: clonedInstanceAdminAddress, - instanceAddress: clonedInstanceAddress, - instanceBundleManagerAddress: clonedBundleManagerAddress, - instanceReaderAddress: clonedInstanceReaderAddress, - instanceNftId: clonedInstanceNftId as string, - } as InstanceAddresses;*/ + */ } - -export async function cloneInstanceFromRegistry(registryAddress: AddressLike, instanceOwner: Signer/*, releaseVersion: string*/): Promise { - const registry = IRegistry__factory.connect(await resolveAddress(registryAddress), instanceOwner); +export async function cloneInstanceFromRegistry(instanceOwner: Signer, core: CoreAddresses, services: ServiceAddresses): Promise { + const registry = core.registry.connect();// read only const instanceServiceDomain = 70; - const instanceServiceAddress = await registry.getServiceAddress(instanceServiceDomain, "3"); - return cloneInstance(instanceServiceAddress, instanceOwner); + services.instanceServiceAddress = await registry.getServiceAddress(instanceServiceDomain, "3"); + return cloneInstance(instanceOwner, services); } \ No newline at end of file diff --git a/scripts/libs/libraries.ts b/scripts/libs/libraries.ts index 3a5cf996c..f888f5774 100644 --- a/scripts/libs/libraries.ts +++ b/scripts/libs/libraries.ts @@ -31,7 +31,7 @@ export type LibraryAddresses = { export const LIBRARY_ADDRESSES: Map = new Map(); -export async function deployLibraries(owner: Signer): Promise { +export async function deployLibraries(owner: Signer): Promise { logger.info("======== Starting deployment of libraries ========"); const { address: key32LibAddress } = await deployContract( "Key32Lib", @@ -301,6 +301,6 @@ export async function deployLibraries(owner: Signer): Promise serviceAuthorizationsLibAddress, targetManagerLibAddress, stakeManagerLibAddress, - }; + } as LibraryAddresses; } \ No newline at end of file diff --git a/scripts/libs/registry.ts b/scripts/libs/registry.ts index bf713e647..62b49710e 100644 --- a/scripts/libs/registry.ts +++ b/scripts/libs/registry.ts @@ -1,4 +1,4 @@ -import { AddressLike, Signer, TransactionResponse, resolveAddress } from "ethers"; +import { AddressLike, Signer, TransactionResponse, assert, resolveAddress } from "ethers"; import { Dip, ChainNft, ChainNft__factory, @@ -14,13 +14,13 @@ import { } from "../../typechain-types"; import { logger } from "../logger"; import { deployContract, addDeployedContract, verifyContract } from "./deployment"; -import { deploymentState } from "./deployment_state"; +import { deploymentState, isResumeableDeployment } from "./deployment_state"; import { LibraryAddresses } from "./libraries"; import { getFieldFromTxRcptLogs, executeTx } from "./transaction"; import { tenderly } from "hardhat"; -export type RegistryAddresses = { +export type CoreAddresses = { dipAddress: AddressLike; dip: Dip; @@ -55,7 +55,7 @@ export type RegistryAddresses = { stakingNftId: bigint; } -export async function deployAndInitializeRegistry(owner: Signer, libraries: LibraryAddresses): Promise { +export async function deployCore(owner: Signer, libraries: LibraryAddresses): Promise { logger.info("======== Starting deployment of registry ========"); logger.info("-------- Starting deployment DIP ----------------"); @@ -90,7 +90,8 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr RoleIdLib: libraries.roleIdLibAddress, TimestampLib: libraries.timestampLibAddress, } - }); + }, + ); const registryAdmin = registryAdminBaseContract as RegistryAdmin; const accessManagerAddress = await registryAdmin.authority(); @@ -99,7 +100,6 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr "RegistryAccessManager", "AccessManagerExtendedInitializeable", accessManagerAddress, - owner, //signer registryAdminDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -124,7 +124,9 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr NftIdLib: libraries.nftIdLibAddress, ObjectTypeLib: libraries.objectTypeLibAddress, } - }); + }, + + ); const registry = registryBaseContract as Registry; const registryNftId = await registry["getNftId(address)"](registryAddress); @@ -136,7 +138,6 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr "ChainNft", "ChainNft", chainNftAddress, - owner, //signer registryDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -193,7 +194,8 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr libraries: { NftIdLib: libraries.nftIdLibAddress, } - }); + }, + ); const stakingReader = stakingReaderBaseContract as StakingReader; @@ -253,20 +255,45 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr const stakingNftId = await registry["getNftId(address)"](stakingAddress); logger.info(`StakingReader deployed at ${stakingReaderAddress}`); - // revert here if resumable deployment is true -> can be already intialized - await executeTx(async () => await stakingReader.initialize(stakingAddress, stakingStoreAddress)); - - await executeTx(async () => await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress)); - await executeTx(async () =>await registryAdmin.initialize(registry, owner, owner)); - - //await verifyRegistryComponents(registryAddress, owner) + if(!isResumeableDeployment) { + await executeTx(async () => await stakingReader.initialize(stakingAddress, stakingStoreAddress)); + logger.info("StakingReader initialized"); + await executeTx(async () => await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress)); + logger.info("Registry initialized"); + await executeTx(async () => await registryAdmin.initialize(registry, owner, owner)); + logger.info("RegistryAdmin initialized"); + } else { + try{ + await executeTx(async () => await stakingReader.initialize(stakingAddress, stakingStoreAddress)); + logger.info("StakingReader initialized"); + } catch (error) { + logger.error(`Error initializing StakingReader at ${await stakingReader.getAddress()}\n ${error}`); + logger.info("Assuming StakingReader is already initialized"); + } + + try{ + await executeTx(async () => await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress)); + logger.info("Registry initialized"); + } catch (error) { + logger.error(`Error initializing Registry at ${await registry.getAddress()}\n ${error}`); + logger.info("Assuming Registry is already initialized"); + } + + try{ + await executeTx(async () => await registryAdmin.initialize(registry, owner, owner)); + logger.info("RegistryAdmin initialized"); + } catch (error) { + logger.error(`Error initializing RegistryAdmin at ${await registryAdmin.getAddress()}\n ${error}`); + logger.info("Assuming RegistryAdmin is already initialized"); + } + } logger.info(`Dip deployed at ${dipAddress}`); - logger.info(`RegistryAdmin deployeqd at ${registryAdmin}`); + logger.info(`RegistryAdmin deployed at ${registryAdminAddress}`); logger.info(`Registry deployed at ${registryAddress}`); logger.info(`ChainNft deployed at ${chainNftAddress}`); - logger.info(`ReleaseManager deployed at ${releaseManager}`); + logger.info(`ReleaseManager deployed at ${releaseManagerAddress}`); logger.info(`TokenRegistry deployed at ${tokenRegistryAddress}`); logger.info(`StakingReader deployed at ${stakingReaderAddress}`); logger.info(`StakingStore deployed at ${stakingStoreAddress}`); @@ -314,8 +341,52 @@ export async function deployAndInitializeRegistry(owner: Signer, libraries: Libr }; } -async function verifyRegistryComponents(registryAddress: RegistryAddresses, owner: Signer) { - if (process.env.SKIP_VERIFICATION?.toLowerCase() === "true") { +async function _tryInitializeCore(core: CoreAddresses, owner: Signer) { + const registry = core.registry.connect(owner); + const registryAdmin = core.registryAdmin.connect(owner); + const stakingReader = core.stakingReader.connect(owner); + + const stakingAddress = core.stakingAddress; + const stakingStoreAddress = core.stakingStoreAddress; + const releaseManagerAddress = core.releaseManagerAddress; + const tokenRegistryAddress = core.tokenRegistryAddress; + + if(!isResumeableDeployment) { + await executeTx(async () => await stakingReader.initialize(stakingAddress, stakingStoreAddress)); + logger.info("StakingReader initialized"); + await executeTx(async () => await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress)); + logger.info("Registry initialized"); + await executeTx(async () => await registryAdmin.initialize(registry, owner, owner)); + logger.info("RegistryAdmin initialized"); + } else { + try{ + await executeTx(async () => await stakingReader.initialize(stakingAddress, stakingStoreAddress)); + logger.info("StakingReader initialized"); + } catch (error) { + logger.error(`Error initializing StakingReader at ${await stakingReader.getAddress()}\n ${error}`); + logger.info("Assuming StakingReader is already initialized"); + } + + try{ + await executeTx(async () => await registry.initialize(releaseManagerAddress, tokenRegistryAddress, stakingAddress)); + logger.info("Registry initialized"); + } catch (error) { + logger.error(`Error initializing Registry at ${await registry.getAddress()}\n ${error}`); + logger.info("Assuming Registry is already initialized"); + } + + try{ + await executeTx(async () => await registryAdmin.initialize(registry, owner, owner)); + logger.info("RegistryAdmin initialized"); + } catch (error) { + logger.error(`Error initializing RegistryAdmin at ${await registryAdmin.getAddress()}\n ${error}`); + logger.info("Assuming RegistryAdmin is already initialized"); + } + } +} + +async function verifyRegistryComponents(registryAddress: CoreAddresses, owner: Signer) { + if (process.env.ENABLE_ETHERSCAN_VERIFICATION?.toLowerCase() === "true") { return; } diff --git a/scripts/libs/release.ts b/scripts/libs/release.ts index cc578875a..21c988aee 100644 --- a/scripts/libs/release.ts +++ b/scripts/libs/release.ts @@ -1,10 +1,11 @@ -import { AddressLike, BytesLike, Signer, resolveAddress, AbiCoder, keccak256, hexlify, Interface, solidityPacked, solidityPackedKeccak256, getCreate2Address, defaultAbiCoder, id, concat, Typed, BigNumberish } from "ethers"; +import { AddressLike, BytesLike, Signer, resolveAddress, AbiCoder, keccak256, hexlify, Interface, solidityPacked, solidityPackedKeccak256, getCreate2Address, defaultAbiCoder, id, concat, Typed, BigNumberish, ContractTransactionReceipt } from "ethers"; import { logger } from "../logger"; -import { PoolService__factory, BundleService__factory, DistributionService__factory, InstanceService__factory, RegistryService__factory, ReleaseManager__factory } from "../../typechain-types"; -import { RegistryAddresses } from "./registry"; +import { ReleaseManager, PoolService__factory, BundleService__factory, DistributionService__factory, InstanceService__factory, RegistryService__factory, ReleaseManager__factory } from "../../typechain-types"; +import { CoreAddresses } from "./registry"; import { LibraryAddresses } from "./libraries"; import { executeTx, getFieldFromTxRcptLogs } from "./transaction"; +import { isResumeableDeployment, deploymentState } from "./deployment_state"; export type ReleaseAddresses = { @@ -144,7 +145,7 @@ export type Release = { }; // TODO implement release addresses computation -export async function computeReleaseAddresses(owner: Signer, registry: RegistryAddresses, libraries: LibraryAddresses, salt: BytesLike): Promise { +export async function computeReleaseAddresses(owner: Signer, registry: CoreAddresses, libraries: LibraryAddresses, salt: BytesLike): Promise { const releaseAddresses: ReleaseAddresses = { registryServiceAddress: "0x0000000000000000000000000000000000000001", @@ -179,7 +180,7 @@ export async function computeReleaseAddresses(owner: Signer, registry: RegistryA } -export async function getReleaseConfig(owner: Signer, registry: RegistryAddresses, libraries: LibraryAddresses, salt: BytesLike): Promise +export async function getReleaseConfig(owner: Signer, registry: CoreAddresses, libraries: LibraryAddresses, salt: BytesLike): Promise { const serviceAddresses = await computeReleaseAddresses(owner, registry, libraries, salt); @@ -336,27 +337,77 @@ export async function getReleaseConfig(owner: Signer, registry: RegistryAddresse return config; } -export async function createRelease(owner: Signer, registry: RegistryAddresses, config: ReleaseConfig, salt: BytesLike): Promise +async function _tryCreateNextRelease(releaseManager: ReleaseManager): Promise { - const releaseManager = await registry.releaseManager.connect(owner); - await releaseManager.createNextRelease(); + let rcpt; + try { + rcpt = await executeTx(async () => releaseManager.createNextRelease()); + } catch (error) { + logger.error(`Error creating release with ReleaseManager at ${await releaseManager.getAddress()}\n ${error}`); + } - const rcpt = await executeTx(async () => releaseManager.prepareNextRelease( - config.addresses, - config.names, - config.serviceRoles, - config.serviceRoleNames, - config.functionRoles, - config.functionRoleNames, - config.selectors, - salt - )); + return rcpt; +} +// TODO in case release already prepared -> read verson salt and accessManager +async function _tryPrepareNextRelease(releaseManager: ReleaseManager, config: ReleaseConfig, salt: BytesLike): Promise +{ + let rcpt; + try { + rcpt = await executeTx(async () => releaseManager.prepareNextRelease( + config.addresses, + config.names, + config.serviceRoles, + config.serviceRoleNames, + config.functionRoles, + config.functionRoleNames, + config.selectors, + salt + )); + } catch (error) { + logger.error(`Error preparing next release with ReleaseManager at ${await releaseManager.getAddress()}\n ${error}`); + } + + return rcpt; +} + +async function _tryActivateNextRelease(releaseManager: ReleaseManager): Promise +{ + let rcpt; + try { + rcpt = await executeTx(async () => releaseManager.activateNextRelease()); + } catch (error) { + logger.error(`Error activating release with ReleaseManager at ${await releaseManager.getAddress()}\n ${error}`); + } + + return rcpt; +} - let logCreationInfo = getFieldFromTxRcptLogs(rcpt!, registry.releaseManager.interface, "LogReleaseCreation", "version"); +export async function createRelease(releaseManager: ReleaseManager, config: ReleaseConfig, salt: BytesLike): Promise +{ + deploymentState.requireDeployed("ReleaseManager"); + + let rcpt; + if(!isResumeableDeployment) { + await executeTx(async () => releaseManager.createNextRelease()); + rcpt = await executeTx(async () => releaseManager.prepareNextRelease( + config.addresses, + config.names, + config.serviceRoles, + config.serviceRoleNames, + config.functionRoles, + config.functionRoleNames, + config.selectors, + salt)); + } else { + await _tryCreateNextRelease(releaseManager); + rcpt = await _tryPrepareNextRelease(releaseManager, config, salt); + } + // TODO in case of failed tx (already created release) fetch release version from releaseManager + let logCreationInfo = getFieldFromTxRcptLogs(rcpt!, releaseManager.interface, "LogReleaseCreation", "version"); const releaseVersion = (logCreationInfo as BigNumberish); - logCreationInfo = getFieldFromTxRcptLogs(rcpt!, registry.releaseManager.interface, "LogReleaseCreation", "salt"); + logCreationInfo = getFieldFromTxRcptLogs(rcpt!, releaseManager.interface, "LogReleaseCreation", "salt"); const releaseSalt = (logCreationInfo as BytesLike); - logCreationInfo = getFieldFromTxRcptLogs(rcpt!, registry.releaseManager.interface, "LogReleaseCreation", "accessManager"); + logCreationInfo = getFieldFromTxRcptLogs(rcpt!, releaseManager.interface, "LogReleaseCreation", "accessManager"); const releaseAccessManager = (logCreationInfo as AddressLike); const release: Release = { @@ -367,4 +418,17 @@ export async function createRelease(owner: Signer, registry: RegistryAddresses, }; return release; +} + +export async function activateRelease(releaseManager: ReleaseManager): Promise +{ + deploymentState.requireDeployed("ReleaseManager"); + + let rcpt; + + if(!isResumeableDeployment) { + rcpt = await executeTx(async () => releaseManager.activateNextRelease()); + } else { + rcpt = await _tryActivateNextRelease(releaseManager); + } } \ No newline at end of file diff --git a/scripts/libs/services.ts b/scripts/libs/services.ts index 49dfa72be..57d39d48d 100644 --- a/scripts/libs/services.ts +++ b/scripts/libs/services.ts @@ -1,8 +1,9 @@ -import { AddressLike, BytesLike, Signer, resolveAddress, id, TransactionResponse } from "ethers"; +import { AddressLike, BytesLike, Signer, resolveAddress, id, TransactionResponse, TransactionReceipt } from "ethers"; import { tenderly } from "hardhat"; -import { - ReleaseManager__factory, +import { + Registry, Registry__factory, + ReleaseManager, ReleaseManager__factory, ProxyManager, DistributionService, DistributionServiceManager, DistributionService__factory, InstanceService, InstanceServiceManager, InstanceService__factory, ComponentService, ComponentServiceManager, ComponentService__factory, @@ -18,10 +19,11 @@ import { } from "../../typechain-types"; import { logger } from "../logger"; import { deployContract, addDeployedContract } from "./deployment"; +import { deploymentState, isResumeableDeployment } from "./deployment_state"; import { LibraryAddresses } from "./libraries"; -import { RegistryAddresses } from "./registry"; +import { CoreAddresses } from "./registry"; import { executeTx, getFieldFromTxRcptLogs } from "./transaction"; -import { getReleaseConfig, createRelease } from "./release"; +import { getReleaseConfig, createRelease, activateRelease } from "./release"; export type ServiceAddresses = { @@ -86,25 +88,92 @@ export type ServiceAddresses = { bundleServiceManagerAddress: AddressLike } -export async function deployAndRegisterServices(owner: Signer, registry: RegistryAddresses, libraries: LibraryAddresses): Promise +// get service address from proxy manager then address -> name +async function registerService(owner: Signer, serviceName: string, serviceManager: ProxyManager, releaseManager: ReleaseManager): Promise +{ + deploymentState.requireDeployed(serviceName); + + const serviceAddress = deploymentState.getContractAddress(serviceName)!; + const registry = Registry__factory.connect(await releaseManager.getRegistry(), owner); + let rcpt; + + if(!isResumeableDeployment) { + logger.info(`Registering new ${serviceName}`); + rcpt = await executeTx(async () => await releaseManager.registerService(serviceAddress)); + logger.debug(`${serviceName} is registered`); + serviceManager.linkToProxy(); + } else { + logger.info(`Trying to register ${serviceName}`); + + const isRegistered = await registry["isRegistered(address)"](serviceAddress); + if(!isRegistered) { + //serviceNftId = await _tryRegisterService(serviceName, releaseManager); + //logger.debug(`${serviceName} is registered`); + //_tryLinkToProxy(serviceManager); + rcpt = await executeTx(async () => await releaseManager.registerService(serviceAddress)); + logger.debug(`${serviceName} is registered`); + serviceManager.linkToProxy(); + } else { + logger.info(`${serviceName} is already registered`); + logger.info(`Assume service manager is already linked`); + return await registry["getNftId(address)"](serviceAddress) as string; + } + } + + const serviceNftId = getFieldFromTxRcptLogs(rcpt!, registry.interface, "LogRegistration", "nftId") as string; + return serviceNftId; +} +/* +async function _tryLinkToProxy(proxyManager: ProxyManager): Promise { + let rcpt; + try { + rcpt = await executeTx(async () => await proxyManager.linkToProxy()); + } catch (error) { + logger.error(`Error linking to proxy with proxy manager ${await proxyManager.getAddress()}\n ${error}`); + } finally { + return rcpt; + } +} + +async function _tryRegisterService(serviceName: string, releaseManager: ReleaseManager): Promise +{ + let serviceNftId; + let rcpt; + const registry = Registry__factory.connect(await releaseManager.getRegistry()); + const serviceAddress = deploymentState.getContractAddress(serviceName)!; + + try{ + rcpt = await executeTx(async () => await releaseManager.registerService(serviceAddress)); + const logRegistrationInfo = getFieldFromTxRcptLogs(rcpt!, registry.interface, "LogRegistration", "nftId"); + serviceNftId = (logRegistrationInfo as unknown); + } catch (error) { + logger.error(`Error registering ${serviceName} at ${serviceAddress} with ReleaseManager ${await releaseManager.getAddress()} and Registry ${await registry.getAddress()}\n ${error}`); + } finally { + return ({ nftId: serviceNftId, receipt: rcpt }); + } +} +*/ + +export async function deployRelease(owner: Signer, registry: CoreAddresses, libraries: LibraryAddresses): Promise { logger.info("======== Starting release creation ========"); + const registryContract = registry.registry.connect(owner); + const releaseManager = registry.releaseManager.connect(owner); //const salt = zeroPadBytes("0x03", 32); const salt: BytesLike = id(`0x5678`); const config = await getReleaseConfig(owner, registry, libraries, salt); - const release = await createRelease(owner, registry, config, salt); + const release = await createRelease(releaseManager, config, salt); logger.info(`Release created - version: ${release.version} salt: ${release.salt} access manager: ${release.accessManager}`); logger.info("======== Starting deployment of services ========"); - const releaseManager = await registry.releaseManager.connect(owner); logger.info("-------- registry service --------"); const { address: registryServiceManagerAddress, contract: registryServiceManagerBaseContract, deploymentTransaction: registryServiceManagerDeploymentTransaction } = await deployContract( - "RegistryServiceManager", - "RegistryServiceManager", + "RegistryServiceManager", // name + "RegistryServiceManager", // type owner, [ release.accessManager, // release access manager address it self can be a salt like value @@ -123,14 +192,11 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const registryServiceImplementationAddress = await registryServiceManager.getImplementation(); const registryService = RegistryService__factory.connect(registryServiceAddress, owner); - logger.info("Verifying registry service implementation"); - // TODO await addDeployedContract( - "RegistryService", + "RegistryServiceImplementation", "RegistryService", registryServiceImplementationAddress, - owner, //signer - registryServiceManagerDeploymentTransaction as TransactionResponse,// deploymentTransaction, + registryServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { libraries: { @@ -140,12 +206,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying registry service proxy"); await addDeployedContract( "RegistryServiceProxy", "UpgradableProxyWithAdmin", registryServiceAddress, - owner, //signer registryServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -153,10 +217,11 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptRs = await executeTx(async () => await releaseManager.registerService(registryServiceAddress)); - const logRegistrationInfoRs = getFieldFromTxRcptLogs(rcptRs!, registry.registry.interface, "LogRegistration", "nftId"); - const registryServiceNfdId = (logRegistrationInfoRs as unknown); - logger.info(`registryServiceManager deployed - registryServiceAddress: ${registryServiceAddress} registryServiceManagerAddress: ${registryServiceManagerAddress} nftId: ${registryServiceNfdId}`); + const registryServiceNftId = await registerService(owner, "RegistryServiceProxy", registryServiceManager, releaseManager); + + logger.info(`RegistryServiceManager deployed - registryServiceAddress: ${registryServiceAddress} registryServiceManagerAddress: ${registryServiceManagerAddress} NftId: ${registryServiceNftId}`); + + logger.info("-------- staking service --------"); const { @@ -186,25 +251,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const stakingServiceImplementationAddress = await stakingServiceManager.getImplementation(); const stakingService = StakingService__factory.connect(stakingServiceAddress, owner); - logger.info("Verifying staking service implementation"); - /* - await deployContract( - "StakingService", - owner, - [], - { libraries: { - NftIdLib: libraries.nftIdLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - StakeManagerLib: libraries.stakeManagerLibAddress, - TargetManagerLib: libraries.targetManagerLibAddress, - }}); - */ await addDeployedContract( - "StakingService", + "StakingServiceImplementation", "StakingService", stakingServiceImplementationAddress, - owner, //signer stakingServiceManagerDeploymentTransaction as TransactionResponse,// deploymentTransaction, [],// constructor args { @@ -217,12 +267,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying staking service proxy"); await addDeployedContract( "StakingServiceProxy", "UpgradableProxyWithAdmin", stakingServiceAddress, - owner, //signer stakingServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -230,12 +278,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptStk = await executeTx(async () => await releaseManager.registerService(stakingServiceAddress)); - const logRegistrationInfoStk = getFieldFromTxRcptLogs(rcptStk!, registry.registry.interface, "LogRegistration", "nftId"); - const stakingServiceNftId = (logRegistrationInfoStk as unknown); - await stakingServiceManager.linkToProxy(); + const stakingServiceNftId = await registerService(owner, "StakingServiceProxy", stakingServiceManager, releaseManager); + logger.info(`stakingServiceManager deployed - stakingServiceAddress: ${stakingServiceAddress} stakingServiceManagerAddress: ${stakingServiceManagerAddress} nftId: ${stakingServiceNftId}`); + + logger.info("-------- instance service --------"); const { address: instanceServiceManagerAddress, @@ -265,26 +313,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const instanceServiceImplementationAddress = await instanceServiceManager.getImplementation(); const instanceService = InstanceService__factory.connect(instanceServiceAddress, owner); - logger.info("Verifying instance service implementation"); - /* - await deployContract( - "InstanceService", - owner, - [], - { libraries: { - NftIdLib: libraries.nftIdLibAddress, - RoleIdLib: libraries.roleIdLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - InstanceAuthorizationsLib: libraries.instanceAuthorizationsLibAddress, - TargetManagerLib: libraries.targetManagerLibAddress, - }}); - */ await addDeployedContract( - "InstanceService", + "InstanceServiceImplementation", "InstanceService", instanceServiceImplementationAddress, - owner, //signer instanceServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -298,12 +330,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying instance service proxy"); await addDeployedContract( "InstanceServiceProxy", "UpgradableProxyWithAdmin", instanceServiceAddress, - owner, //signer instanceServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -311,11 +341,11 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptInst = await executeTx(async () => await releaseManager.registerService(instanceServiceAddress)); - const logRegistrationInfoInst = getFieldFromTxRcptLogs(rcptInst!, registry.registry.interface, "LogRegistration", "nftId"); - const instanceServiceNfdId = (logRegistrationInfoInst as unknown); - await instanceServiceManager.linkToProxy(); - logger.info(`instanceServiceManager deployed - instanceServiceAddress: ${instanceServiceAddress} instanceServiceManagerAddress: ${instanceServiceManagerAddress} nftId: ${instanceServiceNfdId}`); + const instanceServiceNftId = await registerService(owner, "InstanceServiceProxy", instanceServiceManager, releaseManager); + + logger.info(`instanceServiceManager deployed - instanceServiceAddress: ${instanceServiceAddress} instanceServiceManagerAddress: ${instanceServiceManagerAddress} nftId: ${instanceServiceNftId}`); + + logger.info("-------- component service --------"); const { @@ -342,24 +372,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const componentServiceImplementationAddress = await componentServiceManager.getImplementation(); const componentService = ComponentService__factory.connect(componentServiceAddress, owner); - logger.info("Verifying component service implementation"); - /*await deployContract( - "ComponentService", - owner, - [], - { libraries: { - NftIdLib: libraries.nftIdLibAddress, - AmountLib: libraries.amountLibAddress, - FeeLib: libraries.feeLibAddress, - RoleIdLib: libraries.roleIdLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }});*/ await addDeployedContract( - "ComponentService", + "ComponentServiceImplementation", "ComponentService", componentServiceImplementationAddress, - owner, //signer componentServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -373,12 +389,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying component service proxy"); await addDeployedContract( "ComponentServiceProxy", "UpgradableProxyWithAdmin", componentServiceAddress, - owner, //signer componentServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -386,12 +400,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); + const componentServiceNftId = await registerService(owner, "ComponentServiceProxy", componentServiceManager, releaseManager); - const rcptCmpt = await executeTx(async () => await releaseManager.registerService(componentServiceAddress)); - const logRegistrationInfoCmpt = getFieldFromTxRcptLogs(rcptCmpt!, registry.registry.interface, "LogRegistration", "nftId"); - const componentServiceNftId = (logRegistrationInfoCmpt as unknown); logger.info(`componentServiceManager deployed - componentServiceAddress: ${componentServiceAddress} componentServiceManagerAddress: ${componentServiceManagerAddress} nftId: ${componentServiceNftId}`); + + logger.info("-------- distribution service --------"); const { address: distributionServiceManagerAddress, @@ -422,28 +436,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const distributionServiceImplementationAddress = await distributionServiceManager.getImplementation(); const distributionService = DistributionService__factory.connect(distributionServiceAddress, owner); - logger.info("Verifying distribution service implementation"); - /* - await deployContract( - "DistributionService", - owner, - [], - { libraries: { - AmountLib: libraries.amountLibAddress, - DistributorTypeLib: libraries.distributorTypeLibAddress, - NftIdLib: libraries.nftIdLibAddress, - ReferralLib: libraries.referralLibAddress, - TimestampLib: libraries.timestampLibAddress, - UFixedLib: libraries.uFixedLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "DistributionService", + "DistributionServiceImplementation", "DistributionService", distributionServiceImplementationAddress, - owner, //signer distributionServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -459,12 +455,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying distribution service proxy"); await addDeployedContract( "DistributionServiceProxy", "UpgradableProxyWithAdmin", distributionServiceAddress, - owner, //signer distributionServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -472,12 +466,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptDs = await executeTx(async () => await releaseManager.registerService(distributionServiceAddress)); - const logRegistrationInfoDs = getFieldFromTxRcptLogs(rcptDs!, registry.registry.interface, "LogRegistration", "nftId"); - const distributionServiceNftId = (logRegistrationInfoDs as unknown); - await distributionServiceManager.linkToProxy(); + const distributionServiceNftId = await registerService(owner, "DistributionServiceProxy", distributionServiceManager, releaseManager, registryContract); + logger.info(`distributionServiceManager deployed - distributionServiceAddress: ${distributionServiceAddress} distributionServiceManagerAddress: ${distributionServiceManagerAddress} nftId: ${distributionServiceNftId}`); + + logger.info("-------- pricing service --------"); const { address: pricingServiceManagerAddress, @@ -506,25 +500,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const pricingServiceImplementationAddress = await pricingServiceManager.getImplementation(); const pricingService = PricingService__factory.connect(pricingServiceAddress, owner); - logger.info("Verifying pricing service implementation"); - /* - await deployContract( - "PricingService", - owner, - [], - { libraries: { - NftIdLib: libraries.nftIdLibAddress, - AmountLib: libraries.amountLibAddress, - UFixedLib: libraries.uFixedLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "PricingService", + "PricingServiceImplementation", "PricingService", pricingServiceImplementationAddress, - owner, //signer pricingServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -537,12 +516,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying pricing service proxy"); await addDeployedContract( "PricingServiceProxy", "UpgradableProxyWithAdmin", pricingServiceAddress, - owner, //signer pricingServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -550,11 +527,11 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptPrs = await executeTx(async () => await releaseManager.registerService(pricingServiceAddress)); - const logRegistrationInfoPrs = getFieldFromTxRcptLogs(rcptPrs!, registry.registry.interface, "LogRegistration", "nftId"); - const pricingServiceNftId = (logRegistrationInfoPrs as unknown); - await pricingServiceManager.linkToProxy(); - logger.info(`pricingServiceManager deployed - pricingServiceAddress: ${pricingServiceAddress} pricingServiceManagerAddress: ${pricingServiceManagerAddress} nftId: ${pricingServiceNftId}`); + const pricingServiceNftdId = await registerService(owner, "PricingServiceProxy", pricingServiceManager, releaseManager, registryContract); + + logger.info(`pricingServiceManager deployed - pricingServiceAddress: ${pricingServiceAddress} pricingServiceManagerAddress: ${pricingServiceManagerAddress} nftId: ${pricingServiceNftdId}`); + + logger.info("-------- bundle service --------"); const { @@ -583,25 +560,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const bundleServiceImplementationAddress = await bundleServiceManager.getImplementation(); const bundleService = BundleService__factory.connect(bundleServiceAddress, owner); - logger.info("Verifying bundle service implementation"); - /* - await deployContract( - "BundleService", - owner, - [], - { libraries: { - AmountLib: libraries.amountLibAddress, - NftIdLib: libraries.nftIdLibAddress, - TimestampLib: libraries.timestampLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "BundleService", + "BundleServiceImplementation", "BundleService", bundleServiceImplementationAddress, - owner, //signer bundleServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -614,12 +576,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying bundle service proxy"); await addDeployedContract( "BundleServiceProxy", "UpgradableProxyWithAdmin", bundleServiceAddress, - owner, //signer bundleServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -627,12 +587,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptBdl = await executeTx(async () => await releaseManager.registerService(bundleServiceAddress)); - const logRegistrationInfoBdl = getFieldFromTxRcptLogs(rcptBdl!, registry.registry.interface, "LogRegistration", "nftId"); - const bundleServiceNftId = (logRegistrationInfoBdl as unknown); - await bundleServiceManager.linkToProxy(); + const bundleServiceNftId = await registerService(owner, "BundleServiceProxy", bundleServiceManager, releaseManager, registryContract); + logger.info(`bundleServiceManager deployed - bundleServiceAddress: ${bundleServiceAddress} bundleServiceManagerAddress: ${bundleServiceManagerAddress} nftId: ${bundleServiceNftId}`); + + logger.info("-------- pool service --------"); const { address: poolServiceManagerAddress, @@ -662,26 +622,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const poolServiceImplementationAddress = await poolServiceManager.getImplementation(); const poolService = PoolService__factory.connect(poolServiceAddress, owner); - logger.info("Verifying pool service implementation"); - /* - await deployContract( - "PoolService", - owner, - [], - { libraries: { - AmountLib: libraries.amountLibAddress, - FeeLib: libraries.feeLibAddress, - NftIdLib: libraries.nftIdLibAddress, - RoleIdLib: libraries.roleIdLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "PoolService", + "PoolServiceImplementation", "PoolService", poolServiceImplementationAddress, - owner, //signer poolServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -695,12 +639,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying pool service proxy"); await addDeployedContract( "PoolServiceProxy", "UpgradableProxyWithAdmin", poolServiceAddress, - owner, //signer poolServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -708,12 +650,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptPs = await executeTx(async () => await releaseManager.registerService(poolServiceAddress)); - const logRegistrationInfoPs = getFieldFromTxRcptLogs(rcptPs!, registry.registry.interface, "LogRegistration", "nftId"); - const poolServiceNftId = (logRegistrationInfoPs as unknown); - await poolServiceManager.linkToProxy(); + const poolServiceNftId = await registerService(owner, "PoolServiceProxy", poolServiceManager, releaseManager, registryContract); + logger.info(`poolServiceManager deployed - poolServiceAddress: ${poolServiceAddress} poolServiceManagerAddress: ${poolServiceManagerAddress} nftId: ${poolServiceNftId}`); + + logger.info("-------- product service --------"); const { address: productServiceManagerAddress, @@ -740,23 +682,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const productServiceImplementationAddress = await productServiceManager.getImplementation(); const productService = ProductService__factory.connect(productServiceAddress, owner); - logger.info("Verifying product service implementation"); - /* - await deployContract( - "ProductService", - owner, - [], - { libraries: { - NftIdLib: libraries.nftIdLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "ProductService", + "ProductServiceImplementation", "ProductService", productServiceImplementationAddress, - owner, //signer productServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -767,12 +696,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying product service proxy"); await addDeployedContract( "ProductServiceProxy", "UpgradableProxyWithAdmin", productServiceAddress, - owner, //signer productServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -780,12 +707,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptPrd = await executeTx(async () => await releaseManager.registerService(productServiceAddress)); - const logRegistrationInfoPrd = getFieldFromTxRcptLogs(rcptPrd!, registry.registry.interface, "LogRegistration", "nftId"); - const productServiceNftId = (logRegistrationInfoPrd as unknown); - await productServiceManager.linkToProxy(); + const productServiceNftId = await registerService(owner, "ProductServiceProxy", productServiceManager, releaseManager, registryContract); + logger.info(`productServiceManager deployed - productServiceAddress: ${productServiceAddress} productServiceManagerAddress: ${productServiceManagerAddress} nftId: ${productServiceNftId}`); + + logger.info("-------- claim service --------"); const { address: claimServiceManagerAddress, @@ -816,28 +743,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const claimServiceImplementationAddress = await claimServiceManager.getImplementation(); const claimService = ClaimService__factory.connect(claimServiceAddress, owner); - logger.info("Verifying claim service implementation"); - /* - await deployContract( - "ClaimService", - owner, - [], - { libraries: { - AmountLib: libraries.amountLibAddress, - ClaimIdLib: libraries.claimIdLibAddress, - FeeLib: libraries.feeLibAddress, - NftIdLib: libraries.nftIdLibAddress, - PayoutIdLib: libraries.payoutIdLibAddress, - TimestampLib: libraries.timestampLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "ClaimService", + "ClaimServiceImplementation", "ClaimService", claimServiceImplementationAddress, - owner, //signer claimServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -853,12 +762,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying claim service proxy"); await addDeployedContract( "ClaimServiceProxy", "UpgradableProxyWithAdmin", claimServiceAddress, - owner, //signer claimServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -866,12 +773,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptClm = await executeTx(async () => await releaseManager.registerService(claimServiceAddress)); - const logRegistrationInfoClm = getFieldFromTxRcptLogs(rcptClm!, registry.registry.interface, "LogRegistration", "nftId"); - const claimServiceNftId = (logRegistrationInfoClm as unknown); - await claimServiceManager.linkToProxy(); + const claimServiceNftId = await registerService(owner, "ClaimServiceProxy", claimServiceManager, releaseManager, registryContract); + logger.info(`claimServiceManager deployed - claimServiceAddress: ${claimServiceAddress} claimServiceManagerAddress: ${claimServiceManagerAddress} nftId: ${claimServiceNftId}`); + + logger.info("-------- application service --------"); const { address: applicationServiceManagerAddress, @@ -899,24 +806,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const applicationServiceImplementationAddress = await applicationServiceManager.getImplementation(); const applicationService = ApplicationService__factory.connect(applicationServiceAddress, owner); - logger.info("Verifying application service implementation"); - /* - await deployContract( - "ApplicationService", - owner, - [], - { libraries: { - AmountLib: libraries.amountLibAddress, - NftIdLib: libraries.nftIdLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "ApplicationService", + "ApplicationServiceImplementation", "ApplicationService", applicationServiceImplementationAddress, - owner, //signer applicationServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -928,12 +821,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying application service proxy"); await addDeployedContract( "ApplicationServiceProxy", "UpgradableProxyWithAdmin", applicationServiceAddress, - owner, //signer applicationServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -941,12 +832,12 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptAppl = await executeTx(async () => await releaseManager.registerService(applicationServiceAddress)); - const logRegistrationInfoAppl = getFieldFromTxRcptLogs(rcptAppl!, registry.registry.interface, "LogRegistration", "nftId"); - const applicationServiceNftId = (logRegistrationInfoAppl as unknown); - await applicationServiceManager.linkToProxy(); + const applicationServiceNftId = await registerService(owner, "ApplicationServiceProxy", applicationServiceManager, releaseManager, registryContract); + logger.info(`applicationServiceManager deployed - applicationServiceAddress: ${applicationServiceAddress} policyServiceManagerAddress: ${applicationServiceManagerAddress} nftId: ${applicationServiceNftId}`); + + logger.info("-------- policy service --------"); const { address: policyServiceManagerAddress, @@ -974,25 +865,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr const policyServiceImplementationAddress = await policyServiceManager.getImplementation(); const policyService = PolicyService__factory.connect(policyServiceAddress, owner); - logger.info("Verifying policy service implementation"); - /* - await deployContract( - "PolicyService", - owner, - [], - { libraries: { - AmountLib: libraries.amountLibAddress, - NftIdLib: libraries.nftIdLibAddress, - TimestampLib: libraries.timestampLibAddress, - VersionLib: libraries.versionLibAddress, - VersionPartLib: libraries.versionPartLibAddress, - }}); - */ await addDeployedContract( - "PolicyService", + "PolicyServiceImplementation", "PolicyService", policyServiceImplementationAddress, - owner, //signer policyServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -1005,12 +881,10 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - logger.info("Verifying policy service proxy"); await addDeployedContract( "PolicyServiceProxy", "UpgradableProxyWithAdmin", policyServiceAddress, - owner, //signer policyServiceManagerDeploymentTransaction as TransactionResponse, [],// constructor args { @@ -1018,20 +892,24 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr } }); - const rcptPol = await executeTx(async () => await releaseManager.registerService(policyServiceAddress)); - const logRegistrationInfoPol = getFieldFromTxRcptLogs(rcptPol!, registry.registry.interface, "LogRegistration", "nftId"); - const policyServiceNftId = (logRegistrationInfoPol as unknown); - await policyServiceManager.linkToProxy(); + const policyServiceNftId = await registerService(owner, "PolicyServiceProxy", policyServiceManager, releaseManager, registryContract); + logger.info(`policyServiceManager deployed - policyServiceAddress: ${policyServiceAddress} policyServiceManagerAddress: ${policyServiceManagerAddress} nftId: ${policyServiceNftId}`); - + logger.info("======== Finished deployment of services ========"); + + + logger.info("======== Activating release ========"); - await releaseManager.activateNextRelease(); + await activateRelease(releaseManager); + //_tryActivateRelease(releaseManager); + // release already was activated + //await releaseManager.activateNextRelease(); logger.info("======== release activated ========"); return { - registryServiceNftId: registryServiceNfdId as string, + registryServiceNftId: registryServiceNftId as string, registryServiceAddress: registryServiceAddress, registryService: registryService, registryServiceManagerAddress: registryServiceManagerAddress, @@ -1041,7 +919,7 @@ export async function deployAndRegisterServices(owner: Signer, registry: Registr stakingService: stakingService, stakingServiceManagerAddress: stakingServiceManagerAddress, - instanceServiceNftId: instanceServiceNfdId as string, + instanceServiceNftId: instanceServiceNftId as string, instanceServiceAddress: instanceServiceAddress, instanceService: instanceService, instanceServiceManagerAddress: instanceServiceManagerAddress, From 4e9212effa69ea661dd8b85f276d41383733bdcd Mon Sep 17 00:00:00 2001 From: Matthias Zimmermann Date: Thu, 23 May 2024 10:33:25 +0000 Subject: [PATCH 9/9] amend some tenderly setup details --- README.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd244537b..1f8713f58 100644 --- a/README.md +++ b/README.md @@ -89,18 +89,35 @@ Environment variables: - `ETHERSCAN_API_KEY` `POLYGONSCAN_API_KEY` the api key for etherscan/polygonscan (required for mumbai and mainnet) +#### Tenderly Testnet Deployment + +if not already done: +* install hardhat-tenderly +* install tenderly cli + +```bash +npm install @tenderly/hardhat-tenderly +curl https://raw.githubusercontent.com/Tenderly/tenderly-cli/master/scripts/install-linux.sh | sudo sh +``` + +login to tenderly ```bash -# run deployment and verify on tendrely network +tenderly login +``` +when prompted (1st time usage) enter access key (= access token, see https://dashboard.tenderly.co/account/authorization) + +run deployment to tenderly testnet (eg =virtualMainnet in the example below) +```bash +export RESUMEABLE_DEPLOYMENT=false export ENABLE_ETHERSCAN_VERIFICATION=false export ENABLE_TENDERLY_VERIFICATION=true -tenderly login hh run --network scripts/deploy_all.ts ``` Environment variables: -- `RESUMEABLE_DEPLOYMENT` set to `true` to skip deployment/verification of already deployed/verified contracts (based on ./deployment_state_.json) +- `RESUMEABLE_DEPLOYMENT` set to `true` to skip deployment/verification of already deployed/verified contracts (based on ./deployment_state_.json), set to `true` to force a redeploy - `ENABLE_TENDERLY_VERIFICATION` set to `true` to perform verification of deployed contracts # https://dashboard.tenderly.co/{TENDERLY_USERNAME}/{TENDERLY_PROJECT}/fork/{FORK_ID} - `TENDERLY_DEVNET_RPC_URL` is the RPC_URL of a Tenderly Devnet, found on the devnet UI info tab