From e59518566ca017c08faaca75fb92cc9bed680e95 Mon Sep 17 00:00:00 2001 From: FabienC Date: Thu, 18 Jun 2026 16:17:59 +0300 Subject: [PATCH] chore(deploy): migrate to Hardhat v3 + hardhat-deploy v2 (rocketh) Replaces the Hardhat v2 + hardhat-deploy v0.14 (ethers v5) deploy toolchain with Hardhat v3 + hardhat-deploy v2 built on rocketh (viem), matching the parallel-parallelizer setup. Foundation: - package.json: "type": "module"; swap hardhat-deploy@0.14 -> hardhat-deploy@^2, hardhat@^3, rocketh + @rocketh/* (0.19.x), viem, @nomicfoundation/hardhat-viem; drop hardhat-foundry/contract-sizer; scripts: verify -> "rocketh-verify etherscan", add "size". - tsconfig.json: ESM (esnext/bundler), @rocketh and @generated aliases. - hardhat.config.ts: v3 plugins array, networks with type:"http", PRIVATE_KEY accounts, solc 0.8.25/cancun. Hardhat sources pinned to contracts/ with tests redirected so Foundry tests under test/ are not compiled by Hardhat. remappings.txt gains contracts/=contracts/. - rocketh.ts: typed config + deploy/read-execute/proxy/viem extensions, setupDeployScripts, re-exports generated artifacts. - commitlint.config.js -> .cjs (CommonJS under ESM). Deploy scripts (sPRL1/sPRL2/sPRL2V2, MainFeeDistributor, SideChainFeeCollector, RewardMerkleDistributor): - rewritten to the deployScript(env) API: env.deploy({account, artifact, args}); network name via env.name; uint args as BigInt. - deploy/utils switched from ethers v5 to viem (isAddress/zeroAddress); removed the obsolete sPRL2V2 recover script and utils/getVerifyConfig. Verification now uses @rocketh/verifier (ETHERSCAN_API_KEY env); .env.example updated. Validated: tsc --noEmit clean, forge build + hardhat compile generate generated/ artifacts, and an end-to-end deploy dry-run of sPRL1 on an in-memory network succeeds. --- .env.example | 5 +- .gitignore | 1 + bun.lockb | Bin 214729 -> 216293 bytes commitlint.config.js => commitlint.config.cjs | 0 deploy/scripts/fees/MainFeeDistributor.ts | 51 ++++---- deploy/scripts/fees/SideChainFeeCollector.ts | 55 ++++----- .../RewardMerkleDistributor.ts | 56 ++++----- deploy/scripts/sprl/sPRL1.ts | 66 +++++----- deploy/scripts/sprl/sPRL2.ts | 113 +++++++++--------- deploy/scripts/sprl/sPRL2V2.ts | 97 +++++++-------- deploy/utils/index.ts | 4 +- deploy/utils/types.ts | 10 +- hardhat.config.ts | 56 ++++----- package.json | 39 ++++-- remappings.txt | 1 + rocketh.ts | 38 ++++++ tsconfig.json | 20 +++- utils/getVerifyConfig.ts | 86 ------------- 18 files changed, 319 insertions(+), 379 deletions(-) rename commitlint.config.js => commitlint.config.cjs (100%) create mode 100644 rocketh.ts delete mode 100644 utils/getVerifyConfig.ts diff --git a/.env.example b/.env.example index 5a52f77..acd0a09 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,4 @@ -MNEMONIC="YOUR_MNEMONIC" PRIVATE_KEY="PRIVATE_KEY" ALCHEMY_API_KEY="ALCHEMY_API_KEY" -MAINNET_ETHERSCAN_API_KEY="MAINNET_ETHERSCAN_API_KEY" -POLYGON_ETHERSCAN_API_KEY="POLYGON_ETHERSCAN_API_KEY" +# Unified Etherscan V2 API key used by `rocketh-verify etherscan` +ETHERSCAN_API_KEY="ETHERSCAN_API_KEY" diff --git a/.gitignore b/.gitignore index 594fdf4..9cf4bc2 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ lcov.info artifacts cache_hardhat deployments +generated diff --git a/bun.lockb b/bun.lockb index 90390e69cea5febeb0892ce53fce983ddad324df..96e8f35eb439b560ed48f0b07e7fe606b190fd0e 100755 GIT binary patch delta 74334 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 delta 75945 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 { - const { getNamedAccounts, deployments } = hre; - - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - assert(deployer, "Missing deployer account"); - - console.log(`Network: ${hre.network.name}`); - console.log(`Deployer: ${deployer}`); - const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${hre.network.name}/config.json`).toString()); - if (!config.isMainChainFeeDistributor) throw new Error("MainFeeDistributor must be deployed on main chain"); +export default deployScript( + async ({ namedAccounts, name, deploy }) => { + const { deployer } = namedAccounts; + assert(deployer, "Missing deployer account"); + console.log(`Network: ${name}\nDeployer: ${deployer}\nDeploying: ${contractName}`); - const accessManager = checkAddressValid(config.accessManager, "access manager"); + const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${name}/config.json`).toString()); + if (!config.isMainChainFeeDistributor) throw new Error("MainFeeDistributor must be deployed on main chain"); - const feeDistributorData = config.feeDistributor; - const bridgeableToken = checkAddressValid(feeDistributorData.bridgeableToken, "bridgeable token"); + const accessManager = checkAddressValid(config.accessManager, "access manager"); - const feeToken = getTokenAddressFromConfig(feeDistributorData.feeToken, config); + const feeDistributorData = config.feeDistributor; + const bridgeableToken = checkAddressValid(feeDistributorData.bridgeableToken, "bridgeable token"); - const contract = await deploy(contractName, { - from: deployer, - args: [accessManager, bridgeableToken, feeToken], - log: true, - skipIfAlreadyDeployed: false, - }); + const feeToken = getTokenAddressFromConfig(feeDistributorData.feeToken, config); - console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); -}; + const contract = await deploy(contractName, { + account: deployer, + artifact: artifacts.MainFeeDistributor, + args: [accessManager, bridgeableToken, feeToken], + }); -deploy.tags = [contractName]; -export default deploy; + console.log(`Deployed ${contractName}, network: ${name}, address: ${contract.address}`); + }, + { + tags: [contractName], + }, +); diff --git a/deploy/scripts/fees/SideChainFeeCollector.ts b/deploy/scripts/fees/SideChainFeeCollector.ts index 71f842b..a33ec06 100644 --- a/deploy/scripts/fees/SideChainFeeCollector.ts +++ b/deploy/scripts/fees/SideChainFeeCollector.ts @@ -1,6 +1,5 @@ import assert from "assert"; - -import { type DeployFunction } from "hardhat-deploy/types"; +import { deployScript, artifacts } from "@rocketh"; import { checkAddressValid, getLzEidReceiver, getTokenAddressFromConfig } from "../../utils"; import { readFileSync } from "fs"; @@ -8,37 +7,33 @@ import { ConfigData } from "../../utils/types"; const contractName = "SideChainFeeCollector"; -const deploy: DeployFunction = async (hre) => { - const { getNamedAccounts, deployments } = hre; - - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - assert(deployer, "Missing deployer account"); - - console.log(`Network: ${hre.network.name}`); - console.log(`Deployer: ${deployer}`); - const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${hre.network.name}/config.json`).toString()); - if (config.isMainChainFeeDistributor) throw new Error("SideChainFeeCollector must be deployed on side chain"); +export default deployScript( + async ({ namedAccounts, name, deploy }) => { + const { deployer } = namedAccounts; + assert(deployer, "Missing deployer account"); + console.log(`Network: ${name}\nDeployer: ${deployer}\nDeploying: ${contractName}`); - const accessManager = checkAddressValid(config.accessManager, "access manager"); + const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${name}/config.json`).toString()); + if (config.isMainChainFeeDistributor) throw new Error("SideChainFeeCollector must be deployed on side chain"); - const feeDistributorData = config.feeDistributor; - const lzEidReceiver = getLzEidReceiver(feeDistributorData.mainChain); - const destinationReceiver = checkAddressValid(feeDistributorData.destinationReceiver, "destination receiver"); - const bridgeableToken = checkAddressValid(feeDistributorData.bridgeableToken, "bridgeable token"); + const accessManager = checkAddressValid(config.accessManager, "access manager"); - const feeToken = getTokenAddressFromConfig(feeDistributorData.feeToken, config); + const feeDistributorData = config.feeDistributor; + const lzEidReceiver = getLzEidReceiver(feeDistributorData.mainChain); + const destinationReceiver = checkAddressValid(feeDistributorData.destinationReceiver, "destination receiver"); + const bridgeableToken = checkAddressValid(feeDistributorData.bridgeableToken, "bridgeable token"); - const contract = await deploy(contractName, { - from: deployer, - args: [accessManager, lzEidReceiver, bridgeableToken, destinationReceiver, feeToken], - log: true, - skipIfAlreadyDeployed: false, - }); + const feeToken = getTokenAddressFromConfig(feeDistributorData.feeToken, config); - console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); -}; + const contract = await deploy(contractName, { + account: deployer, + artifact: artifacts.SideChainFeeCollector, + args: [accessManager, lzEidReceiver, bridgeableToken, destinationReceiver, feeToken], + }); -deploy.tags = [contractName]; -export default deploy; + console.log(`Deployed ${contractName}, network: ${name}, address: ${contract.address}`); + }, + { + tags: [contractName], + }, +); diff --git a/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts b/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts index 79ac598..41295cc 100644 --- a/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts +++ b/deploy/scripts/rewardMerkleDistributor/RewardMerkleDistributor.ts @@ -1,6 +1,5 @@ import assert from "assert"; - -import { type DeployFunction } from "hardhat-deploy/types"; +import { deployScript, artifacts } from "@rocketh"; import { checkAddressValid, getTokenAddressFromConfig, getWalletAddressFromConfig } from "../../utils"; import { readFileSync } from "fs"; @@ -8,39 +7,34 @@ import { ConfigData } from "../../utils/types"; const contractName = "RewardMerkleDistributor"; -const deploy: DeployFunction = async (hre) => { - const { getNamedAccounts, deployments } = hre; - - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - assert(deployer, "Missing deployer account"); - - console.log(`Network: ${hre.network.name}`); - console.log(`Deployer: ${deployer}`); - - const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${hre.network.name}/config.json`).toString()); +export default deployScript( + async ({ namedAccounts, name, deploy }) => { + const { deployer } = namedAccounts; + assert(deployer, "Missing deployer account"); + console.log(`Network: ${name}\nDeployer: ${deployer}\nDeploying: ${contractName}`); - const accessManager = checkAddressValid(config.accessManager, "access manager"); + const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${name}/config.json`).toString()); - const rewardMerkleDistributorData = config.rewardMerkleDistributor; + const accessManager = checkAddressValid(config.accessManager, "access manager"); - const token = getTokenAddressFromConfig(rewardMerkleDistributorData.token, config); + const rewardMerkleDistributorData = config.rewardMerkleDistributor; - const expiredRewardsRecipient = getWalletAddressFromConfig( - rewardMerkleDistributorData.expiredRewardsRecipient, - config, - ); + const token = getTokenAddressFromConfig(rewardMerkleDistributorData.token, config); - const contract = await deploy(contractName, { - from: deployer, - args: [accessManager, token, expiredRewardsRecipient], - log: true, - skipIfAlreadyDeployed: false, - }); + const expiredRewardsRecipient = getWalletAddressFromConfig( + rewardMerkleDistributorData.expiredRewardsRecipient, + config, + ); - console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); -}; + const contract = await deploy(contractName, { + account: deployer, + artifact: artifacts.RewardMerkleDistributor, + args: [accessManager, token, expiredRewardsRecipient], + }); -deploy.tags = [contractName]; -export default deploy; + console.log(`Deployed ${contractName}, network: ${name}, address: ${contract.address}`); + }, + { + tags: [contractName], + }, +); diff --git a/deploy/scripts/sprl/sPRL1.ts b/deploy/scripts/sprl/sPRL1.ts index 3b70243..021d706 100644 --- a/deploy/scripts/sprl/sPRL1.ts +++ b/deploy/scripts/sprl/sPRL1.ts @@ -1,6 +1,5 @@ import assert from "assert"; - -import { type DeployFunction } from "hardhat-deploy/types"; +import { deployScript, artifacts } from "@rocketh"; import { getTokenAddressFromConfig, getWalletAddressFromConfig, isAddressValid } from "../../utils"; import { readFileSync } from "fs"; @@ -8,34 +7,35 @@ import { ConfigData } from "../../utils/types"; const contractName = "sPRL1"; -const deploy: DeployFunction = async (hre) => { - const { getNamedAccounts, deployments } = hre; - - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - assert(deployer, "Missing deployer account"); - - console.log(`Network: ${hre.network.name}`); - console.log(`Deployer: ${deployer}`); - - const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${hre.network.name}/config.json`).toString()); - const accessManager = config.accessManager; - if (!isAddressValid(accessManager)) throw new Error("Invalid access manager address"); - - const sprl1Data = config.sprl1; - const underlying = getTokenAddressFromConfig(sprl1Data.underlying, config); - const feeReceiver = getWalletAddressFromConfig(sprl1Data.feeReceiver, config); - - const contract = await deploy(contractName, { - from: deployer, - args: [underlying, feeReceiver, accessManager, sprl1Data.startPenaltyPercentage, sprl1Data.timeLockDuration], - log: true, - skipIfAlreadyDeployed: false, - }); - - console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); -}; - -deploy.tags = [contractName]; -export default deploy; +export default deployScript( + async ({ namedAccounts, name, deploy }) => { + const { deployer } = namedAccounts; + assert(deployer, "Missing deployer account"); + console.log(`Network: ${name}\nDeployer: ${deployer}\nDeploying: ${contractName}`); + + const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${name}/config.json`).toString()); + const accessManager = config.accessManager; + if (!isAddressValid(accessManager)) throw new Error("Invalid access manager address"); + + const sprl1Data = config.sprl1; + const underlying = getTokenAddressFromConfig(sprl1Data.underlying, config); + const feeReceiver = getWalletAddressFromConfig(sprl1Data.feeReceiver, config); + + const contract = await deploy(contractName, { + account: deployer, + artifact: artifacts.sPRL1, + args: [ + underlying, + feeReceiver, + accessManager, + BigInt(sprl1Data.startPenaltyPercentage), + BigInt(sprl1Data.timeLockDuration), + ], + }); + + console.log(`Deployed ${contractName}, network: ${name}, address: ${contract.address}`); + }, + { + tags: [contractName], + }, +); diff --git a/deploy/scripts/sprl/sPRL2.ts b/deploy/scripts/sprl/sPRL2.ts index 0352088..61cc6d0 100644 --- a/deploy/scripts/sprl/sPRL2.ts +++ b/deploy/scripts/sprl/sPRL2.ts @@ -1,6 +1,5 @@ import assert from "assert"; - -import { type DeployFunction } from "hardhat-deploy/types"; +import { deployScript, artifacts } from "@rocketh"; import { checkAddressValid, getTokenAddressFromConfig, getWalletAddressFromConfig, isAddressValid } from "../../utils"; import { readFileSync } from "fs"; @@ -8,60 +7,56 @@ import { ConfigData } from "../../utils/types"; const contractName = "sPRL2"; -const deploy: DeployFunction = async (hre) => { - const { getNamedAccounts, deployments } = hre; - - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - assert(deployer, "Missing deployer account"); - - console.log(`Network: ${hre.network.name}`); - console.log(`Deployer: ${deployer}`); - - const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${hre.network.name}/config.json`).toString()); - const accessManager = config.accessManager; - if (!isAddressValid(accessManager)) throw new Error("Invalid access manager address"); - - const sprl2Data = config.sprl2; - const prlToken = getTokenAddressFromConfig("prl", config); - const wethToken = getTokenAddressFromConfig("weth", config); - - const permit2 = checkAddressValid(sprl2Data.permit2, "Permit2"); - const feeReceiver = getWalletAddressFromConfig(sprl2Data.feeReceiver, config); - const balancerRouter = checkAddressValid(sprl2Data.balancerV3Router, "Balancer V3 Router"); - const balancerBPT = checkAddressValid(sprl2Data.balancerBPT, "Balancer BPT"); - const auraBoosterLite = checkAddressValid(sprl2Data.auraBoosterLite, "Aura Booster Lite"); - const auraRewardsPool = checkAddressValid(sprl2Data.auraRewardsPool, "Aura Rewards Pool"); - const auraBPT = checkAddressValid(sprl2Data.auraBPT, "Aura BPT"); - const rewardsTokens = sprl2Data.rewardsTokens.map((token) => checkAddressValid(token, "Reward Token")); - - const BPTConfigParams = { - balancerRouter: balancerRouter, - auraBoosterLite: auraBoosterLite, - auraRewardsPool: auraRewardsPool, - balancerBPT: balancerBPT, - prl: prlToken, - weth: wethToken, - rewardTokens: rewardsTokens, - permit2: permit2, - }; - const contract = await deploy(contractName, { - from: deployer, - args: [ - auraBPT, - feeReceiver, - accessManager, - sprl2Data.startPenaltyPercentage, - sprl2Data.timeLockDuration, - BPTConfigParams, - ], - log: true, - skipIfAlreadyDeployed: false, - }); - - console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); -}; - -deploy.tags = [contractName]; -export default deploy; +export default deployScript( + async ({ namedAccounts, name, deploy }) => { + const { deployer } = namedAccounts; + assert(deployer, "Missing deployer account"); + console.log(`Network: ${name}\nDeployer: ${deployer}\nDeploying: ${contractName}`); + + const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${name}/config.json`).toString()); + const accessManager = config.accessManager; + if (!isAddressValid(accessManager)) throw new Error("Invalid access manager address"); + + const sprl2Data = config.sprl2; + const prlToken = getTokenAddressFromConfig("prl", config); + const wethToken = getTokenAddressFromConfig("weth", config); + + const permit2 = checkAddressValid(sprl2Data.permit2, "Permit2"); + const feeReceiver = getWalletAddressFromConfig(sprl2Data.feeReceiver, config); + const balancerRouter = checkAddressValid(sprl2Data.balancerV3Router, "Balancer V3 Router"); + const balancerBPT = checkAddressValid(sprl2Data.balancerBPT, "Balancer BPT"); + const auraBoosterLite = checkAddressValid(sprl2Data.auraBoosterLite, "Aura Booster Lite"); + const auraRewardsPool = checkAddressValid(sprl2Data.auraRewardsPool, "Aura Rewards Pool"); + const auraBPT = checkAddressValid(sprl2Data.auraBPT, "Aura BPT"); + const rewardsTokens = sprl2Data.rewardsTokens.map((token) => checkAddressValid(token, "Reward Token")); + + const BPTConfigParams = { + balancerRouter, + auraBoosterLite, + auraRewardsPool, + balancerBPT, + prl: prlToken, + weth: wethToken, + rewardTokens: rewardsTokens, + permit2, + }; + + const contract = await deploy(contractName, { + account: deployer, + artifact: artifacts.sPRL2, + args: [ + auraBPT, + feeReceiver, + accessManager, + BigInt(sprl2Data.startPenaltyPercentage), + BigInt(sprl2Data.timeLockDuration), + BPTConfigParams, + ], + }); + + console.log(`Deployed ${contractName}, network: ${name}, address: ${contract.address}`); + }, + { + tags: [contractName], + }, +); diff --git a/deploy/scripts/sprl/sPRL2V2.ts b/deploy/scripts/sprl/sPRL2V2.ts index 3353746..85ad348 100644 --- a/deploy/scripts/sprl/sPRL2V2.ts +++ b/deploy/scripts/sprl/sPRL2V2.ts @@ -1,6 +1,5 @@ import assert from "assert"; - -import { type DeployFunction } from "hardhat-deploy/types"; +import { deployScript, artifacts } from "@rocketh"; import { checkAddressValid, getTokenAddressFromConfig, getWalletAddressFromConfig, isAddressValid } from "../../utils"; import { readFileSync } from "fs"; @@ -8,52 +7,48 @@ import { ConfigData } from "../../utils/types"; const contractName = "sPRL2V2"; -const deploy: DeployFunction = async (hre) => { - const { getNamedAccounts, deployments } = hre; - - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - assert(deployer, "Missing deployer account"); - - console.log(`Network: ${hre.network.name}`); - console.log(`Deployer: ${deployer}`); - - const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${hre.network.name}/config.json`).toString()); - const accessManager = config.accessManager; - if (!isAddressValid(accessManager)) throw new Error("Invalid access manager address"); - - const sprl2v2Data = config.sprl2v2; - const prlToken = getTokenAddressFromConfig("prl", config); - const wethToken = getTokenAddressFromConfig("weth", config); - - const permit2 = checkAddressValid(sprl2v2Data.permit2, "Permit2"); - const feeReceiver = getWalletAddressFromConfig(sprl2v2Data.feeReceiver, config); - const balancerRouter = checkAddressValid(sprl2v2Data.balancerV3Router, "Balancer V3 Router"); - const balancerBPT = checkAddressValid(sprl2v2Data.balancerBPT, "Balancer BPT"); - - const BPTConfigParams = { - balancerRouter: balancerRouter, - balancerBPT: balancerBPT, - prl: prlToken, - weth: wethToken, - permit2: permit2, - }; - const contract = await deploy(contractName, { - from: deployer, - args: [ - feeReceiver, - accessManager, - sprl2v2Data.startPenaltyPercentage, - sprl2v2Data.timeLockDuration, - BPTConfigParams, - ], - log: true, - skipIfAlreadyDeployed: false, - }); - - console.log(`Deployed contract: ${contractName}, network: ${hre.network.name}, address: ${contract.address}`); -}; - -deploy.tags = [contractName]; -export default deploy; +export default deployScript( + async ({ namedAccounts, name, deploy }) => { + const { deployer } = namedAccounts; + assert(deployer, "Missing deployer account"); + console.log(`Network: ${name}\nDeployer: ${deployer}\nDeploying: ${contractName}`); + + const config: ConfigData = JSON.parse(readFileSync(`./deploy/config/${name}/config.json`).toString()); + const accessManager = config.accessManager; + if (!isAddressValid(accessManager)) throw new Error("Invalid access manager address"); + + const sprl2v2Data = config.sprl2v2; + const prlToken = getTokenAddressFromConfig("prl", config); + const wethToken = getTokenAddressFromConfig("weth", config); + + const permit2 = checkAddressValid(sprl2v2Data.permit2, "Permit2"); + const feeReceiver = getWalletAddressFromConfig(sprl2v2Data.feeReceiver, config); + const balancerRouter = checkAddressValid(sprl2v2Data.balancerV3Router, "Balancer V3 Router"); + const balancerBPT = checkAddressValid(sprl2v2Data.balancerBPT, "Balancer BPT"); + + const BPTConfigParams = { + balancerRouter, + balancerBPT, + prl: prlToken, + weth: wethToken, + permit2, + }; + + const contract = await deploy(contractName, { + account: deployer, + artifact: artifacts.sPRL2V2, + args: [ + feeReceiver, + accessManager, + BigInt(sprl2v2Data.startPenaltyPercentage), + BigInt(sprl2v2Data.timeLockDuration), + BPTConfigParams, + ], + }); + + console.log(`Deployed ${contractName}, network: ${name}, address: ${contract.address}`); + }, + { + tags: [contractName], + }, +); diff --git a/deploy/utils/index.ts b/deploy/utils/index.ts index 3e01454..1cd7793 100644 --- a/deploy/utils/index.ts +++ b/deploy/utils/index.ts @@ -1,4 +1,4 @@ -import { ethers } from "ethers"; +import { isAddress, zeroAddress } from "viem"; import { Address, ConfigData } from "./types"; import { EndpointId } from "@layerzerolabs/lz-definitions"; @@ -33,5 +33,5 @@ export const checkAddressValid = (address: Address, label: string) => { }; export const isAddressValid = (address: string) => { - return ethers.utils.isAddress(address) && ethers.constants.AddressZero !== address; + return isAddress(address) && zeroAddress !== address; }; diff --git a/deploy/utils/types.ts b/deploy/utils/types.ts index 6c1bfff..83a22bf 100644 --- a/deploy/utils/types.ts +++ b/deploy/utils/types.ts @@ -1,7 +1,7 @@ -import type { BigNumberish } from "ethers"; - export type Address = `0x${string}`; +export type Numeric = string | number | bigint; + export type ConfigData = { isMainChainFeeDistributor: boolean; accessManager: Address; @@ -26,13 +26,13 @@ export type ConfigData = { sprl1: { underlying: Address; feeReceiver: string; - startPenaltyPercentage: BigNumberish; + startPenaltyPercentage: Numeric; timeLockDuration: number; }; sprl2: { permit2: Address; feeReceiver: string; - startPenaltyPercentage: BigNumberish; + startPenaltyPercentage: Numeric; timeLockDuration: number; balancerV3Router: Address; auraRewardsPool: Address; @@ -44,7 +44,7 @@ export type ConfigData = { sprl2v2: { permit2: Address; feeReceiver: string; - startPenaltyPercentage: BigNumberish; + startPenaltyPercentage: Numeric; timeLockDuration: number; balancerV3Router: Address; balancerBPT: Address; diff --git a/hardhat.config.ts b/hardhat.config.ts index bc4d64f..faa6bc8 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,35 +1,30 @@ import "dotenv/config"; -import "hardhat-deploy"; +import HardhatViem from "@nomicfoundation/hardhat-viem"; +import HardhatDeploy from "hardhat-deploy"; -import { HardhatUserConfig, HttpNetworkAccountsUserConfig } from "hardhat/types"; +import { HardhatUserConfig } from "hardhat/types/config"; import { getRpcURL } from "./utils/getRpcURL"; -import { getVerifyConfig } from "./utils/getVerifyConfig"; -const MNEMONIC = process.env.MNEMONIC; - -// If you prefer to be authenticated using a private key, set a PRIVATE_KEY environment variable const PRIVATE_KEY = process.env.PRIVATE_KEY; - -const accounts: HttpNetworkAccountsUserConfig | undefined = MNEMONIC - ? { mnemonic: MNEMONIC } - : PRIVATE_KEY - ? [PRIVATE_KEY] - : undefined; - -if (accounts == null) { - console.warn( - "Could not find MNEMONIC or PRIVATE_KEY environment variables. It will not be possible to execute transactions in your example.", - ); -} +if (!PRIVATE_KEY) throw new Error("PRIVATE_KEY is not set"); +const accounts = [PRIVATE_KEY]; const config: HardhatUserConfig = { + plugins: [HardhatViem, HardhatDeploy], + // Foundry tests live in `test/`; keep Hardhat from compiling them by pointing its + // Solidity sources at `contracts/` and its test dir at an unused path. + paths: { + sources: "contracts", + tests: "hardhat-test", + }, solidity: { compilers: [ { version: "0.8.25", settings: { + evmVersion: "cancun", optimizer: { enabled: true, runs: 10_000, @@ -40,41 +35,36 @@ const config: HardhatUserConfig = { }, networks: { mainnet: { - accounts, + type: "http", url: getRpcURL("mainnet"), - verify: getVerifyConfig("mainnet"), + accounts, }, sepolia: { - accounts, + type: "http", url: getRpcURL("sepolia"), - verify: getVerifyConfig("sepolia"), + accounts, }, arbiSepolia: { - accounts, + type: "http", url: getRpcURL("arbiSepolia"), - verify: getVerifyConfig("arbiSepolia"), + accounts, }, polygon: { - accounts, + type: "http", url: getRpcURL("polygon"), - verify: getVerifyConfig("polygon"), + accounts, }, base: { + type: "http", url: getRpcURL("base"), - verify: getVerifyConfig("base"), accounts, }, sonic: { + type: "http", url: getRpcURL("sonic"), - verify: getVerifyConfig("sonic"), accounts, }, }, - namedAccounts: { - deployer: { - default: 0, - }, - }, }; export default config; diff --git a/package.json b/package.json index 8a0776a..46ac4b7 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,13 @@ "description": "Parallel Tokenomics", "version": "1.0.0", "private": false, + "type": "module", "scripts": { "compile": "forge build && hardhat compile", - "deploy": "npx hardhat deploy", - "clean": "rm -rf cache out", + "deploy": "hardhat deploy", + "clean": "rm -rf cache out generated", "build": "forge build", + "size": "forge build --sizes", "lint": "bun run lint:sol && bun run prettier:check", "lint:sol": "forge fmt --check && bun solhint \"{script,contracts,test}/**/*.sol\"", "prettier:check": "prettier --check \"**/*.{json,md,yml}\" --ignore-path \".prettierignore\"", @@ -17,27 +19,40 @@ "test:coverage": "forge coverage --ir-minimum", "test:coverage:report": "forge coverage --ir-minimum --report lcov && lcov --remove lcov.info -o lcov.info \"test/*\" && genhtml lcov.info -o coverage", "prepare": "husky", - "verify": "npx hardhat etherscan-verify --sleep" + "verify": "rocketh-verify etherscan" }, "dependencies": { "@layerzerolabs/lz-evm-oapp-v2": "^3.0.14", - "@openzeppelin/contracts": "^5.1.0", - "ts-node": "^10.9.2" + "@openzeppelin/contracts": "^5.1.0" }, "devDependencies": { "@commitlint/cli": "^19.5.0", "@commitlint/config-conventional": "^19.5.0", "@layerzerolabs/lz-definitions": "^3.0.36", - "@nomicfoundation/hardhat-foundry": "^1.1.2", + "@nomicfoundation/hardhat-viem": "^3.0.0", + "@rocketh/deploy": "^0.19.8", + "@rocketh/doc": "^0.19.7", + "@rocketh/export": "^0.19.8", + "@rocketh/proxy": "^0.19.14", + "@rocketh/read-execute": "^0.19.3", + "@rocketh/signer": "^0.19.3", + "@rocketh/verifier": "^0.19.7", + "@rocketh/viem": "^0.19.3", "@types/fs-extra": "^11.0.4", - "dotenv": "^16.4.5", + "@types/node": "^24.3.0", + "dotenv": "^17.2.1", "forge-std": "github:foundry-rs/forge-std#v1.9.5", - "fs-extra": "^11.2.0", - "hardhat-contract-sizer": "^2.10.0", - "hardhat-deploy": "^0.14.0", + "fs-extra": "^11.3.0", + "hardhat": "^3.0.3", + "hardhat-deploy": "^2.0.0-next.40", "husky": "^9.1.6", "murky": "github:dmfxyz/murky", - "prettier": "^3.3.3", - "solhint": "^5.0.3" + "prettier": "^3.5.3", + "rocketh": "^0.19.7", + "solhint": "^5.0.3", + "ts-node": "^10.9.2", + "tsx": "^4.20.5", + "typescript": "^5.9.2", + "viem": "^2.37.1" } } diff --git a/remappings.txt b/remappings.txt index 422f91d..8a15695 100644 --- a/remappings.txt +++ b/remappings.txt @@ -2,3 +2,4 @@ @forge-std/=node_modules/forge-std/src/ @layerzerolabs/=node_modules/@layerzerolabs/ @murky/=node_modules/murky/src/ +contracts/=contracts/ diff --git a/rocketh.ts b/rocketh.ts new file mode 100644 index 0000000..30ea11c --- /dev/null +++ b/rocketh.ts @@ -0,0 +1,38 @@ +// ------------------------------------------------------------------------------------------------ +// Typed Config +// ------------------------------------------------------------------------------------------------ +import type { UserConfig } from "rocketh/types"; + +export const config = { + accounts: { + deployer: { + default: 0, + }, + }, + data: {}, +} as const satisfies UserConfig; + +// ------------------------------------------------------------------------------------------------ +// Extensions available to the deploy scripts through the environment object. +// ------------------------------------------------------------------------------------------------ +import * as deployExtension from "@rocketh/deploy"; // provides a deploy function +import * as readExecuteExtension from "@rocketh/read-execute"; // provides read/execute functions +import * as deployProxyExtension from "@rocketh/proxy"; // provides deployViaProxy for proxy based contracts +import * as viemExtension from "@rocketh/viem"; // provides viem handles to clients and contracts +const extensions = { + ...deployExtension, + ...readExecuteExtension, + ...deployProxyExtension, + ...viemExtension, +}; + +// ------------------------------------------------------------------------------------------------ +// Re-export the generated artifacts so they are available from the @rocketh alias. +import * as artifacts from "./generated/artifacts"; +export { artifacts }; + +// ------------------------------------------------------------------------------------------------ +// Create the deployScript helper bound to our extensions and typed config. +import { setupDeployScripts } from "rocketh"; +const { deployScript } = setupDeployScripts(extensions); +export { deployScript }; diff --git a/tsconfig.json b/tsconfig.json index 7fc6a13..68ba309 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,21 @@ { "exclude": ["node_modules"], - "include": ["./hardhat.config.ts", "./scripts", "./deploy", "./test", "./tasks"], + "include": ["./hardhat.config.ts", "./rocketh.ts", "./scripts", "./deploy", "./utils"], "compilerOptions": { - "target": "es2020", - "module": "commonjs", - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, + "lib": ["es2023"], + "module": "esnext", + "moduleResolution": "bundler", + "target": "es2022", "strict": true, + "esModuleInterop": true, "skipLibCheck": true, - "resolveJsonModule": true + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "outDir": "dist", + "rootDir": ".", + "paths": { + "@rocketh": ["./rocketh.ts"], + "@generated/*": ["./generated/*"] + } } } diff --git a/utils/getVerifyConfig.ts b/utils/getVerifyConfig.ts deleted file mode 100644 index 558c7f4..0000000 --- a/utils/getVerifyConfig.ts +++ /dev/null @@ -1,86 +0,0 @@ -type VerifyConfig = { - etherscan: { - apiUrl: string; - apiKey: string; - }; -}; - -export const getVerifyConfig = (network: string): VerifyConfig => { - switch (network) { - case "mainnet": { - if (!process.env.MAINNET_ETHERSCAN_API_KEY) throw new Error("MAINNET_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api.etherscan.io", - apiKey: process.env.MAINNET_ETHERSCAN_API_KEY, - }, - }; - } - case "sepolia": { - if (!process.env.MAINNET_ETHERSCAN_API_KEY) throw new Error("MAINNET_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api-sepolia.etherscan.io", - apiKey: process.env.MAINNET_ETHERSCAN_API_KEY, - }, - }; - } - case "polygon": { - if (!process.env.POLYGON_ETHERSCAN_API_KEY) throw new Error("POLYGON_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api.polygonscan.com", - apiKey: process.env.POLYGON_ETHERSCAN_API_KEY, - }, - }; - } - case "amoy": { - if (!process.env.POLYGON_ETHERSCAN_API_KEY) throw new Error("POLYGON_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api-amoy.polygonscan.com", - apiKey: process.env.POLYGON_ETHERSCAN_API_KEY, - }, - }; - } - case "arbiSepolia": { - if (!process.env.ARBITRUM_ETHERSCAN_API_KEY) throw new Error("ARBITRUM_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api-sepolia.arbiscan.io", - apiKey: process.env.ARBITRUM_ETHERSCAN_API_KEY, - }, - }; - } - case "fantom": { - if (!process.env.FANTOM_ETHERSCAN_API_KEY) throw new Error("FANTOM_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api.ftmscan.com", - apiKey: process.env.FANTOM_ETHERSCAN_API_KEY, - }, - }; - } - case "base": { - if (!process.env.BASE_ETHERSCAN_API_KEY) throw new Error("BASE_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api.basescan.org", - apiKey: process.env.BASE_ETHERSCAN_API_KEY, - }, - }; - } - case "sonic": { - if (!process.env.SONIC_ETHERSCAN_API_KEY) throw new Error("SONIC_ETHERSCAN_API_KEY is not set"); - return { - etherscan: { - apiUrl: "https://api.sonicscan.org", - apiKey: process.env.SONIC_ETHERSCAN_API_KEY, - }, - }; - } - default: { - throw new Error(`${network} Network Verify not configured`); - } - } -};