From c907c5139de9b133f464a6a6190fa71a9d69fd94 Mon Sep 17 00:00:00 2001 From: Jarrel deLottinville Date: Fri, 14 Oct 2022 12:13:15 -0700 Subject: [PATCH] Enable goerli deploy and remove deprecated testnets (#569) * WIP goerli deploy setup and remove deprecated testnets * fix: get factory events * lint fix * fix deployment code * require node version * add identities as part of the logs to help with verification. TODO: add DaoRegistry identity contract * fix verification script Co-authored-by: Felipe Forbeck Co-authored-by: david roon --- .nvmrc | 1 + .sample.env | 29 ++++++++--------- README.md | 26 ++++++---------- configs/networks/rinkeby.config.ts | 23 -------------- contracts/helpers/WETH.sol | 3 +- docker/README-ganache.md | 8 ++--- docker/README.md | 27 ++++++++-------- docker/docker-compose.yml | 3 +- hardhat.config.js | 27 +--------------- package.json | 4 +++ signers/DefenderSignerProvider.ts | 2 +- signers/README.md | 8 ++--- tasks/deploy.js | 50 +++++++++++++++++++++--------- tasks/verify.ts | 10 ++++-- truffle-config.js | 6 ---- utils/contract-util.js | 5 +-- utils/deployment-util.js | 39 ++++++++++++++++++----- utils/hardhat-test-util.js | 7 +++++ utils/hardhat-util.js | 13 ++++++-- 19 files changed, 153 insertions(+), 138 deletions(-) create mode 100644 .nvmrc delete mode 100644 configs/networks/rinkeby.config.ts diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..19c7bdba7 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +16 \ No newline at end of file diff --git a/.sample.env b/.sample.env index 40cc623c1..cb78d90e6 100644 --- a/.sample.env +++ b/.sample.env @@ -3,11 +3,10 @@ # Set the name of your DAO. Make sure the DAO name is unique. DAO_NAME=My Tribute DAO xyz... -# The public ethereum address that belongs to the Owner of the DAO, -# in this case, it is your public ethereum address on Rinkeby network. -# Make sure you have some ETH, otherwise the deployment will fail. -# It needs to be the address of the first account you have in metamask accounts, -# otherwise it won't work. +# The public ethereum address that belongs to the Owner of the DAO, in this +# case, it is your public ethereum address on the Goerli network. Make sure you +# have some ETH, otherwise the deployment will fail. It needs to be the address +# of the first account you have in metamask accounts, otherwise it won't work. DAO_OWNER_ADDR=0x... # The name of the ERC20 token of your DAO. @@ -26,8 +25,8 @@ ERC20_TOKEN_DECIMALS=0 # these steps to get your ProjectId/API Key from Infura: # https://blog.infura.io/getting-started-with-infura-28e41844cc89/ # Set your own Infura API or Alchemy API key -ETH_NODE_URL=https://rinkeby.infura.io/v3/your-infura-api-key -#ETH_NODE_URL=https://eth-rinkeby.alchemyapi.io/v2/your-alchemy-api-key +ETH_NODE_URL=https://goerli.infura.io/v3/ +#ETH_NODE_URL=https://eth-goerli.alchemyapi.io/v2/ #ETH_NODE_URL=https://api.avax-test.network/ext/bc/C/rpc # The 12 word "secret recovery phrase" for the ethereum address @@ -35,22 +34,24 @@ ETH_NODE_URL=https://rinkeby.infura.io/v3/your-infura-api-key # It will be used to create the HD wallet and sign transactions on your behalf. WALLET_MNEMONIC=... +######################## Snapshot Hub env vars ######################## +ALCHEMY_API_URL=https://eth-goerli.alchemyapi.io/v2/ ######################## Tribute UI env vars ######################## -# Configure the UI to use the Rinkeby network for local development -REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=RINKEBY +# Configure the UI to use the Goerli network for local development +REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=GOERLI # It can be the same value you used for the Tribute DAO deployment. REACT_APP_INFURA_PROJECT_ID_DEV=INFURA_API_KEY -# The address of the Multicall smart contract deployed to the Rinkeby network. -# Copy that from the tribute-contracts/build/deployed/contracts-rinkeby-YYYY-MM-DD-HH:mm:ss.json +# The address of the Multicall smart contract deployed to the Goerli network. +# Copy that from the tribute-contracts/build/deployed/contracts-goerli-YYYY-MM-DD-HH:mm:ss.json REACT_APP_MULTICALL_CONTRACT_ADDRESS=0x... -# The address of the DaoRegistry smart contract deployed to the Rinkeby network. -# Copy that from the tribute-contracts/build/deployed/contracts-rinkeby-YYYY-MM-DD-HH:mm:ss.json +# The address of the DaoRegistry smart contract deployed to the Goerli network. +# Copy that from the tribute-contracts/build/deployed/contracts-goerli-YYYY-MM-DD-HH:mm:ss.json REACT_APP_DAO_REGISTRY_CONTRACT_ADDRESS=0x... -# Enable Rinkeby network for Tribute UI +# Enable Goerli network for Tribute UI REACT_APP_ENVIRONMENT=development diff --git a/README.md b/README.md index 8034ade57..4d459179d 100644 --- a/README.md +++ b/README.md @@ -179,13 +179,7 @@ npm run compile ### Deploy contracts -Deploy contracts to networks such as rinkeby, goerli, harmonytest, polygontest, ganache, mainnet, harmony, polygon or avalanche. - -```sh -npm run deploy rinkeby -``` - -OR +Deploy contracts to networks such as goerli, harmonytest, polygontest, ganache, mainnet, harmony, polygon or avalanche. ```sh npm run deploy goerli @@ -238,7 +232,7 @@ For more information about the deployment, see the in logs [logs/contracts](logs ### Verify contracts ```sh -npm run verify rinkeby +npm run verify goerli ``` OR @@ -254,21 +248,21 @@ In the same `.env` file created under the `tribute-contracts` folder, set the fo ``` ######################## Tribute UI env vars ######################## -# Configure the UI to use the Rinkeby network for local development -REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=RINKEBY +# Configure the UI to use the Goerli network for local development +REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=GOERLI # It can be the same value you used for the Tribute DAO deployment. REACT_APP_INFURA_PROJECT_ID_DEV=YOUR_INFURA_API_KEY -# The address of the Multicall smart contract deployed to the Rinkeby network. -# Copy that from the tribute-contracts/build/contracts-rinkeby-YYYY-MM-DD-HH:mm:ss.json +# The address of the Multicall smart contract deployed to the Goerli network. +# Copy that from the tribute-contracts/build/contracts-goerli-YYYY-MM-DD-HH:mm:ss.json REACT_APP_MULTICALL_CONTRACT_ADDRESS=0x... -# The address of the DaoRegistry smart contract deployed to the Rinkeby network. -# Copy that from the tribute-contracts/build/contracts-rinkeby-YYYY-MM-DD-HH:mm:ss.json +# The address of the DaoRegistry smart contract deployed to the Goerli network. +# Copy that from the tribute-contracts/build/contracts-goerli-YYYY-MM-DD-HH:mm:ss.json REACT_APP_DAO_REGISTRY_CONTRACT_ADDRESS=0x... -# Enable Rinkeby network for Tribute UI +# Enable Goerli network for Tribute UI REACT_APP_ENVIRONMENT=development ``` @@ -332,7 +326,7 @@ Snapshot-hub: - `ENV`: To indicate in which environment it is being executed: local, dev, or prod - `USE_IPFS`: To indicated the pinning service on IPFS should be enabled/disabled (if enabled cause delay in the responses) - `RELAYER_PK`: The PK of the account that will be used to sign the messages. -- `NETWORK`: The network name that will be used by the relayer (use testnet for: rinkeby or ropsten), and mainnet for the main eth network +- `NETWORK`: The network name that will be used by the relayer (use testnet for goerli and mainnet for the main ethereum network) - `JAWSDB_URL`: The postgres url: postgres://user:pwd@host:5432/db-name - `ALLOWED_DOMAINS`: The list of domains that should be allowed to send requests to the API - `ALCHEMY_API_URL`: The relayer API (alternative to Infura) diff --git a/configs/networks/rinkeby.config.ts b/configs/networks/rinkeby.config.ts deleted file mode 100644 index 340bc91d1..000000000 --- a/configs/networks/rinkeby.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { - contracts as defaultContracts, - ContractConfig, -} from "../contracts.config"; - -const disabled: Array = [ - // Utility & Test Contracts disabled by default - "OLToken", - "TestToken1", - "TestToken2", - "TestFairShareCalc", - "PixelNFT", - "ProxToken", - "ERC20Minter", - "MockDao", -]; - -export const contracts: Array = defaultContracts.map((c) => { - if (disabled.find((e) => e === c.name)) { - return { ...c, enabled: false }; - } - return c; -}); diff --git a/contracts/helpers/WETH.sol b/contracts/helpers/WETH.sol index 27618a9e4..3b4787643 100644 --- a/contracts/helpers/WETH.sol +++ b/contracts/helpers/WETH.sol @@ -1,5 +1,4 @@ -//WETH-03.24.2020.sol -//deployed March 24,2020 Rinkeby - 0x8DD25714CCEce48767BaF266EC4F220B60f84D52 +// WETH-03.24.2020.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; diff --git a/docker/README-ganache.md b/docker/README-ganache.md index 50cf1464b..5e2a189c7 100644 --- a/docker/README-ganache.md +++ b/docker/README-ganache.md @@ -19,7 +19,7 @@ In the root of `tribute-contracts` folder create a .env file. This file will con DAO_NAME=My Tribute DAO xyz... # The public ethereum address that belongs to the Owner of the DAO, -# in this case, it is your public ethereum address on Rinkeby network. +# in this case, it is your public ethereum address on the Ganache network. # Make sure you have some ETH, otherwise the deployment will fail. # It needs to be the address of the first account you have in metamask accounts, # otherwise it won't work. @@ -40,7 +40,7 @@ ERC20_TOKEN_DECIMALS=0 # The Ethereum Node URL to connect the Ethereum network. You can follow # these steps to get your ProjectId/API Key from Infura: # https://blog.infura.io/getting-started-with-infura-28e41844cc89/ -# Or can use the default one from OpenLaw team, or set your own Infura/Alchemy API keys +# Set your own Infura/Alchemy API keys ETH_NODE_URL=http://localhost:7545 # The 12 word "secret recovery phrase" for the ethereum address @@ -88,11 +88,11 @@ REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=GANACHE # It can be the same value you used for the Tribute DAO deployment. REACT_APP_INFURA_PROJECT_ID_DEV=set-your-infura-api-key-here -# The address of the Multicall smart contract deployed to the Rinkeby network. +# The address of the Multicall smart contract deployed to the Ganache network. # Copy that from the tribute-contracts/build/deployed/contracts-ganache-YYYY-MM-DD-HH:mm:ss.json REACT_APP_MULTICALL_CONTRACT_ADDRESS=0x... -# The address of the DaoRegistry smart contract deployed to the Rinkeby network. +# The address of the DaoRegistry smart contract deployed to the Ganache network. # Copy that from the tribute-contracts/build/deployed/contracts-ganache-YYYY-MM-DD-HH:mm:ss.json REACT_APP_DAO_REGISTRY_CONTRACT_ADDRESS=0x... ``` diff --git a/docker/README.md b/docker/README.md index 0ccb12c64..e8804858d 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,4 +1,4 @@ -## Launching a Tribute DAO on Rinkeby +## Launching a Tribute DAO on Goerli ### 1. Clone tribute-contracts repository @@ -19,7 +19,7 @@ In the root of `tribute-contracts` folder create a `.env` file. This file will c DAO_NAME=My Tribute DAO xyz... # The public ethereum address that belongs to the Owner of the DAO, -# in this case, it is your public ethereum address on Rinkeby network. +# in this case, it is your public ethereum address on the Goerli network. # Make sure you have some ETH, otherwise the deployment will fail. # It needs to be the address of the first account you have in metamask accounts, # otherwise it won't work. @@ -40,10 +40,9 @@ ERC20_TOKEN_DECIMALS=0 # The Ethereum Node URL to connect the Ethereum network. You can follow # these steps to get your ProjectId/API Key from Infura: # https://blog.infura.io/getting-started-with-infura-28e41844cc89/ -# Or can use the default one from OpenLaw team, or set your own Infura/Alchemy API keys -ETH_NODE_URL=http://rinkeby.openlaw.io:8546 -#ETH_NODE_URL=https://rinkeby.infura.io/v3/ -#ETH_NODE_URL=https://eth-rinkeby.alchemyapi.io/v2/ +# Set your own Infura/Alchemy API keys +ETH_NODE_URL=https://goerli.infura.io/v3/ +#ETH_NODE_URL=https://eth-goerli.alchemyapi.io/v2/ # The 12 word "secret recovery phrase" for the ethereum address # referenced in DAO_OWNER_ADDR above. This can be found in your wallet. @@ -61,7 +60,7 @@ With the environment variables ready, we can install the project dependencies an Using NodeJS v16.x, run: -- > npm run build && npm run deploy rinkeby +- > npm run build && npm run deploy goerli ### 4. Set the tribute-ui environment variables @@ -72,21 +71,21 @@ In the same `.env` file created under the `tribute-contracts` folder, add the fo ``` ######################## Tribute UI env vars ######################## -# Configure the UI to use the Rinkeby network for local development -REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=RINKEBY +# Configure the UI to use the Goerli network for local development +REACT_APP_DEFAULT_CHAIN_NAME_LOCAL=GOERLI # It can be the same value you used for the Tribute DAO deployment. REACT_APP_INFURA_PROJECT_ID_DEV=set-your-infura-api-key-here -# The address of the Multicall smart contract deployed to the Rinkeby network. -# Copy that from the tribute-contracts/build/deployed/contracts-rinkeby-YYYY-MM-DD-HH:mm:ss.json +# The address of the Multicall smart contract deployed to the Goerli network. +# Copy that from the tribute-contracts/build/deployed/contracts-goerli-YYYY-MM-DD-HH:mm:ss.json REACT_APP_MULTICALL_CONTRACT_ADDRESS=0x... -# The address of the DaoRegistry smart contract deployed to the Rinkeby network. -# Copy that from the tribute-contracts/build/deployed/contracts-rinkeby-YYYY-MM-DD-HH:mm:ss.json +# The address of the DaoRegistry smart contract deployed to the Goerli network. +# Copy that from the tribute-contracts/build/deployed/contracts-goerli-YYYY-MM-DD-HH:mm:ss.json REACT_APP_DAO_REGISTRY_CONTRACT_ADDRESS=0x... -# Enable Rinkeby network for Tribute UI +# Enable Goerli network for Tribute UI REACT_APP_ENVIRONMENT=development ``` diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 60f9b23a5..75ff8e5b3 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -6,11 +6,12 @@ services: trib-snapshot-hub: image: openlaw/snapshot-hub:v5.0.1-erc712 container_name: trib-snapshot-hub + env_file: + - ../.env environment: ENV: "local" PORT: 8080 RELAYER_PK: "0xb80a5165a59af8ce566266fcd0e919e13ed4ecbd57ae952e73ae2cddc08b84c6" - ALCHEMY_API_URL: "http://rinkeby.openlaw.io:8545" JAWSDB_URL: "postgres://snap:pwd123@trib-snapshot-db:5432/snapshot-db" IGNORE_VOTE_END_CONSTRAINT: "true" ALLOWED_DOMAINS: "http://localhost:3000" diff --git a/hardhat.config.js b/hardhat.config.js index 34e480af1..90aa9e819 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -56,31 +56,6 @@ module.exports = { }, signerId: process.env.SIGNER || undefined, }, - rinkeby: { - url: process.env.ETH_NODE_URL, - network_id: 4, - chainId: 4, - skipDryRun: true, - gas: 2100000, - gasPrice: 4000000000, - accounts: { - mnemonic: process.env.WALLET_MNEMONIC || "", - count: 10, - }, - signerId: process.env.SIGNER || undefined, - }, - ropsten: { - url: process.env.ETH_NODE_URL, - network_id: 3, - chainId: 3, - gas: 2100000, - gasPrice: 4000000000, - accounts: { - mnemonic: process.env.WALLET_MNEMONIC || "", - count: 10, - }, - signerId: process.env.SIGNER || undefined, - }, harmonytest: { url: process.env.ETH_NODE_URL, network_id: 1666700000, @@ -223,7 +198,7 @@ module.exports = { etherscan: { apiKey: { - rinkeby: process.env.ETHERSCAN_API_KEY, + goerli: process.env.ETHERSCAN_API_KEY, mainnet: process.env.ETHERSCAN_API_KEY, }, }, diff --git a/package.json b/package.json index 3f6ace8fd..a6915661e 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,10 @@ "main": "hardhat-config.js", "directories": { "test": "test" + }, + "engines" : { + "npm" : ">=7.0.0 <9.0.0", + "node" : ">=16.0.0 <17.0.0" }, "scripts": { "build": "npm ci && npm run compile", diff --git a/signers/DefenderSignerProvider.ts b/signers/DefenderSignerProvider.ts index 279148380..d24c28733 100644 --- a/signers/DefenderSignerProvider.ts +++ b/signers/DefenderSignerProvider.ts @@ -26,7 +26,7 @@ export class DefenderSignerProvider extends ProviderWrapper { ) { super(provider); this.chainId = chainId; - const p = ethers.getDefaultProvider("rinkeby"); + const p = ethers.getDefaultProvider("goerli"); this.signer = new DefenderRelaySigner( { apiKey: config.apiKey, diff --git a/signers/README.md b/signers/README.md index 3a0da8ef1..8a0b0fc70 100644 --- a/signers/README.md +++ b/signers/README.md @@ -1,6 +1,6 @@ # Signers -A Signer Provider can be used to sign transactions using a private key managed by an external service, so that transaction can be send to the network using any sort of Network Provider. +A Signer Provider can be used to sign transactions using a private key managed by an external service, so that transaction can be sent to the network using any sort of Network Provider. In this hardhat plugin we currently support two types of Signers: OZ Defender Signer and Google KMS Signer. @@ -9,10 +9,10 @@ Both signers are acting as external signers only. We don't use them to forward t In order to enable a signer for a particular network set the `signerId` to the network config in the `hardhat.config.ts` file: ``` -rinkeby: { +goerli: { url: process.env.ETH_NODE_URL, - network_id: 4, - chainId: 4, + network_id: 5, + chainId: 5, skipDryRun: true, gas: 2100000, gasPrice: 4000000000, diff --git a/tasks/deploy.js b/tasks/deploy.js index 5224a0827..80b99c9dd 100644 --- a/tasks/deploy.js +++ b/tasks/deploy.js @@ -39,8 +39,13 @@ task("deploy", "Deploy the list of contracts", async (args, hre) => { daoArtifacts ); const accounts = await hre.ethers.getSigners(); - accounts.map((a, i) => log(`Account ${i}: ${a.address}`)); + info( + `\nAvailable Accounts\n-----------------------------------------------------------` + ); + accounts.map((a, i) => log(` Account ${i}: ${a.address}`)); + info(`-----------------------------------------------------------`); + info(`\n Deploying contracts...\n`); const result = await deploy({ network, deployFunction, @@ -50,6 +55,8 @@ task("deploy", "Deploy the list of contracts", async (args, hre) => { accounts, }); + info(`\n Deployment completed with success.\n`); + const { dao, factories, @@ -62,13 +69,30 @@ task("deploy", "Deploy the list of contracts", async (args, hre) => { if (dao) { await dao.finalizeDao(); + const addresses = { + // The addresses of all identity contracts + identities: { + DaoRegistry: dao.identity.address, + }, + DaoRegistry: dao.address, + }; + + info( + `\nIdentity Contracts\n-----------------------------------------------------------` + ); + log(`DaoRegistry: ${addresses.identities.DaoRegistry}`); + Object.values(extensions) + .filter((f) => f.identity) + .forEach((c) => { + log(`${c.configs.name}: ${c.identity.address}`); + addresses.identities[c.configs.name] = c.identity.address; + }); info( - `\nAvailable Contracts\n-------------------------------------------------` + `\nDAO Contracts\n-----------------------------------------------------------` ); log(`DaoOwner: ${owner}`); log(`DaoRegistry: ${dao.address}`); - const addresses = { DaoRegistry: dao.address }; Object.values(factories) .concat(Object.values(extensions)) .concat(Object.values(adapters)) @@ -78,6 +102,7 @@ task("deploy", "Deploy the list of contracts", async (args, hre) => { log(`${c.configs.name}: ${c.address}`); addresses[c.configs.name] = c.address; }); + saveDeployedContracts(network, addresses); log( `Deployment to ${network} network was completed at ${new Date().toISOString()}` @@ -89,7 +114,7 @@ task("deploy", "Deploy the list of contracts", async (args, hre) => { } }); -const deployRinkebyDao = async ({ +const deployGoerliDao = async ({ deployFunction, attachFunction, contractImports, @@ -101,17 +126,17 @@ const deployRinkebyDao = async ({ deployFunction, attachFunction, maxAmount: getOptionalEnvVar("MAX_AMOUNT", maxAmount), - unitPrice: toWei("0.1"), - nbUnits: toBN("100000"), + unitPrice: getOptionalEnvVar("UNIT_PRICE", toWei("0.1")), + nbUnits: getOptionalEnvVar("UNITS_PER_CHUNK", toBN("100000")), maxUnits: getOptionalEnvVar("MAX_UNITS", maxUnits), - tokenAddr: ETH_TOKEN, + tokenAddr: getOptionalEnvVar("PAYMENT_TOKEN_ADDR", ETH_TOKEN), erc20TokenName: getEnvVar("ERC20_TOKEN_NAME"), erc20TokenSymbol: getEnvVar("ERC20_TOKEN_SYMBOL"), erc20TokenDecimals: getEnvVar("ERC20_TOKEN_DECIMALS"), erc20TokenAddress: UNITS, maxChunks: getOptionalEnvVar("MAX_CHUNKS", maximumChunks), votingPeriod: getOptionalEnvVar("VOTING_PERIOD_SECONDS", 600), // 600 secs = 10 min - gracePeriod: getOptionalEnvVar("GRACE_PERIOD_SECONDS", 600), // 600 secs = 10 min + gracePeriod: getOptionalEnvVar("GRACE_PERIOD_SECONDS", 300), // 300 secs = 5 min offchainVoting: true, finalize: false, maxExternalTokens: 100, @@ -139,7 +164,7 @@ const deployRinkebyDao = async ({ "OFFCHAIN_ADMIN_ADDR", getEnvVar("DAO_OWNER_ADDR") ), - deployTestTokens: true, + deployTestTokens: false, supplyTestToken1: 1000000, supplyTestToken2: 1000000, supplyPixelNFT: 100, @@ -152,7 +177,7 @@ const deployRinkebyDao = async ({ "GELATO_ADDR", "0xDe6ab16a4015c680daab58021815D09ddB57db8E" ), - weth: "0xc778417e063141139fce010982780140aa0cd5ab", + weth: "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6", maintainerTokenAddress: getOptionalEnvVar("MAINTAINER_TOKEN_ADDR", UNITS), }); }; @@ -741,6 +766,7 @@ const saveDeployedContracts = (network, addresses) => { const DeploymentActions = { mainnet: deployMainnetDao, + goerli: deployGoerliDao, ganache: deployGanacheDao, harmony: deployHarmonyDao, harmonytest: deployHarmonyTestDao, @@ -749,10 +775,6 @@ const DeploymentActions = { avalanchetest: deployAvalancheTestDao, avalanche: deployAvalancheDao, - // Goerli and Rinkeby should be treated the same - goerli: deployRinkebyDao, - rinkeby: deployRinkebyDao, - // Test and Coverage should be treated the same test: deployTestDao, coverage: deployTestDao, diff --git a/tasks/verify.ts b/tasks/verify.ts index 2d2aab11a..edfd0fd9c 100755 --- a/tasks/verify.ts +++ b/tasks/verify.ts @@ -30,9 +30,9 @@ const skipContracts = [ const args = process.argv.slice(2); if (!args || args.length === 0) - throw Error("Missing one of the network names: [rinkeby, ropsten, mainnet]"); + throw Error("Missing one of the network names: [goerli, mainnet]"); -const network = args[0] || "rinkeby"; +const network = args[0] || "goerli"; log(`Selected Network: ${network}`); const sleep = (msec: number) => { @@ -107,6 +107,12 @@ const main = async () => { const verifyContracts = contractConfigs .filter((c: ContractConfig) => !skipContracts.includes(c.name)) .map((c: ContractConfig) => { + if (deployedContracts.identities && deployedContracts.identities[c.name]) { + return { + contractAddress: deployedContracts.identities[c.name], + contractName: c.name, + }; + } return { contractAddress: deployedContracts[c.name], contractName: c.name, diff --git a/truffle-config.js b/truffle-config.js index 7dafdc32b..6aba21675 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -40,12 +40,6 @@ module.exports = { network_id: 5, skipDryRun: true, }, - rinkeby: { - provider: getNetworkProvider, - network_id: 4, - chainId: 4, - skipDryRun: true, - }, mainnet: { provider: getNetworkProvider, network_id: 1, diff --git a/utils/contract-util.js b/utils/contract-util.js index 7b6571be0..d43b7be35 100644 --- a/utils/contract-util.js +++ b/utils/contract-util.js @@ -72,10 +72,11 @@ const maxUnits = toBN("10000000000000000000"); const waitTx = async (p) => { try { - const res = await p; + let res = await p; if (res && res.wait) { - await res.wait(); + res = await res.wait(); } + return res; } catch (err) { error(err); diff --git a/utils/deployment-util.js b/utils/deployment-util.js index 85deaf27c..42b631e8f 100644 --- a/utils/deployment-util.js +++ b/utils/deployment-util.js @@ -149,16 +149,26 @@ const createExtensions = async ({ dao, factories, options }) => { } /** * The tx event is the safest way to read the new extension address. - * Event at index 0 indicates the extension was created - * Arg at index 1 represents the new extension address + * 1. Find the event that contains the `args` field which indicates the factory event + * 2. Take the data at index 1 which represents the new extension address */ let extensionAddress; + if (tx.wait) { const res = await tx.wait(); - extensionAddress = res.events[0].args[1]; + const factoryEvent = res.events.find( + (e) => e.address === factory.address + ); + if (!factoryEvent) throw new Error("Missing factory event."); + + extensionAddress = factoryEvent.args[1]; } else { const { logs } = tx; - extensionAddress = logs[0].args[1]; + const factoryLog = logs.find((l) => l.address === factory.address); + if (!factoryLog) { + throw new Error("no event emitted by the factory"); + } + extensionAddress = factoryLog.args[1]; } const extensionInterface = options[extensionConfigs.name]; if (!extensionInterface) @@ -188,9 +198,11 @@ const createExtensions = async ({ dao, factories, options }) => { Extension enabled '${newExtension.configs.name}' ------------------------------------------------- contract address: ${newExtension.address} - creator address: ${options.owner}`); + creator address: ${options.owner} + identity address: ${factory.identity.address} + `); - return newExtension; + return { ...newExtension, identity: factory.identity }; }; await Object.values(factories).reduce( @@ -480,10 +492,23 @@ const cloneDao = async ({ }) => { const daoFactory = await deployFunction(DaoFactory, [DaoRegistry]); await waitTx(daoFactory.createDao(name, creator ? creator : owner)); + const daoAddress = await daoFactory.getDaoAddress(name); if (daoAddress === ZERO_ADDRESS) throw Error("Invalid dao address"); const daoInstance = await attachFunction(DaoRegistry, daoAddress); - return { dao: daoInstance, daoFactory, daoName: name }; + info(` + Cloned 'DaoRegistry' + ------------------------------------------------- + contract address: ${daoAddress} + identity contract: ${daoFactory.identity.address} + owner: ${creator ? creator : owner} + name: ${name}`); + + return { + dao: { ...daoInstance, identity: daoFactory.identity }, + daoFactory, + daoName: name, + }; }; /** diff --git a/utils/hardhat-test-util.js b/utils/hardhat-test-util.js index 2d600c697..2dc06bc60 100644 --- a/utils/hardhat-test-util.js +++ b/utils/hardhat-test-util.js @@ -108,6 +108,13 @@ const deployFunction = async (contractInterface, args, from) => { const identityInstance = await identityInterface.new({ from: f }); const constructorArgs = [identityInstance.address].concat(args.slice(1)); instance = await contractInterface.new(...constructorArgs, { from: f }); + instance = { + ...instance, + identity: { + name: identityInstance.name, + address: identityInstance.address, + }, + }; } else { if (args) { instance = await contractInterface.new(...args, { from: f }); diff --git a/utils/hardhat-util.js b/utils/hardhat-util.js index cdaae3af4..c6da56e54 100644 --- a/utils/hardhat-util.js +++ b/utils/hardhat-util.js @@ -116,10 +116,12 @@ const deployFunction = async ({ allConfigs, network, daoArtifacts }) => { ------------------------------------------------- contract address: ${contractAddress}`); const instance = await attach(contractInterface, contractAddress); + return { ...instance, configs: contractConfig }; } let deployedContract; + // When the contract is not found in the DaoArtifacts, deploy a new one if (contractConfig.type === ContractType.Factory && args) { // 1. first create a new identity contract @@ -127,12 +129,19 @@ const deployFunction = async ({ allConfigs, network, daoArtifacts }) => { const identityConfig = allConfigs.find( (c) => c.name === identityInterface.contractName ); - const identityInstance = await deploy(identityInterface, identityConfig); + const identityContract = await deploy(identityInterface, identityConfig); // 2 deploy the factory with the new identity address, so it can be used for cloning ops later on deployedContract = await deploy(contractInterface, contractConfig, [ - identityInstance.address, + identityContract.address, ]); + deployedContract = { + ...deployedContract, + identity: { + name: identityInterface.contractName, + address: identityContract.address, + }, + }; } else { deployedContract = await deploy(contractInterface, contractConfig, args); }