diff --git a/.env.example b/.env.example index d277cd52..6bdb3c76 100644 --- a/.env.example +++ b/.env.example @@ -1,15 +1,15 @@ # GENERAL ## The network used for testing purposes -NETWORK_NAME="sepolia" # ["mainnet", "sepolia", "polygon", "polygonMumbai", "base", "baseSepolia", "arbitrum", "arbitrumSepolia"] +NETWORK_NAME="sepolia" # ["mainnet", "sepolia", "polygon", "baseMainnet", "arbitrum"] # CONTRACTS ## One or multiple hex encoded private keys separated by commas `,` replacing the hardhat default accounts. PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" # Default hardhat account 0 private key. DON'T USE FOR DEPLOYMENTS -## Infura credentials -INFURA_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" +## Alchemy RPC endpoint credentials +ALCHEMY_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" ## Gas Reporting REPORT_GAS='true' @@ -29,4 +29,4 @@ GRAPH_KEY="zzzzzzzzzzzz" ## Subgraph SUBGRAPH_NAME="osx" SUBGRAPH_VERSION="v1.0.0" -SUBGRAPH_NETWORK_NAME="mainnet" # ["mainnet", "goerli", "sepolia", "polygon", "polygonMumbai", "base", "baseSepolia", "arbitrum", "arbitrumSepolia"] +SUBGRAPH_NETWORK_NAME="mainnet" # ["mainnet", "sepolia", "polygon", "base", "arbitrum"] diff --git a/.github/workflows/contracts-tests.yml b/.github/workflows/contracts-tests.yml index e4b3728b..fb34a28e 100644 --- a/.github/workflows/contracts-tests.yml +++ b/.github/workflows/contracts-tests.yml @@ -2,7 +2,7 @@ name: 'contracts' on: workflow_dispatch: - push: + pull_request: paths: - 'packages/contracts/**' - '.github/workflows/contracts-*.yml' @@ -31,10 +31,10 @@ jobs: - name: 'Build the contracts' run: 'yarn build' env: - INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }} + ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }} - name: 'Test the contracts and generate the coverage report' run: 'yarn coverage' env: NETWORK_NAME: ${{ vars.NETWORK_NAME }} - INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }} + ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }} diff --git a/.github/workflows/subgraph-tests.yml b/.github/workflows/subgraph-tests.yml index dd492b1e..ef013b86 100644 --- a/.github/workflows/subgraph-tests.yml +++ b/.github/workflows/subgraph-tests.yml @@ -2,7 +2,7 @@ name: 'subgraph' on: workflow_dispatch: - push: + pull_request: paths: - 'packages/subgraph/**' - 'packages/contracts/**' @@ -41,7 +41,7 @@ jobs: working-directory: packages/subgraph env: SUBGRAPH_NETWORK_NAME: ${{ vars.SUBGRAPH_NETWORK_NAME }} - INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }} + ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }} - name: 'Test the subgraph' run: yarn test diff --git a/README.md b/README.md index ae1c72e1..5604be6f 100644 --- a/README.md +++ b/README.md @@ -7,13 +7,12 @@ ## Quickstart -After [creating a new repository from this template](https://github.com/new?template_name=osx-plugin-template-hardhat&template_owner=aragon), cloning, and opening it in your IDE, run +After [creating a new repository from this template](https://github.com/new?template_name=osx-plugin-template-hardhat&template_owner=aragon), cloning, and opening it in your IDE, create an `.env` file from the `.env.example` file and put in the Alchemy API key. Feel free to add other API keys for the services that you want to use. Now run, ```sh yarn install && cd packages/contracts && yarn install && yarn build && yarn typechain ``` -Meanwhile, create an `.env` file from the `.env.example` file and put in the API keys for the services that you want to use. You can now develop a plugin by changing the `src/MyPlugin.sol` and `src/MyPluginSetup.sol` files. You can directly import contracts from [Aragon OSx](https://github.com/aragon/osx) as well as OpenZeppelin's [openzeppelin-contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) and [openzeppelin-contracts-upgradeable](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable) that are already set up for you. ```sol @@ -38,7 +37,7 @@ yarn clean && yarn build && yarn test ## Project -The root folder of the repo includes three subfolders: +The root folder of the repo includes two subfolders: ```markdown . @@ -99,7 +98,7 @@ yarn lint To be able to work on the contracts, make sure that you have created an `.env` file from the `.env.example` file and put in the API keys for -- [Infura](https://www.infura.io/) that we use as the web3 provider +- [Alchemy](https://www.alchemy.com) that we use as the web3 provider - [Alchemy Subgraphs](https://www.alchemy.com/subgraphs) that we use as the subgraph provider - the block explorer that you want to use depending on the networks that you want to deploy to @@ -202,7 +201,7 @@ Deploy the contracts to the local Hardhat Network (being forked from the network yarn deploy --tags CreateRepo,NewVersion ``` -This will create a plugin repo and publish the the first version (`v1.1`) of your plugin. +This will create a plugin repo and publish the first version (`v1.1`) of your plugin. Deploy the contracts to sepolia with @@ -210,7 +209,7 @@ Deploy the contracts to sepolia with yarn deploy --network sepolia --tags CreateRepo,NewVersion,Verification ``` -This will create a plugin repo, publish the the first version (`v1.1`) of your plugin, and verfiy the contracts on sepolia. +This will create a plugin repo, publish the first version (`v1.1`) of your plugin, and verfiy the contracts on sepolia. If you want to deploy a new version of your plugin afterwards (e.g., `1.2`), simply change the `VERSION` entry in the `packages/contracts/plugin-settings.ts` file and use @@ -281,6 +280,10 @@ and finally the subgraph itself with yarn build:subgraph ``` +When running `yarn build`, it requires a plugin address, which is obtained from the configuration file located +at `subgraph/manifest/data/.json`, based on the network specified in your `.env` file under the `SUBGRAPH_NETWORK_NAME` variable. +You do not need to provide a plugin address for building or testing purposes, but it becomes necessary when deploying the subgraph. + During development of the subgraph, you might want to clean outdated files that were build, imported, and generated. To do this, run ```sh @@ -313,7 +316,8 @@ yarn coverage ### Deployment -To deploy the subgraph to the subgraph provider, write your intended subgraph name and version into the `SUBGRAPH_NAME` and `SUBGRAPH_VERSION` variables [in the `.env` file that you created in the beginning](environment-variables) and pick a network name `SUBGRAPH_NETWORK_NAME` [being supported by the subgraph provider](https://docs.alchemy.com/reference/supported-subgraph-chains). Then run +To deploy the subgraph to the subgraph provider, write your intended subgraph name and version into the `SUBGRAPH_NAME` and `SUBGRAPH_VERSION` variables [in the `.env` file that you created in the beginning](environment-variables) and pick a network name `SUBGRAPH_NETWORK_NAME` [being supported by the subgraph provider](https://docs.alchemy.com/reference/supported-subgraph-chains). Remember to place correctly the Plugin address on the network you are going to deploy to, you can do that by adding it on `subgraph/manifest/data/.json`. +Then run ```sh yarn deploy diff --git a/USAGE_GUIDE.md b/USAGE_GUIDE.md index 57bcc289..dda2f230 100644 --- a/USAGE_GUIDE.md +++ b/USAGE_GUIDE.md @@ -99,7 +99,9 @@ The standard deploy scripts in the `packages/contracts/deploy` should already be - Fetches the plugin setup and implementation contract and queues it for block explorer verification. - `20_new_version/23_publish.ts` - Publishes the plugin setup contract on the plugin repo created in `10_repo/11_create_repo.ts` -- `30_upgrade_repo/31_upgrade_repo.ts` +- `30_upgrade_repo/31a_upgrade_and_reinitialize_repo.ts` + - Upgrades the plugin repo to the latest Aragon OSx protocol version and reinitializes it. +- `30_upgrade_repo/31b_upgrade_repo.ts` - Upgrades the plugin repo to the latest Aragon OSx protocol version. - `40_conclude/41_conclude.ts` - Prints information on the used account's balance after deployment. @@ -142,7 +144,7 @@ GRAPH_KEY="zzzzzzzzzzzz" ## Subgraph SUBGRAPH_NAME="osx" SUBGRAPH_VERSION="v1.0.0" -SUBGRAPH_NETWORK_NAME="mainnet" # ["mainnet", "goerli", "sepolia", "polygon", "polygonMumbai", "base", "baseSepolia", "arbitrum", "arbitrumSepolia"] +SUBGRAPH_NETWORK_NAME="mainnet" # ["mainnet", "sepolia", "polygon", "base", "arbitrum"] ``` - `GRAPH_KEY`: This key will be used for deploying the subgraph. diff --git a/packages/contracts/deploy/00_info/01_info.ts b/packages/contracts/deploy/00_info/01_info.ts index ade3e9bb..d6f6acaa 100644 --- a/packages/contracts/deploy/00_info/01_info.ts +++ b/packages/contracts/deploy/00_info/01_info.ts @@ -1,3 +1,4 @@ +import {PLUGIN_REPO_ENS_SUBDOMAIN_NAME} from '../../plugin-settings'; import { AragonOSxAsciiArt, getProductionNetworkName, @@ -52,6 +53,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { await deployer.getBalance() )} native tokens.` ); + + console.log( + `Chosen PluginRepo ENS subdomain name: '${PLUGIN_REPO_ENS_SUBDOMAIN_NAME}'` + ); }; export default func; diff --git a/packages/contracts/deploy/10_create_repo/11_create_repo.ts b/packages/contracts/deploy/10_create_repo/11_create_repo.ts index b4ed1445..caf42237 100644 --- a/packages/contracts/deploy/10_create_repo/11_create_repo.ts +++ b/packages/contracts/deploy/10_create_repo/11_create_repo.ts @@ -58,8 +58,8 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Get the PluginRepo address and deployment block number from the txn and event therein const eventLog = - await findEventTopicLog( - tx, + findEventTopicLog( + await tx.wait(), PluginRepoRegistry__factory.createInterface(), 'PluginRepoRegistered' ); diff --git a/packages/contracts/deploy/20_new_version/23_publish.ts b/packages/contracts/deploy/20_new_version/23_publish.ts index ea146b9b..ddbb0bef 100644 --- a/packages/contracts/deploy/20_new_version/23_publish.ts +++ b/packages/contracts/deploy/20_new_version/23_publish.ts @@ -9,11 +9,8 @@ import { getPastVersionCreatedEvents, pluginEnsDomain, } from '../../utils/helpers'; -import { - PLUGIN_REPO_PERMISSIONS, - toHex, - uploadToIPFS, -} from '@aragon/osx-commons-sdk'; +import {PLUGIN_REPO_PERMISSIONS, uploadToIPFS} from '@aragon/osx-commons-sdk'; +import {ethers} from 'hardhat'; import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; import path from 'path'; @@ -89,8 +86,8 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const tx = await pluginRepo.createVersion( VERSION.release, setup.address, - toHex(buildMetadataURI), - toHex(releaseMetadataURI) + ethers.utils.hexlify(ethers.utils.toUtf8Bytes(buildMetadataURI)), + ethers.utils.hexlify(ethers.utils.toUtf8Bytes(releaseMetadataURI)) ); if (setup == undefined || setup?.receipt == undefined) { diff --git a/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts b/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts deleted file mode 100644 index f862559c..00000000 --- a/packages/contracts/deploy/30_upgrade_repo/31_upgrade_repo.ts +++ /dev/null @@ -1,163 +0,0 @@ -import {findPluginRepo, getProductionNetworkName} from '../../utils/helpers'; -import { - getLatestNetworkDeployment, - getNetworkNameByAlias, -} from '@aragon/osx-commons-configs'; -import { - PLUGIN_REPO_PERMISSIONS, - UnsupportedNetworkError, -} from '@aragon/osx-commons-sdk'; -import {PluginRepo__factory} from '@aragon/osx-ethers'; -import {BytesLike} from 'ethers'; -import {DeployFunction} from 'hardhat-deploy/types'; -import {HardhatRuntimeEnvironment} from 'hardhat/types'; -import path from 'path'; - -type SemVer = [number, number, number]; - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const [deployer] = await hre.ethers.getSigners(); - const productionNetworkName: string = getProductionNetworkName(hre); - const network = getNetworkNameByAlias(productionNetworkName); - if (network === null) { - throw new UnsupportedNetworkError(productionNetworkName); - } - const networkDeployments = getLatestNetworkDeployment(network); - if (networkDeployments === null) { - throw `Deployments are not available on network ${network}.`; - } - - // Get PluginRepo - const {pluginRepo, ensDomain} = await findPluginRepo(hre); - if (pluginRepo === null) { - throw `PluginRepo '${ensDomain}' does not exist yet.`; - } - - console.log( - `Upgrading plugin repo '${ensDomain}' (${pluginRepo.address})...` - ); - - // Get the latest `PluginRepo` implementation as the upgrade target - const latestPluginRepoImplementation = PluginRepo__factory.connect( - networkDeployments.PluginRepoBase.address, - deployer - ); - - // Get the current OSX protocol version from the current plugin repo implementation - let current: SemVer; - try { - current = await pluginRepo.protocolVersion(); - } catch { - current = [1, 0, 0]; - } - - // Get the OSX protocol version from the latest plugin repo implementation - const latest: SemVer = await latestPluginRepoImplementation.protocolVersion(); - - console.log( - `Upgrading from current protocol version v${current[0]}.${current[1]}.${current[2]} to the latest version v${latest[0]}.${latest[1]}.${latest[2]}.` - ); - - // NOTE: The following code can be uncommented and `initData` can be filled - // with arguments in case re-initialization of the `PluginRepo` should become necessary. - // Re-initialization will happen through a call to `function initializeFrom(uint8[3] calldata _previousProtocolVersion, bytes calldata _initData)` - // that Aragon might add to the `PluginRepo` contract once it's required. - /* - // Define the `_initData` arguments - const initData: BytesLike[] = []; - // Encode the call to `function initializeFrom(uint8[3] calldata _previousProtocolVersion, bytes calldata _initData)` with `initData` - const initializeFromCalldata = - latestPluginRepoImplementation.interface.encodeFunctionData('initializeFrom', [ - current, - initData, - ]); - */ - const initializeFromCalldata: BytesLike = []; - - // Check if deployer has the permission to upgrade the plugin repo - if ( - await pluginRepo.isGranted( - pluginRepo.address, - deployer.address, - PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, - [] - ) - ) { - // Use `upgradeToAndCall` if the new implementation must be re-initialized by calling - // on the `PluginRepo` proxy. If not, we use `upgradeTo`. - if (initializeFromCalldata.length > 0) { - await pluginRepo.upgradeToAndCall( - latestPluginRepoImplementation.address, - initializeFromCalldata - ); - } else { - await pluginRepo.upgradeTo(latestPluginRepoImplementation.address); - } - } else { - throw Error( - `The new version cannot be published because the deployer ('${deployer.address}') - is lacking the ${PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID} permission.` - ); - } -}; -export default func; -func.tags = ['UpgradeRepo']; - -/** - * Skips the plugin repo upgrade if exists in the plugin repo. - * @param {HardhatRuntimeEnvironment} hre - */ -func.skip = async (hre: HardhatRuntimeEnvironment) => { - console.log(`\n🏗️ ${path.basename(__filename)}:`); - - const [deployer] = await hre.ethers.getSigners(); - const productionNetworkName: string = getProductionNetworkName(hre); - const network = getNetworkNameByAlias(productionNetworkName); - if (network === null) { - throw new UnsupportedNetworkError(productionNetworkName); - } - const networkDeployments = getLatestNetworkDeployment(network); - if (networkDeployments === null) { - throw `Deployments are not available on network ${network}.`; - } - - // Get the latest `PluginRepo` implementation as the upgrade target - const latestPluginRepoImplementation = PluginRepo__factory.connect( - networkDeployments.PluginRepoBase.address, - deployer - ); - - const {pluginRepo, ensDomain} = await findPluginRepo(hre); - if (pluginRepo === null) { - throw `PluginRepo '${ensDomain}' does not exist yet.`; - } - - // Compare the current protocol version of the `PluginRepo` - let current: SemVer; - try { - current = await pluginRepo.protocolVersion(); - } catch { - current = [1, 0, 0]; - } - const target: SemVer = await latestPluginRepoImplementation.protocolVersion(); - - // Throw an error if attempting to upgrade to an earlier version - if ( - current[0] > target[0] || - current[1] > target[1] || - current[2] > target[2] - ) { - throw `The plugin repo, currently at 'v${current[0]}.${current[1]}.${current[2]}' cannot be upgraded to the earlier version v${target[0]}.${target[1]}.${target[2]}.`; - } - - // Skip if versions are equal - if (JSON.stringify(current) == JSON.stringify(target)) { - console.log( - `PluginRepo '${ensDomain}' (${pluginRepo.address}) has already been upgraded to - the current protocol version v${target[0]}.${target[1]}.${target[2]}. Skipping upgrade...` - ); - return true; - } - - return false; -}; diff --git a/packages/contracts/deploy/30_upgrade_repo/31a_upgrade_repo.ts b/packages/contracts/deploy/30_upgrade_repo/31a_upgrade_repo.ts new file mode 100644 index 00000000..6e428298 --- /dev/null +++ b/packages/contracts/deploy/30_upgrade_repo/31a_upgrade_repo.ts @@ -0,0 +1,36 @@ +import {fetchData, skipUpgrade} from './_common'; +import {PLUGIN_REPO_PERMISSIONS} from '@aragon/osx-commons-sdk'; +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +/** + * Upgrades the plugin repo to the latest implementation. + * This script CAN be called if the contract does not require reinitialization. + * It MUST NOY be called if the contract requires reinitialization, because this + * would leave the proxy unreinitialized. + * @param {HardhatRuntimeEnvironment} hre + */ +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployer, pluginRepo, latestPluginRepoImplementation} = + await fetchData(hre); + + // Check if deployer has the permission to upgrade the plugin repo + if ( + await pluginRepo.isGranted( + pluginRepo.address, + deployer.address, + PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, + [] + ) + ) { + await pluginRepo.upgradeTo(latestPluginRepoImplementation.address); + } else { + throw Error( + `The new version cannot be published because the deployer ('${deployer.address}') + is lacking the ${PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID} permission.` + ); + } +}; +export default func; +func.tags = ['UpgradeRepo']; +func.skip = skipUpgrade; diff --git a/packages/contracts/deploy/30_upgrade_repo/31b_upgrade_and_reinitialize_repo.ts b/packages/contracts/deploy/30_upgrade_repo/31b_upgrade_and_reinitialize_repo.ts new file mode 100644 index 00000000..640e755a --- /dev/null +++ b/packages/contracts/deploy/30_upgrade_repo/31b_upgrade_and_reinitialize_repo.ts @@ -0,0 +1,58 @@ +import {fetchData, skipUpgrade} from './_common'; +import {PLUGIN_REPO_PERMISSIONS} from '@aragon/osx-commons-sdk'; +import {BytesLike} from 'ethers'; +import {DeployFunction} from 'hardhat-deploy/types'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; + +/** + * Upgrades the plugin repo to the latest implementation and reinitializes the proxy. + * This script MUST be called if the contract requires reinitialization -- otherwise + * the proxy is left unreinitialized. + * @param {HardhatRuntimeEnvironment} hre + */ +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const {deployer, pluginRepo, latestPluginRepoImplementation, current} = + await fetchData(hre); + + // Define the `_initData` arguments + const initData: BytesLike[] = []; + + // Encode the call to `function initializeFrom(uint8[3] calldata _previousProtocolVersion, bytes calldata _initData)` with `initData`. + const initializeFromCalldata = + latestPluginRepoImplementation.interface.encodeFunctionData( + // Re-initialization will happen through a call to `function initializeFrom(uint8[3] calldata _previousProtocolVersion, bytes calldata _initData)` + // that Aragon will add to the `PluginRepo` contract once it's required. + 'initializeFrom', + [current, initData] + ); + + // Check if deployer has the permission to upgrade the plugin repo + if ( + await pluginRepo.isGranted( + pluginRepo.address, + deployer.address, + PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID, + [] + ) + ) { + // Use `upgradeToAndCall` to reinitialize the new `PluginRepo` implementation after the update. + if (initializeFromCalldata.length > 0) { + await pluginRepo.upgradeToAndCall( + latestPluginRepoImplementation.address, + initializeFromCalldata + ); + } else { + throw Error( + `Initialization data is missing for 'upgradeToAndCall'. Stopping repo upgrade and reinitialization...` + ); + } + } else { + throw Error( + `The new version cannot be published because the deployer ('${deployer.address}') + is lacking the ${PLUGIN_REPO_PERMISSIONS.UPGRADE_REPO_PERMISSION_ID} permission.` + ); + } +}; +export default func; +func.tags = ['UpgradeAndReinitializeRepo']; +func.skip = skipUpgrade; diff --git a/packages/contracts/deploy/30_upgrade_repo/_common.ts b/packages/contracts/deploy/30_upgrade_repo/_common.ts new file mode 100644 index 00000000..f0b1da8b --- /dev/null +++ b/packages/contracts/deploy/30_upgrade_repo/_common.ts @@ -0,0 +1,106 @@ +import {findPluginRepo, getProductionNetworkName} from '../../utils/helpers'; +import { + getLatestNetworkDeployment, + getNetworkNameByAlias, +} from '@aragon/osx-commons-configs'; +import {UnsupportedNetworkError} from '@aragon/osx-commons-sdk'; +import {PluginRepo, PluginRepo__factory} from '@aragon/osx-ethers'; +import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; +import {HardhatRuntimeEnvironment} from 'hardhat/types'; +import path from 'path'; + +export type SemVer = [number, number, number]; + +type FetchedData = { + deployer: SignerWithAddress; + pluginRepo: PluginRepo; + latestPluginRepoImplementation: PluginRepo; + ensDomain: string; + current: SemVer; + latest: SemVer; +}; + +export async function fetchData( + hre: HardhatRuntimeEnvironment +): Promise { + const [deployer] = await hre.ethers.getSigners(); + const productionNetworkName: string = getProductionNetworkName(hre); + const network = getNetworkNameByAlias(productionNetworkName); + if (network === null) { + throw new UnsupportedNetworkError(productionNetworkName); + } + const networkDeployments = getLatestNetworkDeployment(network); + if (networkDeployments === null) { + throw `Deployments are not available on network ${network}.`; + } + + // Get PluginRepo + const {pluginRepo, ensDomain} = await findPluginRepo(hre); + if (pluginRepo === null) { + throw `PluginRepo '${ensDomain}' does not exist yet.`; + } + + console.log( + `Upgrading plugin repo '${ensDomain}' (${pluginRepo.address})...` + ); + + // Get the latest `PluginRepo` implementation as the upgrade target + const latestPluginRepoImplementation = PluginRepo__factory.connect( + networkDeployments.PluginRepoBase.address, + deployer + ); + + // Get the current OSX protocol version from the current plugin repo implementation + let current: SemVer; + try { + current = await pluginRepo.protocolVersion(); + } catch { + current = [1, 0, 0]; + } + + // Get the OSX protocol version from the latest plugin repo implementation + const latest: SemVer = await latestPluginRepoImplementation.protocolVersion(); + + console.log( + `Upgrading from current protocol version v${current[0]}.${current[1]}.${current[2]} to the latest version v${latest[0]}.${latest[1]}.${latest[2]}.` + ); + + return { + deployer, + pluginRepo, + latestPluginRepoImplementation, + ensDomain, + current, + latest, + }; +} + +/** + * Skips the plugin repo upgrade if the implementation is already up-to-date. + * @param {HardhatRuntimeEnvironment} hre + */ +export const skipUpgrade = async (hre: HardhatRuntimeEnvironment) => { + console.log(`\n🏗️ ${path.basename(__filename)}:`); + + const {ensDomain, pluginRepo, current, latest: target} = await fetchData(hre); + + // Throw an error if attempting to upgrade to an earlier version + if ( + current[0] > target[0] || + current[1] > target[1] || + current[2] > target[2] + ) { + throw `The plugin repo, currently at 'v${current[0]}.${current[1]}.${current[2]}' cannot be upgraded to the earlier version v${target[0]}.${target[1]}.${target[2]}.`; + } + + // Skip if versions are equal + if (JSON.stringify(current) == JSON.stringify(target)) { + console.log( + `PluginRepo '${ensDomain}' (${pluginRepo.address}) has already been upgraded to + the current protocol version v${target[0]}.${target[1]}.${target[2]}. Skipping upgrade...` + ); + return true; + } + + return false; +}; diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index 3608e253..da103f21 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -1,7 +1,6 @@ import { - NetworkConfigs, - NetworkConfig, - networks, + addRpcUrlToNetwork, + networks as osxCommonsConfigNetworks, SupportedNetworks, } from '@aragon/osx-commons-configs'; import '@nomicfoundation/hardhat-chai-matchers'; @@ -18,14 +17,18 @@ import { HardhatNetworkAccountsUserConfig, HardhatRuntimeEnvironment, } from 'hardhat/types'; +import type {NetworkUserConfig} from 'hardhat/types'; import {resolve} from 'path'; import 'solidity-coverage'; const dotenvConfigPath: string = process.env.DOTENV_CONFIG_PATH || '../../.env'; dotenvConfig({path: resolve(__dirname, dotenvConfigPath), override: true}); -if (!process.env.INFURA_API_KEY) { - throw new Error('INFURA_API_KEY in .env not set'); +// check alchemy Api key existence +if (process.env.ALCHEMY_API_KEY) { + addRpcUrlToNetwork(process.env.ALCHEMY_API_KEY); +} else { + throw new Error('ALCHEMY_API_KEY in .env not set'); } // Fetch the accounts specified in the .env file @@ -67,15 +70,10 @@ function getHardhatNetworkAccountsConfig( return accountsConfig; } -type HardhatNetworksExtension = NetworkConfig & { - accounts?: string[]; -}; - // Add the accounts specified in the `.env` file to the networks from osx-commons-configs -const osxCommonsConfigNetworks: NetworkConfigs = - networks; +const networks: {[index: string]: NetworkUserConfig} = osxCommonsConfigNetworks; for (const network of Object.keys(networks) as SupportedNetworks[]) { - osxCommonsConfigNetworks[network].accounts = specifiedAccounts(); + networks[network].accounts = specifiedAccounts(); } // Extend HardhatRuntimeEnvironment @@ -110,21 +108,17 @@ const config: HardhatUserConfig = { Object.keys(namedAccounts).length ), }, - ...osxCommonsConfigNetworks, + ...networks, }, defaultNetwork: 'hardhat', etherscan: { apiKey: { mainnet: process.env.ETHERSCAN_API_KEY || '', - goerli: process.env.ETHERSCAN_API_KEY || '', sepolia: process.env.ETHERSCAN_API_KEY || '', polygon: process.env.POLYGONSCAN_API_KEY || '', - polygonMumbai: process.env.POLYGONSCAN_API_KEY || '', base: process.env.BASESCAN_API_KEY || '', - baseGoerli: process.env.BASESCAN_API_KEY || '', arbitrumOne: process.env.ARBISCAN_API_KEY || '', - arbitrumGoerli: process.env.ARBISCAN_API_KEY || '', }, customChains: [ { @@ -143,14 +137,6 @@ const config: HardhatUserConfig = { browserURL: 'https://basescan.org', }, }, - { - network: 'baseGoerli', - chainId: 84531, - urls: { - apiURL: 'https://api-goerli.basescan.org/api', - browserURL: 'https://goerli.basescan.org', - }, - }, ], }, diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 4587efee..4c2c5cbf 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -14,20 +14,19 @@ "clean": "rimraf ./artifacts ./cache ./coverage ./typechain ./types ./coverage.json && yarn typechain" }, "dependencies": { - "@aragon/osx-commons-contracts": "1.4.0-alpha.3", - "@openzeppelin/contracts": "^4.9.5", - "@openzeppelin/contracts-upgradeable": "^4.9.5" + "@aragon/osx-commons-contracts": "1.4.0-alpha.5", + "@openzeppelin/contracts": "^4.9.6", + "@openzeppelin/contracts-upgradeable": "^4.9.6" }, "devDependencies": { - "@aragon/osx-commons-configs": "0.1.0", + "@aragon/osx-commons-configs": "0.4.0", "@aragon/osx-ethers": "1.4.0-alpha.0", - "@aragon/osx-commons-sdk": "0.0.1-alpha.5", - "@aragon/osx-artifacts": "1.3.1", - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/providers": "^5.7.2", + "@aragon/osx-commons-sdk": "0.0.1-alpha.11", + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/providers": "5.7.2", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-network-helpers": "^1.0.8", "@nomicfoundation/hardhat-toolbox": "^2.0.2", @@ -42,7 +41,7 @@ "chai": "^4.3.7", "cross-env": "^7.0.3", "dotenv": "^16.3.1", - "ethers": "^5.7.2", + "ethers": "5.7.2", "hardhat": "^2.13.1", "hardhat-deploy": "^0.11.26", "hardhat-gas-reporter": "^1.0.9", diff --git a/packages/contracts/plugin-settings.ts b/packages/contracts/plugin-settings.ts index f19ee5bf..9679dd52 100644 --- a/packages/contracts/plugin-settings.ts +++ b/packages/contracts/plugin-settings.ts @@ -2,16 +2,35 @@ import buildMetadata from './src/build-metadata.json'; import releaseMetadata from './src/release-metadata.json'; import {VersionTag} from '@aragon/osx-commons-sdk'; -export const PLUGIN_CONTRACT_NAME = 'MyPlugin'; // This must match the filename `packages/contracts/src/MyPlugin.sol` and the contract name `MyPlugin` within. -export const PLUGIN_SETUP_CONTRACT_NAME = 'MyPluginSetup'; // This must match the filename `packages/contracts/src/MyPluginSetup.sol` and the contract name `MyPluginSetup` within. -export const PLUGIN_REPO_ENS_SUBDOMAIN_NAME = 'my'; // This will result in the ENS domain name 'my.plugin.dao.eth' +export function generateRandomName(length: number): string { + const allowedCharacters = 'abcdefghijklmnopqrstuvwxyz-0123456789'; + let result = ''; + for (let i = 0; i < length; i++) { + result += allowedCharacters.charAt( + Math.floor(Math.random() * allowedCharacters.length) + ); + } + return result; +} +// Specify your plugin implementation and plugin setup contract name. +export const PLUGIN_CONTRACT_NAME = 'MyPlugin'; // See `packages/contracts/src/MyPlugin.sol`. +export const PLUGIN_SETUP_CONTRACT_NAME = 'MyPluginSetup'; // See `packages/contracts/src/MyPluginSetup.sol`. + +// Pick an ENS name for your plugin. E.g., 'my-cool-plugin'. +// For more details, visit https://devs.aragon.org/docs/osx/how-it-works/framework/ens-names. +export const PLUGIN_REPO_ENS_SUBDOMAIN_NAME = generateRandomName(8); + +// Specify the version of your plugin that you are currently working on. The first version is v1.1. +// For more details, visit https://devs.aragon.org/docs/osx/how-it-works/framework/plugin-management/plugin-repo. export const VERSION: VersionTag = { release: 1, // Increment this number ONLY if breaking/incompatible changes were made. Updates between releases are NOT possible. build: 1, // Increment this number if non-breaking/compatible changes were made. Updates to newer builds are possible. }; -/* DO NOT CHANGE UNLESS YOU KNOW WHAT YOU ARE DOING */ +// The metadata associated with the plugin version you are currently working on. +// For more details, visit https://devs.aragon.org/docs/osx/how-to-guides/plugin-development/publication/metadata. +// Don't change this unless you know what you are doing. export const METADATA = { build: buildMetadata, release: releaseMetadata, diff --git a/packages/contracts/test/10_unit-testing/12_plugin-setup.ts b/packages/contracts/test/10_unit-testing/12_plugin-setup.ts index 381580b2..5cf9f7d4 100644 --- a/packages/contracts/test/10_unit-testing/12_plugin-setup.ts +++ b/packages/contracts/test/10_unit-testing/12_plugin-setup.ts @@ -9,7 +9,6 @@ import { } from '../../typechain'; import {STORE_PERMISSION_ID, defaultInitData} from './11_plugin'; import { - ADDRESS, Operation, PERMISSION_MANAGER_FLAGS, getNamedTypesFromMetadata, @@ -111,7 +110,7 @@ describe(PLUGIN_SETUP_CONTRACT_NAME, function () { const {pluginSetup, daoMock, prepareUninstallationInputs} = await loadFixture(fixture); - const dummyAddr = ADDRESS.ZERO; + const dummyAddr = ethers.constants.AddressZero; const permissions = await pluginSetup.callStatic.prepareUninstallation( daoMock.address, diff --git a/packages/contracts/test/20_integration-testing/21_deployment.ts b/packages/contracts/test/20_integration-testing/21_deployment.ts index 1bdcfb7f..4f159d6e 100644 --- a/packages/contracts/test/20_integration-testing/21_deployment.ts +++ b/packages/contracts/test/20_integration-testing/21_deployment.ts @@ -9,7 +9,6 @@ import { PERMISSION_MANAGER_FLAGS, PLUGIN_REPO_PERMISSIONS, UnsupportedNetworkError, - toHex, uploadToIPFS, } from '@aragon/osx-commons-sdk'; import { @@ -80,7 +79,9 @@ describe(`Deployment on network '${productionNetworkName}'`, function () { JSON.stringify(METADATA.build, null, 2) )}`; - expect(results.buildMetadata).to.equal(toHex(buildMetadataURI)); + expect(results.buildMetadata).to.equal( + ethers.utils.hexlify(ethers.utils.toUtf8Bytes(buildMetadataURI)) + ); }); }); }); diff --git a/packages/contracts/test/20_integration-testing/test-helpers.ts b/packages/contracts/test/20_integration-testing/test-helpers.ts index a8712834..5e2dbea3 100644 --- a/packages/contracts/test/20_integration-testing/test-helpers.ts +++ b/packages/contracts/test/20_integration-testing/test-helpers.ts @@ -1,5 +1,4 @@ import {DAOMock, IPlugin} from '../../typechain'; -import {hashHelpers} from '../../utils/helpers'; import { DAO_PERMISSIONS, PLUGIN_SETUP_PROCESSOR_PERMISSIONS, @@ -14,6 +13,7 @@ import { import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; import {ContractTransaction} from 'ethers'; +import {ethers} from 'hardhat'; export async function installPLugin( signer: SignerWithAddress, @@ -33,8 +33,8 @@ export async function installPLugin( }); const preparedEvent = - await findEvent( - prepareTx, + findEvent( + await prepareTx.wait(), psp.interface.getEvent('InstallationPrepared').name ); @@ -53,12 +53,17 @@ export async function installPLugin( pluginSetupRef: pluginSetupRef, plugin: plugin, permissions: preparedPermissions, - helpersHash: hashHelpers(preparedEvent.args.preparedSetupData.helpers), + helpersHash: ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ['address[]'], + [preparedEvent.args.preparedSetupData.helpers] + ) + ), }); const appliedEvent = - await findEvent( - applyTx, + findEvent( + await applyTx.wait(), psp.interface.getEvent('InstallationApplied').name ); @@ -92,7 +97,7 @@ export async function uninstallPLugin( const preparedEvent = await findEvent( - prepareTx, + await prepareTx.wait(), psp.interface.getEvent('UninstallationPrepared').name ); @@ -113,8 +118,8 @@ export async function uninstallPLugin( }); const appliedEvent = - await findEvent( - applyTx, + findEvent( + await applyTx.wait(), psp.interface.getEvent('UninstallationApplied').name ); @@ -150,8 +155,8 @@ export async function updatePlugin( }, }); const preparedEvent = - await findEvent( - prepareTx, + findEvent( + await prepareTx.wait(), psp.interface.getEvent('UpdatePrepared').name ); @@ -170,13 +175,17 @@ export async function updatePlugin( pluginSetupRef: pluginSetupRefUpdate, initData: preparedEvent.args.initData, permissions: preparedPermissions, - helpersHash: hashHelpers(preparedEvent.args.preparedSetupData.helpers), + helpersHash: ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ['address[]'], + [preparedEvent.args.preparedSetupData.helpers] + ) + ), }); - const appliedEvent = - await findEvent( - applyTx, - psp.interface.getEvent('UpdateApplied').name - ); + const appliedEvent = findEvent( + await applyTx.wait(), + psp.interface.getEvent('UpdateApplied').name + ); return {prepareTx, applyTx, preparedEvent, appliedEvent}; } diff --git a/packages/contracts/utils/helpers.ts b/packages/contracts/utils/helpers.ts index c76f6992..45611ac5 100644 --- a/packages/contracts/utils/helpers.ts +++ b/packages/contracts/utils/helpers.ts @@ -4,11 +4,7 @@ import { getLatestNetworkDeployment, getNetworkNameByAlias, } from '@aragon/osx-commons-configs'; -import { - UnsupportedNetworkError, - VersionTag, - findEvent, -} from '@aragon/osx-commons-sdk'; +import {UnsupportedNetworkError, findEvent} from '@aragon/osx-commons-sdk'; import { ENSSubdomainRegistrar__factory, ENS__factory, @@ -17,8 +13,7 @@ import { PluginRepoEvents, PluginRepo__factory, } from '@aragon/osx-ethers'; -import {ContractTransaction} from 'ethers'; -import {LogDescription, defaultAbiCoder, keccak256} from 'ethers/lib/utils'; +import {ContractTransaction, utils} from 'ethers'; import {ethers} from 'hardhat'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; @@ -108,7 +103,7 @@ export async function findPluginRepo( } export type EventWithBlockNumber = { - event: LogDescription; + event: utils.LogDescription; blockNumber: number; }; @@ -132,12 +127,8 @@ export async function getPastVersionCreatedEvents( }); } -export function hashHelpers(helpers: string[]) { - return keccak256(defaultAbiCoder.encode(['address[]'], [helpers])); -} - export type LatestVersion = { - versionTag: VersionTag; + versionTag: PluginRepo.VersionStruct; pluginSetupContract: string; releaseMetadata: string; buildMetadata: string; @@ -166,12 +157,11 @@ export async function createVersion( await tx.wait(); - const versionCreatedEvent = - await findEvent( - tx, - pluginRepo.interface.events['VersionCreated(uint8,uint16,address,bytes)'] - .name - ); + const versionCreatedEvent = findEvent( + await tx.wait(), + pluginRepo.interface.events['VersionCreated(uint8,uint16,address,bytes)'] + .name + ); // Check if versionCreatedEvent is not undefined if (versionCreatedEvent) { diff --git a/packages/contracts/yarn.lock b/packages/contracts/yarn.lock index 43944771..26598cfa 100644 --- a/packages/contracts/yarn.lock +++ b/packages/contracts/yarn.lock @@ -2,52 +2,34 @@ # yarn lockfile v1 -"@aragon/osx-artifacts@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@aragon/osx-artifacts/-/osx-artifacts-1.3.1.tgz#68fa04844086a92d74351df2e9392ade3c8696dc" - integrity sha512-u6IFP8fQZIS65Ks5Sl1DKlw8Qp9s5I7DSn9n/odQohWnN65A17HwHaCPTEcXl2AL3r71rFawldQ8i5/2yU3UGA== - -"@aragon/osx-commons-configs@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@aragon/osx-commons-configs/-/osx-commons-configs-0.1.0.tgz#21bbc5a964eb144e30033a44cc352d35c62982f9" - integrity sha512-qTs/loihwqALBGmhZngORb+p7pjuQJY5UEd8TLNiEW/BGHEpAJPp4GeQu7GSnigRGEKWpPD5W96kfEsaPtLkuQ== +"@aragon/osx-commons-configs@0.4.0", "@aragon/osx-commons-configs@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@aragon/osx-commons-configs/-/osx-commons-configs-0.4.0.tgz#5b6ae025de1ccf7f9a135bfbcb0aa822c774acf9" + integrity sha512-/2wIQCbv/spMRdOjRXK0RrXG1TK5aMcbD73RvMgMwQwSrKcA1dCntUuSxmTm2W8eEtOzs8E1VPjqZk0cXL4SSQ== dependencies: tslib "^2.6.2" -"@aragon/osx-commons-contracts@1.4.0-alpha.3": - version "1.4.0-alpha.3" - resolved "https://registry.yarnpkg.com/@aragon/osx-commons-contracts/-/osx-commons-contracts-1.4.0-alpha.3.tgz#a199720e225ea1da07303d8609948bb4a926508b" - integrity sha512-9ygB2QhroeMetRQJUNvvVKAdOxN3Yhxx+yqz1F5Euf4U3VlPtU9Ick9hlDrwTPuWd5ITufmWEiDAo5zDy1A99A== +"@aragon/osx-commons-contracts@1.4.0-alpha.5": + version "1.4.0-alpha.5" + resolved "https://registry.yarnpkg.com/@aragon/osx-commons-contracts/-/osx-commons-contracts-1.4.0-alpha.5.tgz#37a28085677c21216628ba0a05f5fe09489eb71c" + integrity sha512-F2JWWxmUNmiJsaXcTDyd6F2GUIgnc313vvWTp/cSmSVkccT2pfMleWqxIi4LIodX3ueFUYfE02rLj8Gjp1jljA== dependencies: - "@openzeppelin/contracts" "4.9.5" - "@openzeppelin/contracts-upgradeable" "4.9.5" + "@openzeppelin/contracts" "4.9.6" + "@openzeppelin/contracts-upgradeable" "4.9.6" -"@aragon/osx-commons-sdk@0.0.1-alpha.5": - version "0.0.1-alpha.5" - resolved "https://registry.yarnpkg.com/@aragon/osx-commons-sdk/-/osx-commons-sdk-0.0.1-alpha.5.tgz#9808e7c6a441af6459f96016abe07812706d97bf" - integrity sha512-GyErC61lMckZyG17BZPgPWMkY3phZGdzZHMP17mUyE6vFhth9at5HKhNBi7bWB0eNkcM9RrQksIWHjmSHbW3ug== +"@aragon/osx-commons-sdk@0.0.1-alpha.11": + version "0.0.1-alpha.11" + resolved "https://registry.yarnpkg.com/@aragon/osx-commons-sdk/-/osx-commons-sdk-0.0.1-alpha.11.tgz#1e3e39aac3351b6649921a5e373a5146b86b2c92" + integrity sha512-/FgTLnS73QY0JxZYQlHwpd2ZuMPkPKdIlci9T4jgH9E4Eyyxh6GX7fJK+HekCcf6oMS5tTZ/Cb3sVyyzoO95iw== dependencies: - "@aragon/osx-ethers" "^1.3.0-rc0.4" - "@aragon/osx-ethers-v1.0.0" "npm:@aragon/osx-ethers@1.2.1" - "@aragon/sdk-ipfs" "^1.1.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/contracts" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/providers" "^5.7.2" - "@ethersproject/wallet" "^5.7.0" - graphql "^16.5.0" - graphql-request "^4.3.0" + "@aragon/osx-commons-configs" "^0.4.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/providers" "5.7.2" ipfs-http-client "^51.0.0" - yup "^1.2.0" - -"@aragon/osx-ethers-v1.0.0@npm:@aragon/osx-ethers@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@aragon/osx-ethers/-/osx-ethers-1.2.1.tgz#a442048137153ed5a3ca4eff3f3927b45a5134b5" - integrity sha512-3Fscq8C9elIktiI6OT7fR5iaAvim+ghU6IUvZF3P/phvWm9roNp/GXAROhA/Vx41NQxeqmfXokgFo6KOWt4drA== - dependencies: - ethers "^5.6.2" "@aragon/osx-ethers@1.4.0-alpha.0": version "1.4.0-alpha.0" @@ -56,23 +38,6 @@ dependencies: ethers "^5.6.2" -"@aragon/osx-ethers@^1.3.0-rc0.4": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@aragon/osx-ethers/-/osx-ethers-1.3.1.tgz#d72decea14cc5c11c55ad6654e97b3380429c1c9" - integrity sha512-6APDAasHrIVmJ0SxUSmWCxusVe46OF3eGZGp8MVD3j4BDJjJ+FIrrjN9ePkTpPja3X8GL6PD00l1WIzW2GZQMQ== - dependencies: - ethers "^5.6.2" - -"@aragon/sdk-ipfs@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@aragon/sdk-ipfs/-/sdk-ipfs-1.1.0.tgz#178ee5ce840ce40b44ba0345dd5068e1b5608f9d" - integrity sha512-2uAh/QPcmaita4AfHYV93lESzAhrmGEZ6CL7pvOH86HTkU6j7LnePvD1ly+x0hxRznTb+zgVgSPPKUn0ArPycw== - dependencies: - "@web-std/fetch" "^4.1.0" - "@web-std/file" "^3.0.2" - "@web-std/form-data" "^3.0.2" - isomorphic-unfetch "^3.1.0" - "@aws-crypto/sha256-js@1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz#02acd1a1fda92896fc5a28ec7c6e164644ea32fc" @@ -858,15 +823,15 @@ table "^6.8.0" undici "^5.14.0" -"@openzeppelin/contracts-upgradeable@4.9.5", "@openzeppelin/contracts-upgradeable@^4.9.5": - version "4.9.5" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.5.tgz#572b5da102fc9be1d73f34968e0ca56765969812" - integrity sha512-f7L1//4sLlflAN7fVzJLoRedrf5Na3Oal5PZfIq55NFcVZ90EpV1q5xOvL4lFvg3MNICSDr2hH0JUBxwlxcoPg== +"@openzeppelin/contracts-upgradeable@4.9.6", "@openzeppelin/contracts-upgradeable@^4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.6.tgz#38b21708a719da647de4bb0e4802ee235a0d24df" + integrity sha512-m4iHazOsOCv1DgM7eD7GupTJ+NFVujRZt1wzddDPSVGpWdKq1SKkla5htKG7+IS4d2XOCtzkUNwRZ7Vq5aEUMA== -"@openzeppelin/contracts@4.9.5", "@openzeppelin/contracts@^4.9.5": - version "4.9.5" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.5.tgz#1eed23d4844c861a1835b5d33507c1017fa98de8" - integrity sha512-ZK+W5mVhRppff9BE6YdR8CC52C8zAvsVAiWhEtQ5+oNxFE6h1WdeWo+FJSF8KKvtxxVYZ7MTP/5KoVpAU3aSWg== +"@openzeppelin/contracts@4.9.6", "@openzeppelin/contracts@^4.9.6": + version "4.9.6" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.6.tgz#2a880a24eb19b4f8b25adc2a5095f2aa27f39677" + integrity sha512-xSmezSupL+y9VkHZJGDoCBpmnB2ogM13ccaYDWqJTfS3dbuHkgjuwDFUmaFauBCboQMGB/S5UqUl2y54X99BmA== "@openzeppelin/defender-base-client@^1.46.0": version "1.54.1" @@ -1266,66 +1231,6 @@ dependencies: "@types/node" "*" -"@web-std/blob@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@web-std/blob/-/blob-3.0.5.tgz#391e652dd3cc370dbb32c828368a3022b4d55c9c" - integrity sha512-Lm03qr0eT3PoLBuhkvFBLf0EFkAsNz/G/AYCzpOdi483aFaVX86b4iQs0OHhzHJfN5C15q17UtDbyABjlzM96A== - dependencies: - "@web-std/stream" "1.0.0" - web-encoding "1.1.5" - -"@web-std/fetch@^4.1.0": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@web-std/fetch/-/fetch-4.2.1.tgz#692c5545787081217fce3c024708fa8979c21f9c" - integrity sha512-M6sgHDgKegcjuVsq8J6jb/4XvhPGui8uwp3EIoADGXUnBl9vKzKLk9H9iFzrPJ6fSV6zZzFWXPyziBJp9hxzBA== - dependencies: - "@web-std/blob" "^3.0.3" - "@web-std/file" "^3.0.2" - "@web-std/form-data" "^3.0.2" - "@web-std/stream" "^1.0.1" - "@web3-storage/multipart-parser" "^1.0.0" - abort-controller "^3.0.0" - data-uri-to-buffer "^3.0.1" - mrmime "^1.0.0" - -"@web-std/file@^3.0.2": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@web-std/file/-/file-3.0.3.tgz#a29b9164d34155a126d1ab2af5e5867e83c8b098" - integrity sha512-X7YYyvEERBbaDfJeC9lBKC5Q5lIEWYCP1SNftJNwNH/VbFhdHm+3neKOQP+kWEYJmosbDFq+NEUG7+XIvet/Jw== - dependencies: - "@web-std/blob" "^3.0.3" - -"@web-std/form-data@^3.0.2": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@web-std/form-data/-/form-data-3.1.0.tgz#573b40f6296e8bdba31f1bbf2db398f104ef4831" - integrity sha512-WkOrB8rnc2hEK2iVhDl9TFiPMptmxJA1HaIzSdc2/qk3XS4Ny4cCt6/V36U3XmoYKz0Md2YyK2uOZecoZWPAcA== - dependencies: - web-encoding "1.1.5" - -"@web-std/stream@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@web-std/stream/-/stream-1.0.0.tgz#01066f40f536e4329d9b696dc29872f3a14b93c1" - integrity sha512-jyIbdVl+0ZJyKGTV0Ohb9E6UnxP+t7ZzX4Do3AHjZKxUXKMs9EmqnBDQgHF7bEw0EzbQygOjtt/7gvtmi//iCQ== - dependencies: - web-streams-polyfill "^3.1.1" - -"@web-std/stream@^1.0.1": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@web-std/stream/-/stream-1.0.3.tgz#a1df4d4612990d3607f77ad17d0338c7960bbe2e" - integrity sha512-5MIngxWyq4rQiGoDAC2WhjLuDraW8+ff2LD2et4NRY933K3gL8CHlUXrh8ZZ3dC9A9Xaub8c9sl5exOJE58D9Q== - dependencies: - web-streams-polyfill "^3.1.1" - -"@web3-storage/multipart-parser@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@web3-storage/multipart-parser/-/multipart-parser-1.0.0.tgz#6b69dc2a32a5b207ba43e556c25cc136a56659c4" - integrity sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw== - -"@zxing/text-encoding@0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" - integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA== - abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -2092,13 +1997,6 @@ cross-env@^7.0.3: dependencies: cross-spawn "^7.0.1" -cross-fetch@^3.1.5: - version "3.1.8" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" - integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== - dependencies: - node-fetch "^2.6.12" - cross-spawn@^7.0.0, cross-spawn@^7.0.1: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2113,11 +2011,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== -data-uri-to-buffer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" - integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== - death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" @@ -2507,7 +2400,7 @@ ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.4: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.6.2, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: +ethers@5.7.2, ethers@^5.6.2, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -2572,11 +2465,6 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -extract-files@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a" - integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ== - fast-base64-decode@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418" @@ -2685,15 +2573,6 @@ form-data@^2.2.0: combined-stream "^1.0.6" mime-types "^2.1.12" -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -2961,20 +2840,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -graphql-request@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-4.3.0.tgz#b934e08fcae764aa2cdc697d3c821f046cb5dbf2" - integrity sha512-2v6hQViJvSsifK606AliqiNiijb1uwWp6Re7o0RTyH+uRTv/u7Uqm2g4Fjq/LgZIzARB38RZEvVBFOQOVdlBow== - dependencies: - cross-fetch "^3.1.5" - extract-files "^9.0.0" - form-data "^3.0.0" - -graphql@^16.5.0: - version "16.8.1" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.1.tgz#1930a965bef1170603702acdb68aedd3f3cf6f07" - integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== - handlebars@^4.0.1: version "4.7.8" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" @@ -3396,14 +3261,6 @@ ipfs-utils@^8.1.2, ipfs-utils@^8.1.4: react-native-fetch-api "^2.0.0" stream-to-it "^0.2.2" -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" @@ -3479,13 +3336,6 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -3556,7 +3406,7 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== @@ -3600,7 +3450,7 @@ iso-url@^1.1.5: resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-1.2.1.tgz#db96a49d8d9a64a1c889fc07cc525d093afb1811" integrity sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng== -isomorphic-unfetch@^3.0.0, isomorphic-unfetch@^3.1.0: +isomorphic-unfetch@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== @@ -4062,11 +3912,6 @@ module-error@^1.0.1, module-error@^1.0.2: resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== -mrmime@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" - integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -4152,7 +3997,7 @@ node-emoji@^1.10.0: dependencies: lodash "^4.17.21" -node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.12: +node-fetch@^2.6.0, node-fetch@^2.6.1: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -4410,11 +4255,6 @@ proper-lockfile@^4.1.1: retry "^0.12.0" signal-exit "^3.0.2" -property-expr@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" - integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== - protobufjs@^6.10.2: version "6.11.4" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" @@ -5152,11 +4992,6 @@ timeout-abort-controller@^1.1.1: abort-controller "^3.0.0" retimer "^2.0.0" -tiny-case@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" - integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== - tmp-promise@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" @@ -5190,11 +5025,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -toposort@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" - integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -5281,11 +5111,6 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== -type-fest@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== - typechain@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.3.2.tgz#1090dd8d9c57b6ef2aed3640a516bdbf01b00d73" @@ -5439,17 +5264,6 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.3: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" @@ -5465,20 +5279,6 @@ varint@^6.0.0: resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0" integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg== -web-encoding@1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" - integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA== - dependencies: - util "^0.12.3" - optionalDependencies: - "@zxing/text-encoding" "0.9.0" - -web-streams-polyfill@^3.1.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b" - integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ== - web3-utils@^1.3.6: version "1.10.3" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.3.tgz#f1db99c82549c7d9f8348f04ffe4e0188b449714" @@ -5517,7 +5317,7 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: +which-typed-array@^1.1.11, which-typed-array@^1.1.13: version "1.1.13" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== @@ -5656,16 +5456,6 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -yup@^1.2.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.3.tgz#d2f6020ad1679754c5f8178a29243d5447dead04" - integrity sha512-v8QwZSsHH2K3/G9WSkp6mZKO+hugKT1EmnMqLNUcfu51HU9MDyhlETT/JgtzprnrnQHPWsjc6MUDMBp/l9fNnw== - dependencies: - property-expr "^2.0.5" - tiny-case "^1.0.3" - toposort "^2.0.2" - type-fest "^2.19.0" - zksync-web3@^0.14.3: version "0.14.4" resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.14.4.tgz#0b70a7e1a9d45cc57c0971736079185746d46b1f" diff --git a/packages/subgraph/manifest/data/mumbai.json b/packages/subgraph/manifest/data/arbitrum.json similarity index 60% rename from packages/subgraph/manifest/data/mumbai.json rename to packages/subgraph/manifest/data/arbitrum.json index 9b1a7847..7a2941a6 100644 --- a/packages/subgraph/manifest/data/mumbai.json +++ b/packages/subgraph/manifest/data/arbitrum.json @@ -1,12 +1,15 @@ { "info": "# Do not edit subgraph.yaml,this is a generated file. \n# Instead, edit subgraph.placeholder.yaml and run: yarn manifest", - "network": "mumbai", + "network": "arbitrum-one", + "PluginRepo": { + "address": null + }, "dataSources": { "PluginSetupProcessors": [ { "name": "PluginSetupProcessor", - "address": "0x9227b311C5cecB416707F1C8B7Ca1b52649AabEc", - "startBlock": 33514164 + "address": "0x308a1DC5020c4B5d992F5543a7236c465997fecB", + "startBlock": 145462184 } ] } diff --git a/packages/subgraph/manifest/data/goerli.json b/packages/subgraph/manifest/data/baseMainnet.json similarity index 61% rename from packages/subgraph/manifest/data/goerli.json rename to packages/subgraph/manifest/data/baseMainnet.json index 5f82e606..1b9bd0fa 100644 --- a/packages/subgraph/manifest/data/goerli.json +++ b/packages/subgraph/manifest/data/baseMainnet.json @@ -1,12 +1,15 @@ { "info": "# Do not edit subgraph.yaml,this is a generated file. \n# Instead, edit subgraph.placeholder.yaml and run: yarn manifest", - "network": "goerli", + "network": "base", + "PluginRepo": { + "address": null + }, "dataSources": { "PluginSetupProcessors": [ { "name": "PluginSetupProcessor", - "address": "0xE8B5d8D66a02CD1b9Bd32a4064D7ABa45F51305e", - "startBlock": 8548226 + "address": "0x91a851E9Ed7F2c6d41b15F76e4a88f5A37067cC9", + "startBlock": 2094737 } ] } diff --git a/packages/subgraph/manifest/data/localhost.json b/packages/subgraph/manifest/data/localhost.json index fc78a36a..8f071725 100644 --- a/packages/subgraph/manifest/data/localhost.json +++ b/packages/subgraph/manifest/data/localhost.json @@ -1,6 +1,9 @@ { "info": "# Do not edit subgraph.yaml,this is a generated file. \n# Instead, edit subgraph.placeholder.yaml and run: yarn manifest", - "network": "rinkeby", + "network": "sepolia", + "PluginRepo": { + "address": null + }, "dataSources": { "PluginSetupProcessors": [ { diff --git a/packages/subgraph/manifest/data/mainnet.json b/packages/subgraph/manifest/data/mainnet.json index b7969f87..8a26fa85 100644 --- a/packages/subgraph/manifest/data/mainnet.json +++ b/packages/subgraph/manifest/data/mainnet.json @@ -1,6 +1,9 @@ { "info": "# Do not edit subgraph.yaml,this is a generated file. \n# Instead, edit subgraph.placeholder.yaml and run: yarn manifest", "network": "mainnet", + "PluginRepo": { + "address": null + }, "dataSources": { "PluginSetupProcessors": [ { diff --git a/packages/subgraph/manifest/data/polygon.json b/packages/subgraph/manifest/data/polygon.json index 7675c9ba..58c7d050 100644 --- a/packages/subgraph/manifest/data/polygon.json +++ b/packages/subgraph/manifest/data/polygon.json @@ -1,6 +1,9 @@ { "info": "# Do not edit subgraph.yaml,this is a generated file. \n# Instead, edit subgraph.placeholder.yaml and run: yarn manifest", "network": "matic", + "PluginRepo": { + "address": null + }, "dataSources": { "PluginSetupProcessors": [ { diff --git a/packages/subgraph/manifest/data/sepolia.json b/packages/subgraph/manifest/data/sepolia.json index 18a9af1e..78b95633 100644 --- a/packages/subgraph/manifest/data/sepolia.json +++ b/packages/subgraph/manifest/data/sepolia.json @@ -1,6 +1,9 @@ { "info": "# Do not edit subgraph.yaml,this is a generated file. \n# Instead, edit subgraph.placeholder.yaml and run: yarn manifest", "network": "sepolia", + "PluginRepo": { + "address": null + }, "dataSources": { "PluginSetupProcessors": [ { diff --git a/packages/subgraph/manifest/subgraph.placeholder.yaml b/packages/subgraph/manifest/subgraph.placeholder.yaml index 2de5289f..e8922a64 100644 --- a/packages/subgraph/manifest/subgraph.placeholder.yaml +++ b/packages/subgraph/manifest/subgraph.placeholder.yaml @@ -1,7 +1,7 @@ {{info}} specVersion: 0.0.2 description: A template for Plugin subgraphs -repository: https://github.com/aragon/osx-plugin-subgraph +repository: https://github.com/aragon/osx-plugin-template-hardhat schema: file: ./schema.graphql dataSources: diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index 6fd0d40e..b27653bc 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -17,12 +17,12 @@ }, "devDependencies": { "@aragon/osx-ethers": "1.4.0-alpha.0", - "@aragon/osx-commons-configs": "0.2.0", + "@aragon/osx-commons-configs": "0.4.0", "@graphprotocol/graph-cli": "^0.51.0", "@graphprotocol/graph-ts": "^0.31.0", "cross-env": "^7.0.3", "dotenv": "^16.3.1", - "matchstick-as": "^0.5.2", + "matchstick-as": "^0.6.0", "mustache": "^4.2.0", "ts-morph": "^17.0.1", "ts-node": "^10.9.1", diff --git a/packages/subgraph/scripts/deploy-subgraph.sh b/packages/subgraph/scripts/deploy-subgraph.sh index fd15a08c..961758bd 100755 --- a/packages/subgraph/scripts/deploy-subgraph.sh +++ b/packages/subgraph/scripts/deploy-subgraph.sh @@ -26,7 +26,7 @@ echo '> Building subgraph' if [ "$SUBGRAPH_NETWORK_NAME" == 'localhost' ] then - SUBGRAPH_NETWORK_NAME='goerli' + SUBGRAPH_NETWORK_NAME='sepolia' fi # Prepare subgraph name @@ -38,6 +38,17 @@ echo '' echo '> Deploying subgraph: '$FULLNAME echo '> Subgraph version: '$SUBGRAPH_VERSION +# check if the repo address is null or zero address +FILE=manifest/data/$SUBGRAPH_NETWORK_NAME'.json' + +address=$(jq -r '.PluginRepo.address' "$FILE") + +if [ "$address" = "null" ] || [ "$address" = "0x0000000000000000000000000000000000000000" ]; + then + echo "Repo address is not set properly, exiting..." + exit -1 +fi + # Deploy subgraph if [ "$LOCAL" ] then diff --git a/packages/subgraph/scripts/import-plugin-repo.ts b/packages/subgraph/scripts/import-plugin-repo.ts index 8f9d655c..b24590fe 100644 --- a/packages/subgraph/scripts/import-plugin-repo.ts +++ b/packages/subgraph/scripts/import-plugin-repo.ts @@ -1,29 +1,45 @@ +import {SupportedNetworks} from '@aragon/osx-commons-configs'; import dotenv from 'dotenv'; import fs from 'fs'; import path from 'path'; +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; + // Specify the path to the .env file at the root const rootDir = path.join(__dirname, '../../../'); // Adjust the path as necessary dotenv.config({path: path.join(rootDir, '.env')}); +// path to the networks manifests +const manifestsPath = path.join(__dirname, '../manifest/data'); -// Extract Repo address from the production-network-deployments.json -function extractAndWriteAddressToTS(jsonPath: string): void { - // Read the production-network-deployments.json file - const aragonDeploymentsInfo = JSON.parse(fs.readFileSync(jsonPath, 'utf8')); - +function extractAndWriteAddressToTS(): void { // Get the network from environment variables const network = process.env.SUBGRAPH_NETWORK_NAME; - // Check if the network is defined in aragonDeploymentsInfo - if (!network || !aragonDeploymentsInfo[network]) { - throw new Error( - `Network '${network}' not found in production-network-deployments.json` + // Check if the network is provided and supported + if ( + !network || + !Object.values(SupportedNetworks).includes(network as SupportedNetworks) + ) { + throw new Error(`Network '${network}' invalid or not Supported.`); + } + + // get the plugin address from the network manifest + const networkManifestPath = path.join(manifestsPath, `${network}.json`); + let networkRepoAddress = JSON.parse( + fs.readFileSync(networkManifestPath, 'utf8') + ).PluginRepo.address; + + // check if address is null and throw warning and continue with zero address + if (!networkRepoAddress) { + console.warn( + '\x1b[33m%s\x1b[0m', + `WARNING: Plugin address for network '${network}' is null. Using zero address.` ); + networkRepoAddress = ZERO_ADDRESS; } - // Start the Map creation code with the specific network address const tsContent: string[] = [ - `export const PLUGIN_REPO_ADDRESS = '${aragonDeploymentsInfo[network].address}';`, + `export const PLUGIN_REPO_ADDRESS = '${networkRepoAddress}';`, ]; const outputDir = path.join(__dirname, '../imported'); @@ -42,8 +58,4 @@ function extractAndWriteAddressToTS(jsonPath: string): void { ); } -const aragonDeploymentsInfoPath = path.join( - rootDir, - 'production-network-deployments.json' -); -extractAndWriteAddressToTS(aragonDeploymentsInfoPath); +extractAndWriteAddressToTS(); diff --git a/packages/subgraph/yarn.lock b/packages/subgraph/yarn.lock index e209c607..d97d0e2c 100644 --- a/packages/subgraph/yarn.lock +++ b/packages/subgraph/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@aragon/osx-commons-configs@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@aragon/osx-commons-configs/-/osx-commons-configs-0.2.0.tgz#32f83596f4a2e9e48aef61cf560c1c5b4d32a049" - integrity sha512-wCFtgmuGCzs8L5mCxVCYQ6uEu69IrofS7q2w7E1Fjk7/nWuSmRUpgmif3ki9BQq1qpOvDu2P+u3UNLnIz8J82g== +"@aragon/osx-commons-configs@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@aragon/osx-commons-configs/-/osx-commons-configs-0.4.0.tgz#5b6ae025de1ccf7f9a135bfbcb0aa822c774acf9" + integrity sha512-/2wIQCbv/spMRdOjRXK0RrXG1TK5aMcbD73RvMgMwQwSrKcA1dCntUuSxmTm2W8eEtOzs8E1VPjqZk0cXL4SSQ== dependencies: tslib "^2.6.2" @@ -2702,10 +2702,10 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -matchstick-as@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/matchstick-as/-/matchstick-as-0.5.2.tgz#6a6dde02d1d939c32458bd67bac688891a07a34c" - integrity sha512-fb1OVphDKEvJY06Ue02Eh1CNncuW95vp6b8tNAP7UIqplICSLoU/zgN6U7ge7R0upsoO78C7CRi4EyK/7Jxz7g== +matchstick-as@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/matchstick-as/-/matchstick-as-0.6.0.tgz#c65296b1f51b1014d605c52067d9b5321ea630e8" + integrity sha512-E36fWsC1AbCkBFt05VsDDRoFvGSdcZg6oZJrtIe/YDBbuFh8SKbR5FcoqDhNWqSN+F7bN/iS2u8Md0SM+4pUpw== dependencies: wabt "1.0.24"