From d162382bcc0e02cad8475af01baeaaf1c8b207d1 Mon Sep 17 00:00:00 2001 From: Santiago Gonzalez Date: Mon, 3 Jun 2024 17:41:23 -0500 Subject: [PATCH] update deployment scripts --- README.md | 104 ++++++++---------- constants/config.ts | 88 +++++---------- constants/splits.ts | 2 +- deploy/003_deploy_PGRegistry_UUPS.ts | 2 +- deploy/004_deploy_PGNetworkRegistry_UUPS.ts | 4 +- deploy/005_deploy_PGRegistryV2_UUPS.ts | 70 ++++++++++++ deploy/006_deploy_PGNetworkRegistryV2_UUPS.ts | 85 ++++++++++++++ hardhat.config.ts | 65 ++--------- tasks/taskDeploy.ts | 71 ++++++++++++ 9 files changed, 312 insertions(+), 179 deletions(-) create mode 100644 deploy/005_deploy_PGRegistryV2_UUPS.ts create mode 100644 deploy/006_deploy_PGNetworkRegistryV2_UUPS.ts diff --git a/README.md b/README.md index dc2bf5d..8e719c2 100644 --- a/README.md +++ b/README.md @@ -292,74 +292,74 @@ pnpm hardhat memberlist:generate `./constants/config.ts` ```sh -pnpm hardhat --network goerli deploy:split --controller -pnpm hardhat --network optimismGoerli deploy:split --controller -pnpm hardhat --network arbitrumGoerli deploy:split --controller +# Split V1 +pnpm hardhat --network sepolia deploy:split --controller +pnpm hardhat --network optimismSepolia deploy:split --controller +pnpm hardhat --network arbitrumSepolia deploy:split --controller ``` -The `--controller` flag will set the deployer address as the 0xSplit controller.. - -- **Deploy & Verify Registry Summoner + Singleton contracts** on relevant test networks (OPTIONAL as these should be - already deployed) - ```sh -pnpm hardhat --network goerli deploy --tags Summoner -pnpm hardhat --network goerli etherscan-verify - -pnpm hardhat --network optimismGoerli deploy --tags Summoner -pnpm hardhat --network optimismGoerli etherscan-verify - -pnpm hardhat --network arbitrumGoerli deploy --tags Summoner -pnpm hardhat --network arbitrumGoerli etherscan-verify +# Split V2 +pnpm hardhat --network sepolia deploy:splitV2 --controller +pnpm hardhat --network optimismSepolia deploy:splitV2 --controller +pnpm hardhat --network arbitrumSepolia deploy:splitV2 --controller ``` +The `--controller` flag will set the deployer address as the 0xSplit controller.. + - **Deploy a Main NetworkRegistry** using the deploy script. The registry will be owned either by `safe` address, or `moloch`.avatar() address you define in `./constants/config.ts`, otherwise the `deployer` will be set as owner by default. Finally don't forget to set the `pgRegistry` to the deployed contract address in `./constants/config.ts`. -Using Summoner: +GuildRegistry: ```sh -pnpm hardhat --network goerli deploy --tags PGNetworkRegistry +pnpm hardhat --network sepolia deploy --tags GuildRegistry +# or using SplitV2 +pnpm hardhat --network sepolia deploy --tags GuildRegistryV2 ``` -Using UUPS Proxy: +NetworkRegistry: ```sh -pnpm hardhat --network sepolia deploy --tags UpgradeablePGNetworkRegistry +pnpm hardhat --network sepolia deploy --tags NetworkRegistry +# or using SplitV2 +pnpm hardhat --network sepolia deploy --tags NetworkRegistryV2 ``` - **Transfer 0xSplit control to NetworkRegistry contract**: if NetworkRegistry is owner by the DAO safe, remember to trigger an action later to accept control. ```sh -pnpm hardhat --network goerli registry:ownSplit +pnpm hardhat --network sepolia registry:ownSplit ``` - **Deploy a Replica NetworkRegistry on relevant L2's**. The registry will be owned by a temporary `registryOwner` address if set in `./constants/config.ts`, otherwise the `deployer` will renounce ownership (Zero address) by default. Finally don't forget to set the `pgRegistry` to the deployed contract address in `./constants/config.ts`. -Using Summoner: +GuildRegistry: ```sh -pnpm hardhat --network optimismGoerli deploy --tags PGNetworkRegistry -pnpm hardhat --network arbitrumGoerli deploy --tags PGNetworkRegistry +pnpm hardhat --network optimismSepolia deploy --tags GuildRegistry +# or using SplitV2 +pnpm hardhat --network optimismSepolia deploy --tags GuildRegistryV2 ``` -Using UUPS Proxy: +NetworkRegistry: ```sh -pnpm hardhat --network optimismSepolia deploy --tags UpgradeablePGNetworkRegistry -pnpm hardhat --network arbitrumSepolia deploy --tags UpgradeablePGNetworkRegistry +pnpm hardhat --network optimismSepolia deploy --tags NetworkRegistry +# or using SplitV2 +pnpm hardhat --network optimismSepolia deploy --tags NetworkRegistryV2 ``` - **Register a new Replicas on the Main NetworkRegistry** ``` -pnpm hardhat --network goerli registry:addNetwork --foreign-chain-id 420 --foreign-domain-id 1735356532 --foreign-registry-address +pnpm hardhat --network sepolia registry:addNetwork --foreign-chain-id 420 --foreign-domain-id 1735356532 --foreign-registry-address -pnpm hardhat --network goerli registry:addNetwork --foreign-chain-id 421613 --foreign-domain-id 1734439522 --foreign-registry-address +pnpm hardhat --network sepolia registry:addNetwork --foreign-chain-id 421613 --foreign-domain-id 1734439522 --foreign-registry-address ``` - **Transfer 0xSplit control in L2s to replica NetworkRegistry contracts**. In case of Replica registries that have @@ -375,50 +375,32 @@ pnpm hardhat --network goerli registry:addNetwork --foreign-chain-id 421613 --fo - **Test New Member Sync Action** ``` -pnpm hardhat --network goerli registry:newMember --member --multiplier 100 +pnpm hardhat --network sepolia registry:newMember --member --multiplier 100 ``` - Copy the hash from the latest tx and open - [Goerli subgraph](https://thegraph.com/hosted-service/subgraph/connext/nxtp-amarok-runtime-v0-goerli) + [Sepolia subgraph](https://thegraph.com/hosted-service/subgraph/connext/runtime-v1-sepolia) - Copy/Paste Origin Transfer query from [this link](https://docs.connext.network/developers/guides/xcall-status) and replace the txHash parameter. You'll get the `transferId` from both cross-chain actions submitted to optimism and arbitrum -- Open [Connextscan]() to monitor cross-chain actions status. It usually takes ~30min to get a Complete status (Tx +- Open [Connextscan](https://testnet.connextscan.io/) to monitor cross-chain actions status. It usually takes ~30min to get a Complete status (Tx Reconciled & Executed) ## Deployed Contracts ### Sepolia -| Contract | Address | -| ------------------------------ | ------- | -| NetworkRegistry Proxy | TBD | -| NetworkRegistry Implementation | TBD | -| PGContribCalculator | TBD | - -### ~~Goerli~~ - -| Contract | Address | -| ------------------------------- | ---------------------------------------------- | -| NetworkRegistrySummoner | ~~0xd1a8c3b7F7250b50E352b51d148A29f24C0CeD62~~ | -| NetworkRegistry Singleton | ~~0x250F9e93822cD48269E8a24A9D4bE817A9cf389D~~ | -| NetworkRegistryShaman Singleton | | - -### ~~Optimism Goerli~~ - -| Contract | Address | -| ------------------------------- | ---------------------------------------------- | -| NetworkRegistrySummoner | ~~0x7D32b8Ae083d78ff6628271a15B162676380bd00~~ | -| NetworkRegistry Singleton | ~~0xF3C93FBa186758605318b2F6d0b141029a20E2a8~~ | -| NetworkRegistryShaman Singleton | | - -### ~~Arbitrum Goerli~~ - -| Contract | Address | -| ------------------------------- | ---------------------------------------------- | -| NetworkRegistrySummoner | ~~0x7D32b8Ae083d78ff6628271a15B162676380bd00~~ | -| NetworkRegistry Singleton | ~~0xF3C93FBa186758605318b2F6d0b141029a20E2a8~~ | -| NetworkRegistryShaman Singleton | | +| Contract | Address | +| --------------------------------- | ------- | +| NetworkRegistry Proxy | TBD | +| NetworkRegistry Implementation | TBD | +| NetworkRegistryV2 Proxy | TBD | +| NetworkRegistryV2 Implementation | TBD | +| GuildRegistry Proxy | TBD | +| GuildRegistry Implementation | TBD | +| GuildRegistryV2 Proxy | TBD | +| GuildRegistryV2 Implementation | TBD | +| PGContribCalculator | TBD | ### Polygon Mumbai diff --git a/constants/config.ts b/constants/config.ts index 0aa8594..a852a67 100644 --- a/constants/config.ts +++ b/constants/config.ts @@ -1,6 +1,7 @@ // 0xSplits contracts export const defaultSplitsConfig = { splitMain: "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE", // same address on all live/test networks + splitV2Factory: "0x80f1B766817D04870f115fEBbcCADF8DBF75E017", // PullSplitFactory }; // NOTICE: DAO + Connext + 0xSplits config @@ -14,6 +15,8 @@ export const deploymentConfig: { [key: string]: any } = { safe: "", // TODO: splitMain: defaultSplitsConfig.splitMain, split: "", // TODO: + splitv2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, "100": { @@ -26,6 +29,8 @@ export const deploymentConfig: { [key: string]: any } = { safe: "", // TODO: splitMain: defaultSplitsConfig.splitMain, split: "", // TODO: + splitv2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, "137": { @@ -38,6 +43,8 @@ export const deploymentConfig: { [key: string]: any } = { safe: "", // TODO: splitMain: defaultSplitsConfig.splitMain, split: "", // TODO: + splitv2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, "42161": { @@ -50,6 +57,8 @@ export const deploymentConfig: { [key: string]: any } = { safe: "", // TODO: splitMain: defaultSplitsConfig.splitMain, split: "", // TODO: + splitv2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, "10": { @@ -62,87 +71,48 @@ export const deploymentConfig: { [key: string]: any } = { safe: "", // TODO: splitMain: defaultSplitsConfig.splitMain, split: "", // TODO: + splitv2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, - "5": { - // goerli - domainId: 1735353714, - connext: "0xFCa08024A6D4bCc87275b1E4A1E22B71fAD7f649", - moloch: "0xbfb34e1e13d68922cb86769f4abcdab9bd68e5ff", // TODO: - safe: "0x7201030e136734e92560427b1346af2219d12074", // TODO: - splitMain: defaultSplitsConfig.splitMain, - split: "0xe650e123237920d5f620579fb42670145361a0a9", // TODO: - pgRegistry: "0x9eF64c547477b2263ed56821ce6Be79564824F44", // TODO: - }, - "80001": { - // mumbai - l2: true, - domainId: 9991, - connext: "0x2334937846Ab2A3FCE747b32587e1A1A2f6EEC5a", - registryOwner: "0x10136Fa41B6522E4DBd068C6F7D80373aBbCFBe6", // TODO: - moloch: "", - safe: "", - splitMain: defaultSplitsConfig.splitMain, - split: "0x6f9a5dc2903a2bcb51caf05978e4f260a531c578", // TODO: - pgRegistry: "0x07E1eF1E6Eff099c082232a9AcA0Fa5551602d62", // TODO: - }, - "420": { - // optimismGoerli - l2: true, - domainId: 1735356532, - connext: "0x5Ea1bb242326044699C3d81341c5f535d5Af1504", - registryOwner: "0x10136Fa41B6522E4DBd068C6F7D80373aBbCFBe6", // TODO: - moloch: "", - safe: "", - splitsMain: "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694EE", - splitMain: defaultSplitsConfig.splitMain, - split: "0xb12a8499c8aca88fe2270ba5552d0a2a1fd8b7fe", // TODO: - pgRegistry: "0x8054874b08783070a189218a22e7ffb4600430c0", // TODO: - }, - "421613": { - // arbitrumGoerli - l2: true, - domainId: 1734439522, - connext: "0x2075c9E31f973bb53CAE5BAC36a8eeB4B082ADC2", - registryOwner: "0x10136Fa41B6522E4DBd068C6F7D80373aBbCFBe6", // TODO: - moloch: "", - safe: "", - splitMain: defaultSplitsConfig.splitMain, - split: "0x14ff51c8806f1730d64137fcf79ba38c67d593c8", // TODO: - pgRegistry: "0x8054874b08783070a189218a22e7ffb4600430c0", // TODO: - }, "11155111": { // sepolia - domainId: 0, // TODO: - connext: "0xFCa08024A6D4bCc87275b1E4A1E22B71fAD7f649", // TODO: - moloch: "0x832ec97051ed6a1abdbafa74dace307af59b1ef3", // TODO: - safe: "0x79c740401f76b8a7b26baf3e522571add38362d0", // TODO: - splitMain: "0x5924cD81dC672151527B1E4b5Ef57B69cBD07Eda", - split: "0xccc8922d223f5bb2e623bf100970913ac85fd17d", // TODO: - pgRegistry: "0x7A69DbBFF504FAB98ADe857992BC6d1Ae94Ba0d0", // TODO: + domainId: 1936027759, + connext: "0x445fbf9cCbaf7d557fd771d56937E94397f43965", + moloch: "", // TODO: + safe: "", // TODO: + splitMain: "0x54E4a6014D36c381fC43b7E24A1492F556139a6F", + split: "", // TODO: + splitV2: "0x5e3058D49074b6Ce2419672BAFBCAfaA0835758d", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, + pgRegistry: "", // TODO: }, "11155420": { // optimismSepolia l2: true, - domainId: 0, // TODO: - connext: "", // TODO: + domainId: 1869640549, + connext: "0x8247ed6d0a344eeae4edBC7e44572F1B70ECA82A", registryOwner: "0x10136Fa41B6522E4DBd068C6F7D80373aBbCFBe6", // TODO: moloch: "", safe: "", - splitMain: defaultSplitsConfig.splitMain, + splitMain: "0x2ed6c4B5dA6378c7897AC67Ba9e43102Feb694E", split: "", // TODO: + splitV2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, "421614": { // arbitrumSepolia l2: true, - domainId: 0, // TODO: - connext: "", // TODO: + domainId: 1633842021, + connext: "0x1780Ac087Cbe84CA8feb75C0Fb61878971175eb8", registryOwner: "0x10136Fa41B6522E4DBd068C6F7D80373aBbCFBe6", // TODO: moloch: "", safe: "", splitMain: "", // TODO: split: "", // TODO: + splitV2: "", // TODO: + splitV2Factory: defaultSplitsConfig.splitV2Factory, pgRegistry: "", // TODO: }, }; diff --git a/constants/splits.ts b/constants/splits.ts index cad2b5e..2dd99f9 100644 --- a/constants/splits.ts +++ b/constants/splits.ts @@ -10,4 +10,4 @@ export const PERCENTAGE_SCALE = BigNumber.from(1e6); // Min & max distribution fee (0-10%) export const MIN_DISTRIBUTION_FEE = BigNumber.from(0); -export const MAX_DISTRIBUTION_FEE = BigNumber.from(1e5); +export const MAX_DISTRIBUTION_FEE = BigNumber.from(2^16); diff --git a/deploy/003_deploy_PGRegistry_UUPS.ts b/deploy/003_deploy_PGRegistry_UUPS.ts index 8555365..899dc9e 100644 --- a/deploy/003_deploy_PGRegistry_UUPS.ts +++ b/deploy/003_deploy_PGRegistry_UUPS.ts @@ -9,7 +9,7 @@ const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { deployments, ethers, getChainId, getNamedAccounts, network } = hre; const { deployer } = await getNamedAccounts(); const signer = await ethers.getSigner(deployer); - const chainId = network.name === "hardhat" ? "5" : await getChainId(); // hardhat -> Forking mode + const chainId = network.name === "hardhat" ? "11155111" : await getChainId(); // hardhat -> Forking mode const { deploy } = deployments; diff --git a/deploy/004_deploy_PGNetworkRegistry_UUPS.ts b/deploy/004_deploy_PGNetworkRegistry_UUPS.ts index 49a5158..70cc279 100644 --- a/deploy/004_deploy_PGNetworkRegistry_UUPS.ts +++ b/deploy/004_deploy_PGNetworkRegistry_UUPS.ts @@ -9,7 +9,7 @@ const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { const { companionNetworks, deployments, ethers, getChainId, getNamedAccounts, network } = hre; const { deployer } = await getNamedAccounts(); const signer = await ethers.getSigner(deployer); - const chainId = network.name === "hardhat" ? "5" : await getChainId(); // hardhat -> Forking mode + const chainId = network.name === "hardhat" ? "11155111" : await getChainId(); // hardhat -> Forking mode const { deploy } = deployments; @@ -79,7 +79,7 @@ const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { return; } - console.error("PGRegistry: Not supported Network!"); + console.error("PGNetworkRegistry: Not supported Network!"); }; export default deployFn; diff --git a/deploy/005_deploy_PGRegistryV2_UUPS.ts b/deploy/005_deploy_PGRegistryV2_UUPS.ts new file mode 100644 index 0000000..a3decbc --- /dev/null +++ b/deploy/005_deploy_PGRegistryV2_UUPS.ts @@ -0,0 +1,70 @@ +import { Baal } from "@daohaus/baal-contracts"; +// import { ethers } from "hardhat"; +import { DeployFunction } from "hardhat-deploy/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { deploymentConfig } from "../constants"; + +const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { deployments, ethers, getChainId, getNamedAccounts, network } = hre; + const { deployer } = await getNamedAccounts(); + const signer = await ethers.getSigner(deployer); + const chainId = network.name === "hardhat" ? "11155111" : await getChainId(); // hardhat -> Forking mode + + const { deploy } = deployments; + + // uncomment if you get gas-related errors and need current network fee data to update params + // console.log("Feedata", await ethers.provider.getFeeData()); + + const networkConfig = deploymentConfig[chainId]; + + console.log("networkConfig", networkConfig); + + let safeAddress = networkConfig.safe; + if (networkConfig.moloch && !networkConfig.safe) { + const baal = (await ethers.getContractAt("Baal", networkConfig.moloch, signer)) as Baal; + safeAddress = await baal.avatar(); + } + const owner = safeAddress || deployer; + + console.log("Registry will be owned by", owner, "Is Safe?", owner === safeAddress); + + const initializationParams = ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [networkConfig.splitV2, owner], + ); + + const calculatorLibraryDeployed = await deploy("PGContribCalculator", { + contract: "PGContribCalculator", + from: deployer, + args: [], + log: true, + }); + + const registryDeployed = await deploy("GuildRegistryV2", { + contract: "GuildRegistryV2", + from: deployer, + args: [], + libraries: { + PGContribCalculator: calculatorLibraryDeployed.address, + }, + proxy: { + execute: { + init: { + methodName: "initialize", + args: [initializationParams], + }, + }, + owner, + proxyContract: "ERC1967Proxy", + proxyArgs: ["{implementation}", "{data}"], + }, + log: true, + }); + const registryAddress = registryDeployed.address; + + console.log(`PG GuildRegistryV2 deployed on ${network.name} chain at ${registryAddress}`); +}; + +export default deployFn; +deployFn.tags = ["GuildRegistryV2", "UpgradeablePGuildRegistry"]; diff --git a/deploy/006_deploy_PGNetworkRegistryV2_UUPS.ts b/deploy/006_deploy_PGNetworkRegistryV2_UUPS.ts new file mode 100644 index 0000000..74ac4cf --- /dev/null +++ b/deploy/006_deploy_PGNetworkRegistryV2_UUPS.ts @@ -0,0 +1,85 @@ +import { Baal } from "@daohaus/baal-contracts"; +// import { ethers } from "hardhat"; +import { DeployFunction } from "hardhat-deploy/types"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { deploymentConfig } from "../constants"; + +const deployFn: DeployFunction = async (hre: HardhatRuntimeEnvironment) => { + const { companionNetworks, deployments, ethers, getChainId, getNamedAccounts, network } = hre; + const { deployer } = await getNamedAccounts(); + const signer = await ethers.getSigner(deployer); + const chainId = network.name === "hardhat" ? "11155111" : await getChainId(); // hardhat -> Forking mode + + const { deploy } = deployments; + + // uncomment if you get gas-related errors and need current network fee data to update params + // console.log("Feedata", await ethers.provider.getFeeData()); + + if (Object.keys(deploymentConfig).includes(chainId)) { + const networkConfig = deploymentConfig[chainId]; + const parentChainId = companionNetworks.l1 && (await companionNetworks.l1.getChainId()); + console.log("Is L2?", networkConfig.l2, parentChainId); + + console.log("networkConfig", networkConfig); + + let safeAddress = networkConfig.safe; + if (networkConfig.moloch && !networkConfig.safe) { + const baal = (await ethers.getContractAt("Baal", networkConfig.moloch, signer)) as Baal; + safeAddress = await baal.avatar(); + } + const owner = networkConfig.l2 + ? networkConfig.registryOwner || ethers.constants.AddressZero + : safeAddress || deployer; + + console.log("Registry will be owned by", owner, "Is L2?", networkConfig.l2, "Is Safe?", owner === safeAddress); + + const initializationParams = ethers.utils.defaultAbiCoder.encode( + ["address", "uint32", "address", "address", "address"], + [ + networkConfig.connext, + networkConfig.l2 ? deploymentConfig[parentChainId].domainId : 0, + networkConfig.l2 ? deploymentConfig[parentChainId].pgRegistry : ethers.constants.AddressZero, + networkConfig.splitV2, + owner, + ], + ); + + const calculatorLibraryDeployed = await deploy("PGContribCalculator", { + contract: "PGContribCalculator", + from: deployer, + args: [], + log: true, + }); + + const registryDeployed = await deploy("NetworkRegistryV2", { + contract: "NetworkRegistryV2", + from: deployer, + args: [], + libraries: { + PGContribCalculator: calculatorLibraryDeployed.address, + }, + proxy: { + execute: { + init: { + methodName: "initialize", + args: [initializationParams], + }, + }, + owner, + proxyContract: "ERC1967Proxy", + proxyArgs: ["{implementation}", "{data}"], + }, + log: true, + }); + const registryAddress = registryDeployed.address; + + console.log(`PG NetworkRegistryV2 deployed on ${network.name} chain at ${registryAddress}`); + + return; + } + console.error("PGNetworkRegistry: Not supported Network!"); +}; + +export default deployFn; +deployFn.tags = ["NetworkRegistryV2", "UpgradeablePGNetworkRegistry"]; diff --git a/hardhat.config.ts b/hardhat.config.ts index 9ac840e..278ed96 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,5 +1,5 @@ // NOTICE: hardhat-foundry must be disabled when running pnpm coverage -import "@nomicfoundation/hardhat-foundry"; +// import "@nomicfoundation/hardhat-foundry"; import "@nomicfoundation/hardhat-toolbox"; import { config as dotenvConfig } from "dotenv"; import "hardhat-contract-sizer"; @@ -29,38 +29,30 @@ if (!infuraApiKey) { const chainIds = { hardhat: 31337, - goerli: 5, sepolia: 11155111, mainnet: 1, gnosis: 100, "arbitrum-mainnet": 42161, - "arbitrum-goerli": 421613, "arbitrum-sepolia": 421614, "optimism-mainnet": 10, - "optimism-goerli": 420, "optimism-sepolia": 11155420, "polygon-mainnet": 137, - "polygon-mumbai": 80001, }; const explorerApiKey = (networkName: keyof typeof chainIds) => { const fromEnv = () => { switch (networkName) { case "mainnet": - case "goerli": case "sepolia": return process.env.ETHERSCAN_APIKEY; case "gnosis": return process.env.GNOSISSCAN_APIKEY; case "polygon-mainnet": - case "polygon-mumbai": return process.env.POLYGONSCAN_APIKEY; case "optimism-mainnet": - case "optimism-goerli": case "optimism-sepolia": return process.env.OPTIMISTICSCAN_APIKEY; case "arbitrum-mainnet": - case "arbitrum-goerli": case "arbitrum-sepolia": return process.env.ARBISCAN_APIKEY; default: @@ -74,21 +66,14 @@ const getNodeURI = (networkName: keyof typeof chainIds) => { switch (networkName) { case "arbitrum-mainnet": return "https://rpc.ankr.com/arbitrum"; - case "arbitrum-goerli": - return "https://goerli-rollup.arbitrum.io/rpc"; - // return "https://arbitrum-goerli.publicnode.com"; case "arbitrum-sepolia": return "https://sepolia-rollup.arbitrum.io/rpc"; case "optimism-mainnet": return "https://rpc.ankr.com/optimism"; - case "optimism-goerli": - return "https://goerli.optimism.io"; case "optimism-sepolia": return "https://sepolia.optimism.io"; case "polygon-mainnet": return "https://rpc.ankr.com/polygon"; - case "polygon-mumbai": - return "https://rpc-mumbai.maticvigil.com"; case "gnosis": return "https://rpc.gnosischain.com"; default: @@ -150,16 +135,6 @@ const config: HardhatUserConfig = { // }, // avalanche: getChainConfig("avalanche"), // bsc: getChainConfig("bsc"), - goerli: { - ...getChainConfig("goerli"), - companionNetworks: { - "l2-optimism": "optimismGoerli", - "l2-arbitrum": "arbitrumGoerli", - }, - gas: 5000000, - gasPrice: 8000000000, - gasMultiplier: 2, - }, sepolia: { ...getChainConfig("sepolia"), companionNetworks: { @@ -173,15 +148,6 @@ const config: HardhatUserConfig = { mainnet: getChainConfig("mainnet"), gnosis: getChainConfig("gnosis"), arbitrum: getChainConfig("arbitrum-mainnet"), - arbitrumGoerli: { - ...getChainConfig("arbitrum-goerli"), - companionNetworks: { - l1: "goerli", - }, - initialBaseFeePerGas: 1635190000, - gasPrice: 1635190000, - gasMultiplier: 1.2, - }, arbitrumSepolia: { ...getChainConfig("arbitrum-sepolia"), companionNetworks: { @@ -192,13 +158,6 @@ const config: HardhatUserConfig = { gasMultiplier: 1.2, }, optimism: getChainConfig("optimism-mainnet"), - optimismGoerli: { - ...getChainConfig("optimism-goerli"), - companionNetworks: { - l1: "goerli", - }, - gasPrice: 2000000000, - }, optimismSepolia: { ...getChainConfig("optimism-sepolia"), companionNetworks: { @@ -207,12 +166,6 @@ const config: HardhatUserConfig = { gasPrice: 2000000000, }, polygon: getChainConfig("polygon-mainnet"), - mumbai: { - ...getChainConfig("polygon-mumbai"), - companionNetworks: { - l1: "goerli", - }, - }, }, paths: { artifacts: "./artifacts", @@ -225,7 +178,13 @@ const config: HardhatUserConfig = { disambiguatePaths: false, runOnCompile: true, strict: false, - only: ["GuildRegistry.sol", "NetworkRegistry.sol", "PGContribCalculator"], + only: [ + "GuildRegistry.sol", + "GuildRegistryV2.sol", + "NetworkRegistry.sol", + "NetworkRegistryV2.sol", + "PGContribCalculator", + ], }, solidity: { compilers: [ @@ -284,16 +243,12 @@ const config: HardhatUserConfig = { etherscan: { apiKey: { mainnet: explorerApiKey("mainnet"), - goerli: explorerApiKey("goerli"), sepolia: explorerApiKey("sepolia"), optimisticEthereum: explorerApiKey("optimism-mainnet"), - optimisticGoerli: explorerApiKey("optimism-goerli"), - // optimisticSepolia: explorerApiKey("optimism-sepolia"), + optimisticSepolia: explorerApiKey("optimism-sepolia"), arbitrumOne: explorerApiKey("arbitrum-mainnet"), - arbitrumGoerli: explorerApiKey("arbitrum-goerli"), - // arbitrumSepolia: explorerApiKey("arbitrum-sepolia"), + arbitrumSepolia: explorerApiKey("arbitrum-sepolia"), polygon: explorerApiKey("polygon-mainnet"), - polygonMumbai: explorerApiKey("polygon-mumbai"), }, }, external: { diff --git a/tasks/taskDeploy.ts b/tasks/taskDeploy.ts index 2ed951f..421ff8d 100644 --- a/tasks/taskDeploy.ts +++ b/tasks/taskDeploy.ts @@ -7,6 +7,7 @@ import type { TaskArguments } from "hardhat/types"; import { MAX_DISTRIBUTION_FEE, PERCENTAGE_SCALE, deploymentConfig } from "../constants"; import { Member } from "../src/utils"; import type { ISplitMain } from "../types/contracts/interfaces/ISplitMain"; +import { SplitFactoryV2 } from "../types"; task("deploy:split") .addFlag("controller", "Set the deployer address as Split controller") @@ -67,3 +68,73 @@ task("deploy:split") ` txhash: (${receipt.transactionHash})`, ); }); + +task("deploy:splitV2") + .addFlag("controller", "Set the deployer address as Split controller") + .addOptionalParam("controllerAddress", "Split contract controller address", ethers.constants.AddressZero) + .addOptionalParam("memberList", "JSON file containg member list records", "./memberlist.json", types.inputFile) + .addOptionalParam("distributorFee", "Split distributorFee", 0, types.int) + .setAction(async function (taskArguments: TaskArguments, { ethers, getChainId, getNamedAccounts, network }) { + const chainId = await getChainId(); + if (!deploymentConfig[chainId]?.splitMain) { + console.error("Not Supported Network", network.name, chainId); + return; + } + console.log(`Deploying SplitV2 to ${network.name}\n TaskArguments:`, taskArguments); + + const { deployer } = await getNamedAccounts(); + + const inputFile = taskArguments.memberList; + const data = fs.readFileSync(inputFile, { encoding: "utf-8" }); + const memberList = JSON.parse(data); + memberList.sort((a: Member, b: Member) => { + return parseInt(a.memberAddress.slice(2), 16) - parseInt(b.memberAddress.slice(2), 16); + }); + console.log("Total Members:", memberList.length); + + const accounts = memberList.map((m: Member) => m.memberAddress); + const percentAllocations = memberList.map((m: Member) => m.percentAllocation) as Array; + const { distributorFee } = taskArguments; + const controller = taskArguments.controller ? deployer : taskArguments.controllerAddress; + + const total = percentAllocations.reduce((prev: number, curr: number) => prev + curr, 0); + if (total != PERCENTAGE_SCALE.toNumber()) { + throw new Error( + `percentAllocations mismatch 0xSplit PERCENTAGE_SCALE (${total} != ${PERCENTAGE_SCALE.toString()})`, + ); + } + // console.log('total', total, PERCENTAGE_SCALE.toString()); + if (BigNumber.from(distributorFee).gt(MAX_DISTRIBUTION_FEE)) { + throw new Error(`distributorFee must not be greater than ${MAX_DISTRIBUTION_FEE.toString()}`); + } + + const signer: SignerWithAddress = await ethers.getSigner(deployer); + + const splitMain = (await ethers.getContractAt( + "SplitFactoryV2", + deploymentConfig[chainId]?.splitV2Factory, + signer, + )) as SplitFactoryV2; + + const tx = await splitMain.createSplit( + { + recipients: accounts, + allocations: percentAllocations, + totalAllocation: PERCENTAGE_SCALE, + distributionIncentive: distributorFee, + }, + controller, + deployer + ); + + const receipt = await tx.wait(); + + const splitAddress = + receipt.events?.[1].topics[1] && ethers.utils.defaultAbiCoder.decode(["address"], receipt.events?.[1].topics[1])[0]; + + console.log( + `New Split contract deployed to ${network.name}:`, + splitAddress, + ` txhash: (${receipt.transactionHash})`, + ); + });