From afa11fe6a781d98d1ea133a309b0b1dfeca91972 Mon Sep 17 00:00:00 2001 From: Sergey <2901744+evercoinx@users.noreply.github.com.> Date: Fri, 4 Oct 2024 11:04:28 +0200 Subject: [PATCH] Implement task to deploy ValidatorRegistry contract --- Makefile | 62 +++++++++++++++++ hardhat.config.ts | 1 + tasks/deploy-validator-registry.ts | 103 +++++++++++++++++++++++++++++ utils/account.ts | 15 ++++- utils/network.ts | 59 +++++++++++++++++ 5 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 Makefile create mode 100644 tasks/deploy-validator-registry.ts create mode 100644 utils/network.ts diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..6c20b5fe --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ +# Binaries +BIN_HARDHAT := ./node_modules/.bin/hardhat +BIN_ECHIDNA := echidna +BIN_MYTH := myth + +# Configs +CONFIG_ECHIDNA := echidna.config.yaml +CONFIG_SOLC := solc.json + +# Networks +NETWORK_HARDHAT := hardhat +NETWORK_LOCALHOST := localhost +NETWORK_HOLESKY := holesky +NETWORK_ETHEREUM := ethereum + +# Hardhat contract addresses +HARDHAT_MATICX := 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 +HARDHAT_VALIDATOR_REGISTRY := 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 +HARDHAT_STAKE_MANAGER := 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 +HARDHAT_MATIC_TOKEN := 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 +HARDHAT_MATICX := 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 +HARDHAT_MANAGER := 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + +# Localhost contract addresses +LOCALHOST_MATICX := +LOCALHOST_VALIDATOR_REGISTRY := +LOCALHOST_STAKE_MANAGER := +LOCALHOST_MATIC_TOKEN := +LOCALHOST_MATICX := +LOCALHOST_MANAGER := + +# Holesky contract addresses +HOLESKY_MATICX := +HOLESKY_VALIDATOR_REGISTRY := +HOLESKY_STAKE_MANAGER := +HOLESKY_MATIC_TOKEN := +HOLESKY_MATICX := +HOLESKY_MANAGER := + +# Ethereum contract addresses +ETHEREUM_MATICX := +ETHEREUM_VALIDATOR_REGISTRY := +ETHEREUM_STAKE_MANAGER := +ETHEREUM_MATIC_TOKEN := +ETHEREUM_MATICX := +ETHEREUM_MANAGER := + +all: hardhat + +hardhat: deploy-validatorregistry-hardhat + +localhost: deploy-validatorregistry-localhost + +# Deploy the MaticX contract +deploy-validatorregistry-hardhat: + $(BIN_HARDHAT) deploy:validator-registry --network $(NETWORK_HARDHAT) --stake-manager $(HARDHAT_STAKE_MANAGER) --matic-token $(HARDHAT_MATIC_TOKEN) --matic-x $(HARDHAT_MATICX) --manager $(HARDHAT_MANAGER) +deploy-validatorregistry-localhost: + $(BIN_HARDHAT) deploy:validator-registry --network $(NETWORK_LOCALHOST) +deploy-validatorregistry-holesky: + $(BIN_HARDHAT) deploy:validator-registry --network $(NETWORK_HOLESKY) +deploy-validatorregistry-ethereum: + $(BIN_HARDHAT) deploy:validator-registry --network $(NETWORK_ETHEREUM) diff --git a/hardhat.config.ts b/hardhat.config.ts index b7156bf5..b23b21ca 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -15,6 +15,7 @@ import "hardhat-contract-sizer"; import "hardhat-gas-reporter"; import "solidity-coverage"; import { deployDirect, deployProxy, verify } from "./scripts/tasks"; +import "./tasks/deploy-validator-registry"; import { extractEnvironmentVariables } from "./utils/environment"; const envSuffix = process.env.NODE_ENV === "main" ? "" : ".test"; diff --git a/tasks/deploy-validator-registry.ts b/tasks/deploy-validator-registry.ts new file mode 100644 index 00000000..f0a794ef --- /dev/null +++ b/tasks/deploy-validator-registry.ts @@ -0,0 +1,103 @@ +import { TASK_CLEAN, TASK_COMPILE } from "hardhat/builtin-tasks/task-names"; +import { task, types } from "hardhat/config"; +import { getSigner } from "../utils/account"; +import { isLocalNetwork, Network } from "../utils/network"; + +interface TaskParams { + stakeManager: string; + maticToken: string; + maticX: string; + manager: string; +} + +task("deploy:validator-registry") + .setDescription("Deploy the ValidatorRegistry contract") + .addParam( + "stakeManager", + "Address of the StakeManager contract", + undefined, + types.string + ) + .addParam( + "maticToken", + "Address of the MaticToken contract", + undefined, + types.string + ) + .addParam( + "maticX", + "Address of the MaticX contract", + undefined, + types.string + ) + .addParam( + "manager", + "Address of the Manager contract", + undefined, + types.string + ) + .setAction( + async ( + { + stakeManager: stakeManagerAddress, + maticToken: maticTokenAddress, + maticX: maticXAddress, + manager: managerAddress, + }: TaskParams, + { ethers, network, run, upgrades } + ) => { + if (!ethers.utils.isAddress(stakeManagerAddress)) { + throw new Error("Invalid StakeManager address"); + } + if (!ethers.utils.isAddress(maticTokenAddress)) { + throw new Error("Invalid MaticToken address"); + } + if (!ethers.utils.isAddress(maticXAddress)) { + throw new Error("Invalid MaticX address"); + } + if (!ethers.utils.isAddress(managerAddress)) { + throw new Error("Invalid Manager address"); + } + + const networkName = network.name as Network; + console.log(`Network name: ${networkName}`); + if (!isLocalNetwork(networkName)) { + await run(TASK_CLEAN); + } + await run(TASK_COMPILE); + + const deployer = await getSigner( + ethers, + network.provider, + network.config.from + ); + const ValidatorRegistry = await ethers.getContractFactory( + "ValidatorRegistry", + deployer + ); + + const validatorRegistry = await upgrades.deployProxy( + ValidatorRegistry, + [ + stakeManagerAddress, + maticTokenAddress, + maticXAddress, + managerAddress, + ], + { kind: "transparent" } + ); + await validatorRegistry.deployed(); + + console.log( + `ValidatorRegistry Proxy deployed at ${validatorRegistry.address}` + ); + + const implementationAddress = + await upgrades.erc1967.getImplementationAddress( + validatorRegistry.address + ); + console.log( + `ValidatorRegistry Implementation deployed at ${implementationAddress}` + ); + } + ); diff --git a/utils/account.ts b/utils/account.ts index a8f1116b..cc8bd07b 100644 --- a/utils/account.ts +++ b/utils/account.ts @@ -1,4 +1,17 @@ -import { ethers } from "hardhat"; +import { ethers } from "ethers"; +import { ethers as ethersType } from "ethers"; +import { EIP1193Provider } from "hardhat/types"; + +type HardhatEthers = typeof ethersType; + +export async function getSigner( + ethers: HardhatEthers, + ethereum: EIP1193Provider, + address?: string +) { + const provider = new ethers.providers.Web3Provider(ethereum); + return provider.getSigner(address); +} export function generateRandomAddress(): string { const privateKey = `0x${Buffer.from(ethers.utils.randomBytes(32)).toString("hex")}`; diff --git a/utils/network.ts b/utils/network.ts new file mode 100644 index 00000000..6436addf --- /dev/null +++ b/utils/network.ts @@ -0,0 +1,59 @@ +export enum Provider { + Alchemy = "alchemy", + Infura = "infura", +} + +export enum Network { + Hardhat = "hardhat", + Localhost = "localhost", + Holesky = "holesky", + Ethereum = "ethereum", + EthereumAlt = "mainnet", +} + +export function getProviderUrl( + network: Network, + provider: Provider, + apiKey: string +): string { + if (network === Network.Localhost) { + return "http://127.0.0.1:8545"; + } + + const urls: Record> = { + [Network.Holesky]: { + [Provider.Alchemy]: "https://eth-holesky.g.alchemy.com", + [Provider.Infura]: "https://holesky.infura.io", + }, + [Network.Ethereum]: { + [Provider.Alchemy]: "https://eth-mainnet.g.alchemy.com", + [Provider.Infura]: "https://mainnet.infura.io", + }, + [Network.EthereumAlt]: { + [Provider.Alchemy]: "https://eth-mainnet.g.alchemy.com", + [Provider.Infura]: "https://mainnet.infura.io", + }, + }; + + const apiVersions: Record = { + [Provider.Alchemy]: 2, + [Provider.Infura]: 3, + }; + + return ( + provider && + `${urls[network][provider]}/v${apiVersions[provider]}/${apiKey}` + ); +} + +export function isLocalNetwork(network: Network): boolean { + return [Network.Hardhat, Network.Localhost].includes(network); +} + +export function isTestNetwork(network: Network): boolean { + return [Network.Holesky].includes(network); +} + +export function isMainNetwork(network: Network): boolean { + return [Network.Ethereum, Network.EthereumAlt].includes(network); +}