From 20e6cc9313c7be25abbba183bb6a8b79d8c04727 Mon Sep 17 00:00:00 2001 From: Alain Nicolas Date: Fri, 17 Nov 2023 17:00:53 +0100 Subject: [PATCH] chore: Check the contracts are upgradeable --- .github/workflows/smart-contracts.yml | 39 ++++++++++++++- contracts/.env.example | 41 --------------- contracts/README.md | 5 +- contracts/env/.env.arbitrum | 14 ++++++ contracts/env/.env.arbitrum-goerli | 14 ++++++ contracts/env/.env.linea | 15 ++++++ contracts/env/.env.linea-goerli | 16 ++++++ contracts/hardhat.config.ts | 27 +++++----- contracts/package.json | 11 ++-- .../script/deploy/deployIncorrectModule.ts | 22 -------- .../script/deploy/deployMsgSenderModule.ts | 22 -------- contracts/script/deploy/postDeployment.ts | 17 +++++-- contracts/script/recreateNetworkFile.ts | 42 +++++++++++++--- .../script/upgrade/checkImplementations.ts | 45 +++++++++++++++++ .../script/upgrade/checkUpgradeability.ts | 33 ++++++------ contracts/script/upgrade/checkUpgradeable.ts | 50 ------------------- .../script/upgrade/forceUpgradeEverything.ts | 4 +- contracts/script/upgrade/upgradeEverything.ts | 4 +- 18 files changed, 232 insertions(+), 189 deletions(-) delete mode 100644 contracts/.env.example create mode 100644 contracts/env/.env.arbitrum create mode 100644 contracts/env/.env.arbitrum-goerli create mode 100644 contracts/env/.env.linea create mode 100644 contracts/env/.env.linea-goerli delete mode 100644 contracts/script/deploy/deployIncorrectModule.ts delete mode 100644 contracts/script/deploy/deployMsgSenderModule.ts create mode 100644 contracts/script/upgrade/checkImplementations.ts delete mode 100644 contracts/script/upgrade/checkUpgradeable.ts diff --git a/.github/workflows/smart-contracts.yml b/.github/workflows/smart-contracts.yml index c3ab00f1..b3210032 100644 --- a/.github/workflows/smart-contracts.yml +++ b/.github/workflows/smart-contracts.yml @@ -157,8 +157,43 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - - name: Check contracts upgradeability - run: pnpm run check:upgradeability:ci + - name: Check contracts implementations + run: pnpm run check:implementations + + - name: Create Linea testnet env file + run: | + cp ./env/.env.linea-goerli .env + echo INFURA_KEY=${{ secrets.INFURA_KEY }} >> .env + + - name: Check contracts upgradeability on Linea testnet + run: pnpm run check:upgradeability linea-goerli + + - name: Create Linea mainnet env file + run: | + rm .env + cp ./env/.env.linea .env + echo INFURA_KEY=${{ secrets.INFURA_KEY }} >> .env + + - name: Check contracts upgradeability on Linea mainnet + run: pnpm run check:upgradeability linea + + - name: Create Arbitrum testnet env file + run: | + rm .env + cp ./env/.env.arbitrum-goerli .env + echo INFURA_KEY=${{ secrets.INFURA_KEY }} >> .env + + - name: Check contracts upgradeability on Arbitrum testnet + run: pnpm run check:upgradeability arbitrum-goerli + + - name: Create Arbitrum mainnet env file + run: | + rm .env + cp ./env/.env.arbitrum .env + echo INFURA_KEY=${{ secrets.INFURA_KEY }} >> .env + + - name: Check contracts upgradeability on Arbitrum mainnet + run: pnpm run check:upgradeability arbitrum - name: Add upgradeability summary run: | diff --git a/contracts/.env.example b/contracts/.env.example deleted file mode 100644 index 69316fe5..00000000 --- a/contracts/.env.example +++ /dev/null @@ -1,41 +0,0 @@ -# Config -INFURA_KEY= -PRIVATE_KEY=0000000000000000000000000000000000000000000000000000000000000001 -ETHERSCAN_API_KEY= -SCROLL_API_KEY= - -# LINEA TESTNET -ROUTER_ADDRESS=0x736c78b2f2cBf4F921E8551b2acB6A5Edc9177D5 -PORTAL_REGISTRY_ADDRESS=0x506f88a5Ca8D5F001f2909b029738A40042e42a6 -SCHEMA_REGISTRY_ADDRESS=0xB2c4Da1f8F08A0CA25862509E5431289BE2b598B -MODULE_REGISTRY_ADDRESS=0x1a20b2CFA134686306436D2c9f778D7eC6c43A43 -ATTESTATION_REGISTRY_ADDRESS=0xC765F28096F6121C2F2b82D35A4346280164428b -ATTESTATION_READER_ADDRESS=0x65c8294C7aF0f0bDDe51eF92AF850613bb629fc6 -EAS_REGISTRY_ADDRESS=0xaEF4103A04090071165F78D45D83A0C0782c2B2a - -# LINEA MAINNET -#ROUTER_ADDRESS=0x4d3a380A03f3a18A5dC44b01119839D8674a552E -#PORTAL_REGISTRY_ADDRESS=0xd5d61e4ECDf6d46A63BfdC262af92544DFc19083 -#SCHEMA_REGISTRY_ADDRESS=0x0f95dCec4c7a93F2637eb13b655F2223ea036B59 -#MODULE_REGISTRY_ADDRESS=0xf851513A732996F22542226341748f3C9978438f -#ATTESTATION_REGISTRY_ADDRESS=0x3de3893aa4Cdea029e84e75223a152FD08315138 -#ATTESTATION_READER_ADDRESS=0x40871e247CF6b8fd8794c9c56bB5c2b8a4FA3B6c -#EAS_REGISTRY_ADDRESS=0xaEF4103A04090071165F78D45D83A0C0782c2B2a - -# ARBITRUM TESTNET - -#ROUTER_ADDRESS = 0x746390cB11913d8F93BDF8a974cFEC724039B3Cc -#ATTESTATION_REGISTRY_ADDRESS = 0xCD839595FdA5A8111d5E03D42d9D9af60ee67B66 -#MODULE_REGISTRY_ADDRESS = 0x58EE79284bE65b217Db408A0991314f9Ae84348A -#PORTAL_REGISTRY_ADDRESS = 0x7d6a914C1e33C141CB4a5e0095c1075E5649aFB2 -#SCHEMA_REGISTRY_ADDRESS = 0x129043e80e0B4C7da61a622df0912c31D3414AA7 -#ATTESTATION_READER_ADDRESS = 0x055E7d488eCACf9f1B0B42659c331C037505D4a1 - -# ARBITRUM MAINNET - -#ROUTER_ADDRESS = 0xa77196867bB03D04786EF636cDdD82f37A1248a9 -#ATTESTATION_REGISTRY_ADDRESS = 0x335E9719e8eFE2a19A92E07BC4836160fC31cd7C -#MODULE_REGISTRY_ADDRESS = 0x3acF4daAB6cbc01546Dd4a96c9665B398d48A4ba -#PORTAL_REGISTRY_ADDRESS = 0x4042D0A54f997EE3a1b0F51e4813654199BFd8bD -#SCHEMA_REGISTRY_ADDRESS = 0xE96072F46EA0e42e538762dDc0aFa4ED8AE6Ec27 -#ATTESTATION_READER_ADDRESS = 0x324C060A26444c3fB9B93e03d31e8cfF4b1715C1 diff --git a/contracts/README.md b/contracts/README.md index 7affe825..a50485b5 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -205,10 +205,9 @@ the last upgrade or the first deployment. ## Start upgrading 1. Check that your `.env` file contains the address of all the proxies -2. Upgrade only the implementations that changed since the last upgrade via the `pnpm run upgrade:all NETWORK_NAME` - command +2. Upgrade only the implementations that changed since the last upgrade via the `pnpm run upgrade NETWORK_NAME` command 3. _Optional_: Upgrade all the implementations by forcing their re-deployment via the - `pnpm run upgrade:all:force NETWORK_NAME` command + `pnpm run upgrade:force NETWORK_NAME` command :warning: Note: Forcing the redeployment of all the implementations is more expensive! diff --git a/contracts/env/.env.arbitrum b/contracts/env/.env.arbitrum new file mode 100644 index 00000000..60ea0c86 --- /dev/null +++ b/contracts/env/.env.arbitrum @@ -0,0 +1,14 @@ +# Config +INFURA_KEY= + +PRIVATE_KEY_ARBITRUM_MAINNET=0000000000000000000000000000000000000000000000000000000000000001 + +ARBISCAN_API_KEY= + +# Contracts +ROUTER_ADDRESS=0xa77196867bB03D04786EF636cDdD82f37A1248a9 +ATTESTATION_REGISTRY_ADDRESS=0x335E9719e8eFE2a19A92E07BC4836160fC31cd7C +MODULE_REGISTRY_ADDRESS=0x3acF4daAB6cbc01546Dd4a96c9665B398d48A4ba +PORTAL_REGISTRY_ADDRESS=0x4042D0A54f997EE3a1b0F51e4813654199BFd8bD +SCHEMA_REGISTRY_ADDRESS=0xE96072F46EA0e42e538762dDc0aFa4ED8AE6Ec27 +ATTESTATION_READER_ADDRESS=0x324C060A26444c3fB9B93e03d31e8cfF4b1715C1 diff --git a/contracts/env/.env.arbitrum-goerli b/contracts/env/.env.arbitrum-goerli new file mode 100644 index 00000000..7dde799f --- /dev/null +++ b/contracts/env/.env.arbitrum-goerli @@ -0,0 +1,14 @@ +# Config +INFURA_KEY= + +PRIVATE_KEY_ARBITRUM_TESTNET=0000000000000000000000000000000000000000000000000000000000000001 + +ARBISCAN_API_KEY= + +# Contracts +ROUTER_ADDRESS=0x746390cB11913d8F93BDF8a974cFEC724039B3Cc +ATTESTATION_REGISTRY_ADDRESS=0xCD839595FdA5A8111d5E03D42d9D9af60ee67B66 +MODULE_REGISTRY_ADDRESS=0x58EE79284bE65b217Db408A0991314f9Ae84348A +PORTAL_REGISTRY_ADDRESS=0x7d6a914C1e33C141CB4a5e0095c1075E5649aFB2 +SCHEMA_REGISTRY_ADDRESS=0x129043e80e0B4C7da61a622df0912c31D3414AA7 +ATTESTATION_READER_ADDRESS=0x055E7d488eCACf9f1B0B42659c331C037505D4a1 diff --git a/contracts/env/.env.linea b/contracts/env/.env.linea new file mode 100644 index 00000000..5168455d --- /dev/null +++ b/contracts/env/.env.linea @@ -0,0 +1,15 @@ +# Config +INFURA_KEY= + +PRIVATE_KEY_LINEA_MAINNET=0000000000000000000000000000000000000000000000000000000000000001 + +LINEASCAN_API_KEY= + +# Contracts +ROUTER_ADDRESS=0x4d3a380A03f3a18A5dC44b01119839D8674a552E +PORTAL_REGISTRY_ADDRESS=0xd5d61e4ECDf6d46A63BfdC262af92544DFc19083 +SCHEMA_REGISTRY_ADDRESS=0x0f95dCec4c7a93F2637eb13b655F2223ea036B59 +MODULE_REGISTRY_ADDRESS=0xf851513A732996F22542226341748f3C9978438f +ATTESTATION_REGISTRY_ADDRESS=0x3de3893aa4Cdea029e84e75223a152FD08315138 +ATTESTATION_READER_ADDRESS=0x40871e247CF6b8fd8794c9c56bB5c2b8a4FA3B6c +EAS_REGISTRY_ADDRESS=0xaEF4103A04090071165F78D45D83A0C0782c2B2a diff --git a/contracts/env/.env.linea-goerli b/contracts/env/.env.linea-goerli new file mode 100644 index 00000000..3dfc49b2 --- /dev/null +++ b/contracts/env/.env.linea-goerli @@ -0,0 +1,16 @@ +# Config +INFURA_KEY= + +PRIVATE_KEY_LINEA_TESTNET=0000000000000000000000000000000000000000000000000000000000000001 + +LINEASCAN_API_KEY= + +# Contracts +ROUTER_ADDRESS=0x736c78b2f2cBf4F921E8551b2acB6A5Edc9177D5 +PORTAL_REGISTRY_ADDRESS=0x506f88a5Ca8D5F001f2909b029738A40042e42a6 +SCHEMA_REGISTRY_ADDRESS=0xB2c4Da1f8F08A0CA25862509E5431289BE2b598B +MODULE_REGISTRY_ADDRESS=0x1a20b2CFA134686306436D2c9f778D7eC6c43A43 +ATTESTATION_REGISTRY_ADDRESS=0xC765F28096F6121C2F2b82D35A4346280164428b +ATTESTATION_READER_ADDRESS=0x65c8294C7aF0f0bDDe51eF92AF850613bb629fc6 +EAS_REGISTRY_ADDRESS=0xaEF4103A04090071165F78D45D83A0C0782c2B2a + diff --git a/contracts/hardhat.config.ts b/contracts/hardhat.config.ts index 8afb44c2..eab3660c 100644 --- a/contracts/hardhat.config.ts +++ b/contracts/hardhat.config.ts @@ -22,27 +22,25 @@ const config: HardhatUserConfig = { hardhat: {}, "arbitrum-goerli": { url: "https://goerli-rollup.arbitrum.io/rpc", - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + accounts: + process.env.PRIVATE_KEY_ARBITRUM_TESTNET !== undefined ? [process.env.PRIVATE_KEY_ARBITRUM_TESTNET] : [], }, arbitrum: { url: "https://arb1.arbitrum.io/rpc", - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + accounts: + process.env.PRIVATE_KEY_ARBITRUM_MAINNET !== undefined ? [process.env.PRIVATE_KEY_ARBITRUM_MAINNET] : [], }, "linea-goerli": { url: `https://linea-goerli.infura.io/v3/${process.env.INFURA_KEY ?? ""}`, - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + accounts: process.env.PRIVATE_KEY_LINEA_TESTNET !== undefined ? [process.env.PRIVATE_KEY_LINEA_TESTNET] : [], }, linea: { url: `https://linea-mainnet.infura.io/v3/${process.env.INFURA_KEY ?? ""}`, - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], - }, - sepolia: { - url: `https://sepolia.infura.io/v3/${process.env.INFURA_KEY ?? ""}`, - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + accounts: process.env.PRIVATE_KEY_LINEA_MAINNET !== undefined ? [process.env.PRIVATE_KEY_LINEA_MAINNET] : [], }, "scroll-sepolia": { - url: "https://sepolia-rpc.scroll.io/" || "", - accounts: process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [], + url: "https://sepolia-rpc.scroll.io/", + accounts: process.env.PRIVATE_KEY_SCROLL_TESTNET !== undefined ? [process.env.PRIVATE_KEY_SCROLL_TESTNET] : [], }, }, paths: { @@ -50,11 +48,10 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: { - "arbitrum-goerli": process.env.ETHERSCAN_API_KEY ?? "", - arbitrum: process.env.ETHERSCAN_API_KEY ?? "", - "linea-goerli": process.env.ETHERSCAN_API_KEY ?? "", - linea: process.env.ETHERSCAN_API_KEY ?? "", - sepolia: process.env.ETHERSCAN_API_KEY ?? "", + "arbitrum-goerli": process.env.ARBISCAN_API_KEY ?? "", + arbitrum: process.env.ARBISCAN_API_KEY ?? "", + "linea-goerli": process.env.LINEASCAN_API_KEY ?? "", + linea: process.env.LINEASCAN_API_KEY ?? "", "scroll-sepolia": process.env.SCROLL_API_KEY ?? "", }, customChains: [ diff --git a/contracts/package.json b/contracts/package.json index a42cd6c8..101b71a9 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -19,19 +19,18 @@ ], "scripts": { "build": "forge build", - "check:upgradeability": "npx hardhat run script/upgrade/checkUpgradeability.ts", - "check:upgradeability:ci": "cp .env.example .env && pnpm run check:upgradeability", - "check:upgradeable": "npx hardhat run script/upgrade/checkUpgradeable.ts --network", + "check:implementations": "npx hardhat run script/upgrade/checkImplementations.ts", + "check:upgradeability": "npx hardhat run script/upgrade/checkUpgradeability.ts --network", "clean": "rm -rf lcov.info coverage artifacts cache_hardhat cache out typechain-types", "decode": "npx hardhat run script/decode.ts", - "deploy:all": "npx hardhat run script/deploy/deployEverything.ts --network", + "deploy": "npx hardhat run script/deploy/deployEverything.ts --network", "deploy:post": "npx hardhat run script/deploy/postDeployment.ts --network", "encode": "npx hardhat run script/encode.ts", "lint": "pnpm solhint \"{script,src,test}/**/*.sol\"", "reimport": "npx hardhat run script/recreateNetworkFile.ts --network", "test": "forge test", - "upgrade:all": "npx hardhat run script/upgrade/upgradeEverything.ts --network", - "upgrade:all:force": "npx hardhat run script/upgrade/forceUpgradeEverything.ts --network" + "upgrade": "npx hardhat run script/upgrade/upgradeEverything.ts --network", + "upgrade:force": "npx hardhat run script/upgrade/forceUpgradeEverything.ts --network" }, "devDependencies": { "@nomicfoundation/hardhat-ethers": "^3.0.4", diff --git a/contracts/script/deploy/deployIncorrectModule.ts b/contracts/script/deploy/deployIncorrectModule.ts deleted file mode 100644 index 7f615139..00000000 --- a/contracts/script/deploy/deployIncorrectModule.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ethers, run } from "hardhat"; - -async function main() { - console.log("Deploying IncorrectModule..."); - const IncorrectModule = await ethers.getContractFactory("IncorrectModule"); - const incorrectModule = await IncorrectModule.deploy(); - await incorrectModule.waitForDeployment(); - const incorrectModuleAddress = await incorrectModule.getAddress(); - - await run("verify:verify", { - address: incorrectModuleAddress, - }); - - console.log(`IncorrectModule successfully deployed and verified at ${incorrectModuleAddress}!`); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/script/deploy/deployMsgSenderModule.ts b/contracts/script/deploy/deployMsgSenderModule.ts deleted file mode 100644 index 58010533..00000000 --- a/contracts/script/deploy/deployMsgSenderModule.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ethers, run } from "hardhat"; - -async function main() { - console.log("Deploying MsgSenderModule..."); - const MsgSenderModule = await ethers.getContractFactory("MsgSenderModule"); - const msgSenderModule = await MsgSenderModule.deploy(); - await msgSenderModule.waitForDeployment(); - const msgSenderModuleAddress = await msgSenderModule.getAddress(); - - await run("verify:verify", { - address: msgSenderModuleAddress, - }); - - console.log(`MsgSenderModule successfully deployed and verified at ${msgSenderModuleAddress}!`); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/script/deploy/postDeployment.ts b/contracts/script/deploy/postDeployment.ts index 86a0e918..0c485a9c 100644 --- a/contracts/script/deploy/postDeployment.ts +++ b/contracts/script/deploy/postDeployment.ts @@ -1,13 +1,13 @@ import { ethers } from "hardhat"; import dotenv from "dotenv"; -import { Contract } from "ethers"; +import { SchemaRegistry } from "../../typechain-types"; dotenv.config({ path: "../.env" }); async function main() { const proxyAddress = process.env.SCHEMA_REGISTRY_ADDRESS ?? ""; - console.log("Creating relationship schema using schema registry, with proxy at", proxyAddress); - const schemaRegistry = await ethers.getContractAt("SchemaRegistry", proxyAddress); + console.log(`Creating canonical Schemas using the SchemaRegistry at ${proxyAddress}`); + const schemaRegistry: SchemaRegistry = await ethers.getContractAt("SchemaRegistry", proxyAddress); await createSchema( schemaRegistry, @@ -23,10 +23,17 @@ async function main() { "https://schema.org/Property", "string namedGraph, bytes32 subject, string predicate, bytes32 object", ); + await createSchema( + schemaRegistry, + "Offchain", + "Represents a link to an offchain payload", + "https://schema.org/Property", + "(bytes32 schemaId, string uri)", + ); } async function createSchema( - schemaRegistry: Contract, + schemaRegistry: SchemaRegistry, schemaName: string, schemaDescription: string, schemaContext: string, @@ -34,10 +41,12 @@ async function createSchema( ) { const schemaId = await schemaRegistry.getIdFromSchemaString(schemaString); const schemaExists = await schemaRegistry.isRegistered(schemaId); + if (!schemaExists) { const tx = await schemaRegistry.createSchema(schemaName, schemaDescription, schemaContext, schemaString); await tx.wait(); const schemaCreated = await schemaRegistry.isRegistered(schemaId); + if (schemaCreated) { console.log(`Schema "${schemaName}" successfully created with ID ${schemaId}`); } else { diff --git a/contracts/script/recreateNetworkFile.ts b/contracts/script/recreateNetworkFile.ts index 64109375..d856d1f7 100644 --- a/contracts/script/recreateNetworkFile.ts +++ b/contracts/script/recreateNetworkFile.ts @@ -13,37 +13,67 @@ async function main() { const routerProxyAddress = process.env.ROUTER_ADDRESS ?? ""; const Router = await ethers.getContractFactory("Router"); - await upgrades.forceImport(routerProxyAddress, Router, { kind: "transparent" }); + try { + await upgrades.forceImport(routerProxyAddress, Router, { kind: "transparent" }); + console.log("✅ Router re-imported"); + } catch (e) { + console.log("❌ Router already registered"); + } console.log("Re-importing AttestationRegistry..."); const attestationRegistryProxyAddress = process.env.ATTESTATION_REGISTRY_ADDRESS ?? ""; const AttestationRegistry = await ethers.getContractFactory("AttestationRegistry"); - await upgrades.forceImport(attestationRegistryProxyAddress, AttestationRegistry, { kind: "transparent" }); + try { + await upgrades.forceImport(attestationRegistryProxyAddress, AttestationRegistry, { kind: "transparent" }); + console.log("✅ AttestationRegistry re-imported"); + } catch (e) { + console.log("❌ AttestationRegistry already registered"); + } console.log("Re-importing ModuleRegistry..."); const moduleRegistryProxyAddress = process.env.MODULE_REGISTRY_ADDRESS ?? ""; const ModuleRegistry = await ethers.getContractFactory("ModuleRegistry"); - await upgrades.forceImport(moduleRegistryProxyAddress, ModuleRegistry, { kind: "transparent" }); + try { + await upgrades.forceImport(moduleRegistryProxyAddress, ModuleRegistry, { kind: "transparent" }); + console.log("✅ ModuleRegistry re-imported"); + } catch (e) { + console.log("❌ ModuleRegistry already registered"); + } console.log("Re-importing PortalRegistry..."); const portalRegistryProxyAddress = process.env.PORTAL_REGISTRY_ADDRESS ?? ""; const PortalRegistry = await ethers.getContractFactory("PortalRegistry"); - await upgrades.forceImport(portalRegistryProxyAddress, PortalRegistry, { kind: "transparent" }); + try { + await upgrades.forceImport(portalRegistryProxyAddress, PortalRegistry, { kind: "transparent" }); + console.log("✅ PortalRegistry re-imported"); + } catch (e) { + console.log("❌ PortalRegistry already registered"); + } console.log("Re-importing SchemaRegistry..."); const schemaRegistryProxyAddress = process.env.SCHEMA_REGISTRY_ADDRESS ?? ""; const SchemaRegistry = await ethers.getContractFactory("SchemaRegistry"); - await upgrades.forceImport(schemaRegistryProxyAddress, SchemaRegistry, { kind: "transparent" }); + try { + await upgrades.forceImport(schemaRegistryProxyAddress, SchemaRegistry, { kind: "transparent" }); + console.log("✅ SchemaRegistry re-imported"); + } catch (e) { + console.log("❌ SchemaRegistry already registered"); + } console.log("Re-importing AttestationReader..."); const attestationReaderProxyAddress = process.env.ATTESTATION_READER_ADDRESS ?? ""; const AttestationReader = await ethers.getContractFactory("AttestationReader"); - await upgrades.forceImport(attestationReaderProxyAddress, AttestationReader, { kind: "transparent" }); + try { + await upgrades.forceImport(attestationReaderProxyAddress, AttestationReader, { kind: "transparent" }); + console.log("✅ AttestationReader re-imported"); + } catch (e) { + console.log("❌ AttestationReader already registered"); + } console.log("All contracts are re-imported and the network file is re-created!"); } diff --git a/contracts/script/upgrade/checkImplementations.ts b/contracts/script/upgrade/checkImplementations.ts new file mode 100644 index 00000000..de16c6e1 --- /dev/null +++ b/contracts/script/upgrade/checkImplementations.ts @@ -0,0 +1,45 @@ +import { ethers, upgrades } from "hardhat"; + +/* + * This script aims to statically check if the implementation contracts follow the rules for upgradeability. + * It validates implementation contracts without deploying them. + * OpenZeppelin doc: https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#validate-implementation + * Note: this does not run the check against the already deployed version of the registries. + */ +async function main() { + console.log("Checking contracts implementation for upgradeability..."); + + console.log("Checking AttestationRegistry..."); + const AttestationRegistry = await ethers.getContractFactory("AttestationRegistry"); + await upgrades.validateImplementation(AttestationRegistry); + console.log("AttestationRegistry OK"); + + console.log("Checking ModuleRegistry..."); + const ModuleRegistry = await ethers.getContractFactory("ModuleRegistry"); + await upgrades.validateImplementation(ModuleRegistry); + console.log("ModuleRegistry OK"); + + console.log("Checking PortalRegistry..."); + const PortalRegistry = await ethers.getContractFactory("PortalRegistry"); + await upgrades.validateImplementation(PortalRegistry); + console.log("PortalRegistry OK"); + + console.log("Checking SchemaRegistry..."); + const SchemaRegistry = await ethers.getContractFactory("SchemaRegistry"); + await upgrades.validateImplementation(SchemaRegistry); + console.log("SchemaRegistry OK"); + + console.log("Checking AttestationReader..."); + const AttestationReader = await ethers.getContractFactory("AttestationReader"); + await upgrades.validateImplementation(AttestationReader); + console.log("AttestationReader OK"); + + console.log("All contracts implementations are upgradeable!"); +} + +// We recommend this pattern to be able to use async/await everywhere +// and properly handle errors. +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/contracts/script/upgrade/checkUpgradeability.ts b/contracts/script/upgrade/checkUpgradeability.ts index 127885c2..789e9fd6 100644 --- a/contracts/script/upgrade/checkUpgradeability.ts +++ b/contracts/script/upgrade/checkUpgradeability.ts @@ -1,38 +1,43 @@ import { ethers, upgrades } from "hardhat"; /* - * This script aims to statically check if the registries contracts follow the rules for upgradability. - * It validates implementation contracts without deploying them. - * OpenZeppelin doc: https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#validate-implementation - * Note: this does not run the check against the already deployed version of the registries. + * This script aims to dynamically check if the contracts are upgradeable. + * Validates a new implementation contract without deploying it and without actually upgrading to it. + * OpenZeppelin doc: https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#validate-upgrade + * Note: this does run the check against the already deployed version of the registries. */ async function main() { console.log("Checking contracts for upgradeability..."); console.log("Checking AttestationRegistry..."); + const attestationRegistryProxyAddress = process.env.ATTESTATION_REGISTRY_ADDRESS ?? ""; const AttestationRegistry = await ethers.getContractFactory("AttestationRegistry"); - await upgrades.validateImplementation(AttestationRegistry); - console.log("AttestationRegistry OK"); + + await upgrades.validateUpgrade(attestationRegistryProxyAddress, AttestationRegistry, { kind: "transparent" }); console.log("Checking ModuleRegistry..."); + const moduleRegistryProxyAddress = process.env.MODULE_REGISTRY_ADDRESS ?? ""; const ModuleRegistry = await ethers.getContractFactory("ModuleRegistry"); - await upgrades.validateImplementation(ModuleRegistry); - console.log("ModuleRegistry OK"); + + await upgrades.validateUpgrade(moduleRegistryProxyAddress, ModuleRegistry, { kind: "transparent" }); console.log("Checking PortalRegistry..."); + const portalRegistryProxyAddress = process.env.PORTAL_REGISTRY_ADDRESS ?? ""; const PortalRegistry = await ethers.getContractFactory("PortalRegistry"); - await upgrades.validateImplementation(PortalRegistry); - console.log("PortalRegistry OK"); + + await upgrades.validateUpgrade(portalRegistryProxyAddress, PortalRegistry, { kind: "transparent" }); console.log("Checking SchemaRegistry..."); + const schemaRegistryProxyAddress = process.env.SCHEMA_REGISTRY_ADDRESS ?? ""; const SchemaRegistry = await ethers.getContractFactory("SchemaRegistry"); - await upgrades.validateImplementation(SchemaRegistry); - console.log("SchemaRegistry OK"); + + await upgrades.validateUpgrade(schemaRegistryProxyAddress, SchemaRegistry, { kind: "transparent" }); console.log("Checking AttestationReader..."); + const attestationReaderProxyAddress = process.env.ATTESTATION_READER_ADDRESS ?? ""; const AttestationReader = await ethers.getContractFactory("AttestationReader"); - await upgrades.validateImplementation(AttestationReader); - console.log("AttestationReader OK"); + + await upgrades.validateUpgrade(attestationReaderProxyAddress, AttestationReader, { kind: "transparent" }); console.log("All contracts are upgradeable!"); } diff --git a/contracts/script/upgrade/checkUpgradeable.ts b/contracts/script/upgrade/checkUpgradeable.ts deleted file mode 100644 index ac157ab7..00000000 --- a/contracts/script/upgrade/checkUpgradeable.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { ethers, upgrades } from "hardhat"; - -/* - * This script aims to dynamically check if the registries contracts are upgradeable. - * Validates a new implementation contract without deploying it and without actually upgrading to it. - * OpenZeppelin doc: https://docs.openzeppelin.com/upgrades-plugins/1.x/api-hardhat-upgrades#validate-upgrade - * Note: this does run the check against the already deployed version of the registries. - */ -async function main() { - console.log("Checking contracts for upgradeability..."); - - console.log("Checking AttestationRegistry..."); - const attestationRegistryProxyAddress = process.env.ATTESTATION_REGISTRY_ADDRESS ?? ""; - const AttestationRegistry = await ethers.getContractFactory("AttestationRegistry"); - - await upgrades.validateUpgrade(attestationRegistryProxyAddress, AttestationRegistry, { kind: "transparent" }); - - console.log("Checking ModuleRegistry..."); - const moduleRegistryProxyAddress = process.env.MODULE_REGISTRY_ADDRESS ?? ""; - const ModuleRegistry = await ethers.getContractFactory("ModuleRegistry"); - - await upgrades.validateUpgrade(moduleRegistryProxyAddress, ModuleRegistry, { kind: "transparent" }); - - console.log("Checking PortalRegistry..."); - const portalRegistryProxyAddress = process.env.PORTAL_REGISTRY_ADDRESS ?? ""; - const PortalRegistry = await ethers.getContractFactory("PortalRegistry"); - - await upgrades.validateUpgrade(portalRegistryProxyAddress, PortalRegistry, { kind: "transparent" }); - - console.log("Checking SchemaRegistry..."); - const schemaRegistryProxyAddress = process.env.SCHEMA_REGISTRY_ADDRESS ?? ""; - const SchemaRegistry = await ethers.getContractFactory("SchemaRegistry"); - - await upgrades.validateUpgrade(schemaRegistryProxyAddress, SchemaRegistry, { kind: "transparent" }); - - console.log("Checking AttestationReader..."); - const attestationReaderProxyAddress = process.env.ATTESTATION_READER_ADDRESS ?? ""; - const AttestationReader = await ethers.getContractFactory("AttestationReader"); - - await upgrades.validateUpgrade(attestationReaderProxyAddress, AttestationReader, { kind: "transparent" }); - - console.log("All contracts are upgradeable!"); -} - -// We recommend this pattern to be able to use async/await everywhere -// and properly handle errors. -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/contracts/script/upgrade/forceUpgradeEverything.ts b/contracts/script/upgrade/forceUpgradeEverything.ts index 8ad1aa5e..7bcaf085 100644 --- a/contracts/script/upgrade/forceUpgradeEverything.ts +++ b/contracts/script/upgrade/forceUpgradeEverything.ts @@ -4,7 +4,7 @@ import dotenv from "dotenv"; dotenv.config({ path: "../.env" }); async function main() { - console.log(`START SCRIPT`); + console.log(`Force-upgrading all contracts...`); const routerProxyAddress = process.env.ROUTER_ADDRESS; if (!routerProxyAddress) { @@ -182,7 +182,7 @@ async function main() { console.log(`SchemaRegistry = ${schemaProxyAddress}`); console.log(`AttestationReader = ${attestationReaderProxyAddress}`); - console.log(`END SCRIPT`); + console.log(`All contracts were force-upgraded!`); } // We recommend this pattern to be able to use async/await everywhere diff --git a/contracts/script/upgrade/upgradeEverything.ts b/contracts/script/upgrade/upgradeEverything.ts index 572248e2..ad955222 100644 --- a/contracts/script/upgrade/upgradeEverything.ts +++ b/contracts/script/upgrade/upgradeEverything.ts @@ -4,7 +4,7 @@ import dotenv from "dotenv"; dotenv.config({ path: "../.env" }); async function main() { - console.log(`START SCRIPT`); + console.log(`Upgrading all contracts...`); const routerProxyAddress = process.env.ROUTER_ADDRESS; if (!routerProxyAddress) { @@ -170,7 +170,7 @@ async function main() { console.log(`SchemaRegistry = ${schemaProxyAddress}`); console.log(`AttestationReader = ${attestationReaderProxyAddress}`); - console.log(`END SCRIPT`); + console.log(`All contracts were upgraded!`); } // We recommend this pattern to be able to use async/await everywhere