diff --git a/.env.example b/.env.example index 530e2d8..c572777 100644 --- a/.env.example +++ b/.env.example @@ -1,25 +1,27 @@ # GENERAL ## The network used for testing purposes -NETWORK_NAME="mainnet" # ["mainnet", "sepolia", "polygon", "polygonMumbai"] +NETWORK_NAME="sepolia" # ["mainnet", "sepolia", "polygon", "polygonMumbai"] -# CONTRACTS +# PROTOCOL CONTRACTS + +PLUGIN_REPO_FACTORY_ADDRESS="0xA69347F49dD618cb4577670D0728684AfAa01197" +PLUGIN_SETUP_PROCESSOR_ADDRESS="0xAc7e4fB4a2f58b7EA5516f47b6f804956Faf0134" ## Hex encoded private keys separated by a comma `,`a PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" # Default hardhat account 0 private key. DON'T USE FOR DEPLOYMENTS -## Infura credentials +## API keys INFURA_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" +ETHERSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" # Needed for contract verification +POLYGONSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" +BASESCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" + ## Gas Reporting REPORT_GAS='true' COINMARKETCAP_API_KEY="zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz" -## Block explorers -ETHERSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" -POLYGONSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" -BASESCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" - # SUBGRAPH ## The Graph credentials diff --git a/README.md b/README.md index 7f60c1d..aeb3507 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ yarn build yarn test ``` +See [Deployment](#deployment) below + ## Overview A Space is composed by a DAO and several plugins installed on it. The [DAO](https://github.com/aragon/osx/blob/develop/packages/contracts/src/core/dao/DAO.sol) contract holds all the assets and rights to act on external components, while plugins are custom, composable, opt-in pieces of logic that can perform certain actions governed by the DAO's permission database. @@ -772,3 +774,112 @@ The plugins from this repo are built on top of many contract primitives from Ara - `minProposerVotingPower` wasn't used The rest of dependencies are imported directly from Aragon or from OpenZeppelin. + +## Deployment + +### On a blockchain supported by Aragon + +If the current contracts are meant to be deployed on a blockchain like Mainnet, Sepolia, Polygon, Base, etc, the only step needed is to define the relevant env vars on `.env` and run the following command: + +```sh +cd packages/contracts +npx hardhat deploy --network +``` + +### On a custom blockchain + +In the case of specific blockchains where OSx support is not officially available, you will need to deploy it first. The high level process looks like: + +0. Prepare a wallet for the whole deployment process +1. Deploy OSx + 1. This will create a Managing DAO, where the deployer wallet can `execute()` actions +2. Deploy the plugins of this project +3. Install the plugin that will control the Managing DAO +4. Revoke the `ROOT_PERMISSION` from the deployment wallet on the DAO + +#### 1) Deploy OSx + +Clone [https://github.com/aragon/osx](the OSx repo) into a separate folder. + +```sh +yarn +cd packages/contracts +yarn build +yarn test +``` + +- Edit the `packages/contracts/hardhat.config.ts` to include the details of your target network. +- Edit the `.env` file to make use of the deployment wallet's private key. + +```sh +npx hardhat deploy --network +``` + +Write down the address of the deployed contracts. The result should look similar to this: + +```json +{ + "managingDAOImplementation": "0x731b7F3d74C9dc25A90af73B960ad51f42481d6c", + "managingDAO": "0x1C57A251B1902656693f689aA69389f2a6f2a432", + "ENSRegistry": "0xE847017f1e18F7bF35b180fD45b4dAC18E81d568", + "PublicResolver": "0xE3B1288048f898A28a78FCf9942E14Cc853fFEF2", + "DAO_ENSSubdomainRegistrar_Implementation": "0xd92C33f309D6e795DCe1980aBc42D3431b0af0e7", + "DAO_ENSSubdomainRegistrar": "0xcf9D94Ddd248694B66D1D445b85ccbE385634Cc8", + "Plugin_ENSSubdomainRegistrar_Implementation": "0x7BC82fCba3521B15792423ac4E6076582235263B", + "Plugin_ENSSubdomainRegistrar": "0xd14C706586c6177d54D201df009b75FB14E8AB5E", + "DAORegistry_Implementation": "0x66a19CC345dAB31dfb6295017819d54dB594DE56", + "DAORegistry": "0x11d3B1B24C19B5672b92CD535d2F1F35C53AC543", + "PluginRepoRegistry_Implementation": "0x38b112318cfd563Fa5de538E7c219bf72F1CcA6a", + "PluginRepoRegistry": "0x9b51505f7bf3A45BC92F6bE269324096abEC0A73", + "PluginRepoFactory": "0xA69347F49dD615cb4577670D0728684AfAa01197", + "PluginSetupProcessor": "0xAc7e4fB4a2158b7EA5516f47b6f804956Faf0134", + "DAOFactory": "0x2d11E9413264e3814C2a21160cBCcb9Dc3C96890" +} +``` + +You are going to need the `PluginRepoFactory`, the `PluginSetupProcessor` and the `managingDAO`. + +#### 2) Deploy your plugins + +On this repository: + +- Edit the `packages/contracts/hardhat.config.ts` to include the details of your target network. +- Edit the `packages/contracts/plugin-setup-params.ts` to define the details of your new plugins + - Make sure that you don't deploy the same plugin repo twice, since this will cause an ENS collision + - In such case, either define a new ENS subdomain or consider running the step 1 again +- Edit the `.env` file + - Define the deployment wallet's private key + - Define the `PLUGIN_REPO_FACTORY_ADDRESS` and the `PLUGIN_SETUP_PROCESSOR_ADDRESS` from the contracts [deployed above](#1-deploy-osx) + +```sh +cd packages/contracts +yarn build +npx hardhat deploy --network +``` + +With this step, the deployment would be technically done. + +However, as the maintainer of the deployment, you are strongly encouraged to configure the Managing DAO such in a way that updates are approved by a group of people. + +#### 3) Install a governance plugin to the Managing DAO + +The Managing DAO is the contract that has the role of managing certain protocol modules, like the Plugin Registry, the DAO registry, etc. In case a new OSx version is available, only that DAO is be able to push upgrades and perform certain management tasks, which makes it a key component. + +The Managing DAO will be created with the following permissions: + +- The Managing DAO holds `ROOT_PERMISSION` on itself +- The deployer address holds `EXECUTE_PERMISSION` on the Managing DAO + +Among the plugins deployed [in the step above](#2-deploy-your-plugins), one of them should be installed to the Managing DAO. + +In your custom script make sure to: + +1. Use the same deployment wallet as before +2. Call `prepareInstallation()` on the Plugin Setup Processor deployed during the [Deploy OSX](#1-deploy-osx) step +3. Call `execute()` on the Managing DAO, with an action that calls `applyInstallation()` on the Plugin Setup Processor + +#### 4) Drop the ROOT permission of the deployer + +In the same custom script as before: + +1. Call `execute()` on the Managing DAO, with an action that calls `revoke(dao, deploymentWalletAddr, ROOT_PERMISSION_ID)` on the DAO itself diff --git a/packages/contracts/deploy/01_repo/10_create_repo.ts b/packages/contracts/deploy/01_repo/10_create_repo.ts index 09a0cc1..dc2731f 100644 --- a/packages/contracts/deploy/01_repo/10_create_repo.ts +++ b/packages/contracts/deploy/01_repo/10_create_repo.ts @@ -30,16 +30,28 @@ async function deployRepo( hre: HardhatRuntimeEnvironment, ensSubdomain: string ) { + const {network} = hre; + let pluginRepoFactoryAddr: string; + + if (!process.env.PLUGIN_REPO_FACTORY_ADDRESS) { + pluginRepoFactoryAddr = getPluginRepoFactoryAddress(network.name); + if (!pluginRepoFactoryAddr) + throw new Error( + 'PLUGIN_REPO_FACTORY_ADDRESS is empty and no default value is available for ' + + network.name + ); + + console.log( + 'Using the default Plugin Repo Factory address (PLUGIN_REPO_FACTORY_ADDRESS is empty)' + ); + } else { + pluginRepoFactoryAddr = process.env.PLUGIN_REPO_FACTORY_ADDRESS; + } + console.log(`\nDeploying the "${ensSubdomain}" plugin repo`); - const {network} = hre; const [deployer] = await hre.ethers.getSigners(); - // Get the PluginRepoFactory address - const pluginRepoFactoryAddr: string = getPluginRepoFactoryAddress( - network.name - ); - const pluginRepoFactory = PluginRepoFactory__factory.connect( pluginRepoFactoryAddr, deployer diff --git a/packages/contracts/deploy/02_setup/10_setup.ts b/packages/contracts/deploy/02_setup/10_setup.ts index 9f3b18d..d45e48f 100644 --- a/packages/contracts/deploy/02_setup/10_setup.ts +++ b/packages/contracts/deploy/02_setup/10_setup.ts @@ -12,7 +12,21 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const {deploy} = deployments; const {deployer} = await getNamedAccounts(); - const pspAddress = getPluginSetupProcessorAddress(network.name); + let pspAddress: string; + if (!process.env.PLUGIN_SETUP_PROCESSOR_ADDRESS) { + pspAddress = getPluginSetupProcessorAddress(network.name); + if (!pspAddress) + throw new Error( + 'PLUGIN_SETUP_PROCESSOR_ADDRESS is empty and no default value is available for ' + + network.name + ); + + console.log( + 'Using the default Plugin Setup Processor address (PLUGIN_SETUP_PROCESSOR_ADDRESS is empty)' + ); + } else { + pspAddress = process.env.PLUGIN_SETUP_PROCESSOR_ADDRESS; + } // Space Setup console.log(