From 0651b51294f1f1268affe99463d28109d99dcaa4 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 14:50:05 -0300 Subject: [PATCH 01/11] feat: support deployment dry run on forked network --- deploy/001-deploy-mock-tokens.ts | 6 ++- deploy/004-swap-router.ts | 14 +++--- deploy/006-deploy-pool-registry.ts | 5 +- deploy/007-deploy-pool-lens.ts | 2 +- deploy/008-deploy-comptrollers.ts | 3 +- deploy/009-deploy-vtokens.ts | 7 ++- deploy/010-deploy-reward-distributors.ts | 7 ++- deploy/011-initial-liquidity.ts | 6 +-- deploy/012-transfer-pools-ownership.ts | 2 +- deploy/013-vip-based-config.ts | 10 ++-- deploy/014-shortfall-protocolshare.ts | 5 +- deploy/016-deploy-beacon-implementations.ts | 4 +- deploy/017-update-pool-registry.ts | 4 +- deploy/018-native-token-gateway.ts | 4 +- deploy/019-deploy-ir-models.ts | 5 +- hardhat.config.ts | 51 +++++++++++++++++++-- helpers/deploymentUtils.ts | 6 +-- tsconfig.json | 2 +- type-extensions.ts | 9 ++++ 19 files changed, 99 insertions(+), 53 deletions(-) create mode 100644 type-extensions.ts diff --git a/deploy/001-deploy-mock-tokens.ts b/deploy/001-deploy-mock-tokens.ts index 27cdd0a2a..3ed63103c 100644 --- a/deploy/001-deploy-mock-tokens.ts +++ b/deploy/001-deploy-mock-tokens.ts @@ -4,11 +4,11 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"; import { getConfig } from "../helpers/deploymentConfig"; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployments, getNamedAccounts }: any = hre; + const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { tokensConfig } = await getConfig(hre.network.name); + const { tokensConfig } = await getConfig(hre.getNetworkName()); for (const token of tokensConfig) { if (token.isMock) { @@ -27,4 +27,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { func.tags = ["MockTokens"]; +func.skip = async hre => hre.network.live + export default func; diff --git a/deploy/004-swap-router.ts b/deploy/004-swap-router.ts index 498776ce9..211b91d5a 100644 --- a/deploy/004-swap-router.ts +++ b/deploy/004-swap-router.ts @@ -16,7 +16,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const vbnbAddress = (await deployments.get("vBNB")).address; // Pancake Factory doesn't exist on hardhat so we are using the testnet address const pancakeFactoryAddress = - hre.network.name === "bscmainnet" + hre.getNetworkName() === "bscmainnet" ? Mainnet.contracts.pancakeFactory.address : Testnet.contracts.pancakeFactory.address; @@ -48,7 +48,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { autoMine: true, skipIfAlreadyDeployed: true, }); - if (hre.network.name !== "bsctestnet") { + if (hre.getNetworkName() !== "bsctestnet") { const comptrollerStablecoinsAddresses = (await deployments.get("Comptroller_Stablecoins")).address; await deploy("SwapRouter_Stablecoins", { contract: "SwapRouter", @@ -95,10 +95,10 @@ func.tags = ["SwapRouter", "il"]; // deploySwapRouter.skip = async (hre: HardhatRuntimeEnvironment) => hre.network.live; // Pancake Factory is not deployed on the local network func.skip = async hre => - hre.network.name === "sepolia" || - hre.network.name === "hardhat" || - hre.network.name === "opbnbtestnet" || - hre.network.name === "opbnbmainnet" || - hre.network.name === "ethereum"; + hre.getNetworkName() === "sepolia" || + hre.getNetworkName() === "hardhat" || + hre.getNetworkName() === "opbnbtestnet" || + hre.getNetworkName() === "opbnbmainnet" || + hre.getNetworkName() === "ethereum"; export default func; diff --git a/deploy/006-deploy-pool-registry.ts b/deploy/006-deploy-pool-registry.ts index 4958efe38..1c23dbb93 100644 --- a/deploy/006-deploy-pool-registry.ts +++ b/deploy/006-deploy-pool-registry.ts @@ -8,12 +8,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { preconfiguredAddresses } = await getConfig(hre.network.name); + const { preconfiguredAddresses } = await getConfig(hre.getNetworkName()); const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); - const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer", hre); + const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer"); // The reason for this is that the contracts `OptimizedTransparentUpgradeableProxy` and `DefaultProxyAdmin` that the hardhat-deploy // plugin fetches from the artifact is not zk compatible causing the deployments to fail. So we bought it one level up to our repo, diff --git a/deploy/007-deploy-pool-lens.ts b/deploy/007-deploy-pool-lens.ts index 2ccd22246..0c204f7ef 100644 --- a/deploy/007-deploy-pool-lens.ts +++ b/deploy/007-deploy-pool-lens.ts @@ -8,7 +8,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.network.name); + const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); await deploy("PoolLens", { from: deployer, diff --git a/deploy/008-deploy-comptrollers.ts b/deploy/008-deploy-comptrollers.ts index 89bdd15c7..40bdd9665 100644 --- a/deploy/008-deploy-comptrollers.ts +++ b/deploy/008-deploy-comptrollers.ts @@ -10,12 +10,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const deploymentConfig = await getConfig(hre.network.name); + const deploymentConfig = await getConfig(hre.getNetworkName()); const { poolConfig, preconfiguredAddresses } = deploymentConfig; const poolRegistry = await ethers.getContract("PoolRegistry"); const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); const maxLoopsLimit = 100; diff --git a/deploy/009-deploy-vtokens.ts b/deploy/009-deploy-vtokens.ts index d7c6b9fce..34ebc9428 100644 --- a/deploy/009-deploy-vtokens.ts +++ b/deploy/009-deploy-vtokens.ts @@ -19,14 +19,13 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { tokensConfig, poolConfig, preconfiguredAddresses } = await getConfig(hre.network.name); + const { tokensConfig, poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.network.name); - const maxBorrowRateMantissa = getMaxBorrowRateMantissa(hre.network.name); + const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); + const maxBorrowRateMantissa = getMaxBorrowRateMantissa(hre.getNetworkName()); const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); // VToken Beacon diff --git a/deploy/010-deploy-reward-distributors.ts b/deploy/010-deploy-reward-distributors.ts index f146597ba..ecf5b91db 100644 --- a/deploy/010-deploy-reward-distributors.ts +++ b/deploy/010-deploy-reward-distributors.ts @@ -15,14 +15,13 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer } = await getNamedAccounts(); const maxLoopsLimit = 100; - const { tokensConfig, poolConfig, preconfiguredAddresses } = await getConfig(hre.network.name); - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.network.name); + const { tokensConfig, poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); + const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); const accessControlAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); - const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer", hre); + const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer"); const defaultProxyAdmin = await hre.artifacts.readArtifact( "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", ); diff --git a/deploy/011-initial-liquidity.ts b/deploy/011-initial-liquidity.ts index bd36fa462..ff8d2cf1d 100644 --- a/deploy/011-initial-liquidity.ts +++ b/deploy/011-initial-liquidity.ts @@ -45,7 +45,7 @@ const faucetTokens = async (deploymentConfig: DeploymentConfig, hre: HardhatRunt }; const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig, hre: HardhatRuntimeEnvironment) => { - if (hre.network.name == "bscmainnet" || hre.network.name == "ethereum") { + if (hre.getNetworkName() == "bscmainnet" || hre.getNetworkName() == "ethereum") { return; } const { poolConfig, tokensConfig, preconfiguredAddresses } = deploymentConfig; @@ -62,7 +62,7 @@ const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig console.log(`Sending ${amount} ${symbol} to VTreasury`); console.log(`Token Contract: ${tokenContract.address}`); console.log(`Token Contract: ${amount.toString()}`); - const treasuryAddress = await toAddress(preconfiguredAddresses.VTreasury || "VTreasury", hre); + const treasuryAddress = await toAddress(preconfiguredAddresses.VTreasury || "VTreasury"); console.log(`Token Contract: ${treasuryAddress}`); const tx = await tokenContract.transfer(treasuryAddress, amount, { gasLimit: 5000000 }); @@ -71,7 +71,7 @@ const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig }; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const deploymentConfig = await getConfig(hre.network.name); + const deploymentConfig = await getConfig(hre.getNetworkName()); await faucetTokens(deploymentConfig, hre); await sendInitialLiquidityToTreasury(deploymentConfig, hre); }; diff --git a/deploy/012-transfer-pools-ownership.ts b/deploy/012-transfer-pools-ownership.ts index c51c1ff1a..028e9fc60 100644 --- a/deploy/012-transfer-pools-ownership.ts +++ b/deploy/012-transfer-pools-ownership.ts @@ -6,7 +6,7 @@ import { PoolConfig, getConfig } from "../helpers/deploymentConfig"; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployer } = await getNamedAccounts(); - const { poolConfig, preconfiguredAddresses } = await getConfig(hre.network.name); + const { poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; const rewardsDistributors = poolConfig diff --git a/deploy/013-vip-based-config.ts b/deploy/013-vip-based-config.ts index acaf7f6af..9689ac4c6 100644 --- a/deploy/013-vip-based-config.ts +++ b/deploy/013-vip-based-config.ts @@ -229,11 +229,10 @@ const addMarket = async ( poolRegistry: PoolRegistry, vTokenAddress: string, vTokenConfig: VTokenConfig, - hre: HardhatRuntimeEnvironment, ): Promise => { const { name, collateralFactor, liquidationThreshold, initialSupply, supplyCap, borrowCap } = vTokenConfig; console.log("Adding a command to register " + name + " to PoolRegistry"); - const receiver = await toAddress(vTokenConfig.vTokenReceiver, hre); + const receiver = await toAddress(vTokenConfig.vTokenReceiver); return { contract: poolRegistry.address, signature: "addMarket((address,uint256,uint256,uint256,address,uint256,uint256))", @@ -316,7 +315,6 @@ const configureAccessControls = async ( const { accessControlConfig, preconfiguredAddresses } = deploymentConfig; const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); const accessControlManager = await ethers.getContractAt( "AccessControlManager", @@ -325,8 +323,8 @@ const configureAccessControls = async ( const commands = await Promise.all( accessControlConfig.map(async (entry: AccessControlEntry) => { const { caller, target, method } = entry; - const callerAddress = await toAddress(caller, hre); - const targetAddress = await toAddress(target, hre); + const callerAddress = await toAddress(caller); + const targetAddress = await toAddress(target); if (await hasPermission(accessControlManager, targetAddress, method, callerAddress, hre)) { return []; } @@ -371,7 +369,7 @@ const executeCommands = async (commands: GovernanceCommand[], hre: HardhatRuntim const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { getNamedAccounts } = hre; const { deployer } = await getNamedAccounts(); - const deploymentConfig = await getConfig(hre.network.name); + const deploymentConfig = await getConfig(hre.getNetworkName()); const { poolConfig, preconfiguredAddresses } = deploymentConfig; const unregisteredPools = await getUnregisteredPools(poolConfig, hre); diff --git a/deploy/014-shortfall-protocolshare.ts b/deploy/014-shortfall-protocolshare.ts index 73b8b59f3..3eddcc8b1 100644 --- a/deploy/014-shortfall-protocolshare.ts +++ b/deploy/014-shortfall-protocolshare.ts @@ -15,13 +15,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { preconfiguredAddresses } = await getConfig(hre.network.name); + const { preconfiguredAddresses } = await getConfig(hre.getNetworkName()); const poolRegistry = await ethers.getContract("PoolRegistry"); const deployerSigner = ethers.provider.getSigner(deployer); const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); const proxyAdmin = await ethers.getContract("DefaultProxyAdmin"); const owner = await proxyAdmin.owner(); @@ -29,7 +28,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", ); - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.network.name); + const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); const riskFund = await ethers.getContract("RiskFundV2"); diff --git a/deploy/016-deploy-beacon-implementations.ts b/deploy/016-deploy-beacon-implementations.ts index 36ca1451a..7ec853be7 100644 --- a/deploy/016-deploy-beacon-implementations.ts +++ b/deploy/016-deploy-beacon-implementations.ts @@ -11,10 +11,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.network.name); + const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); const poolRegistry = await ethers.getContract("PoolRegistry"); - const maxBorrowRateMantissa = getMaxBorrowRateMantissa(hre.network.name); + const maxBorrowRateMantissa = getMaxBorrowRateMantissa(hre.getNetworkName()); // Comptroller Implementation await deploy("ComptrollerImpl", { diff --git a/deploy/017-update-pool-registry.ts b/deploy/017-update-pool-registry.ts index e165fd80b..6094667ad 100644 --- a/deploy/017-update-pool-registry.ts +++ b/deploy/017-update-pool-registry.ts @@ -8,8 +8,8 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy, catchUnknownSigner } = deployments; const { deployer } = await getNamedAccounts(); - const { preconfiguredAddresses } = await getConfig(hre.network.name); - const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer", hre); + const { preconfiguredAddresses } = await getConfig(hre.getNetworkName()); + const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer"); const defaultProxyAdmin = await hre.artifacts.readArtifact( "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", ); diff --git a/deploy/018-native-token-gateway.ts b/deploy/018-native-token-gateway.ts index e22b143f4..ae2e34dc0 100644 --- a/deploy/018-native-token-gateway.ts +++ b/deploy/018-native-token-gateway.ts @@ -118,9 +118,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { preconfiguredAddresses } = await getConfig(hre.network.name); + const { preconfiguredAddresses } = await getConfig(hre.getNetworkName()); - const vWNativesInfo = getVWNativeTokens(hre.network.name); + const vWNativesInfo = getVWNativeTokens(hre.getNetworkName()); for (const vWNativeInfo of vWNativesInfo) { await deploy(`NativeTokenGateway_${vWNativeInfo.name}`, { contract: "NativeTokenGateway", diff --git a/deploy/019-deploy-ir-models.ts b/deploy/019-deploy-ir-models.ts index 112df5984..eb5ac03b6 100644 --- a/deploy/019-deploy-ir-models.ts +++ b/deploy/019-deploy-ir-models.ts @@ -15,13 +15,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { deployments, getNamedAccounts } = hre; const { deploy } = deployments; const { deployer } = await getNamedAccounts(); - const { poolConfig, preconfiguredAddresses } = await getConfig(hre.network.name); + const { poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.network.name); + const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", - hre, ); for (const pool of poolConfig) { diff --git a/hardhat.config.ts b/hardhat.config.ts index 011e59c8f..8a033fbff 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -11,7 +11,7 @@ import "hardhat-dependency-compiler"; import "hardhat-deploy"; import { DeployResult } from "hardhat-deploy/types"; import "hardhat-gas-reporter"; -import { HardhatUserConfig, extendConfig, task, types } from "hardhat/config"; +import { HardhatUserConfig, extendConfig, extendEnvironment, task, types } from "hardhat/config"; import { HardhatConfig } from "hardhat/types"; import "solidity-coverage"; import "solidity-docgen"; @@ -21,46 +21,83 @@ import { convertToUnit } from "./helpers/utils"; dotenv.config(); const DEPLOYER_PRIVATE_KEY = process.env.DEPLOYER_PRIVATE_KEY; +const getRpcUrl = (networkName: string): string => { + let uri + if (networkName) { + uri = process.env[`ARCHIVE_NODE_${networkName}`]; + } + if (!uri) { + throw new Error( + `invalid uri or network not supported by node provider : ${uri}` + ); + } + return uri; +} + +extendEnvironment((hre) => { + hre.getNetworkName = () => process.env.HARDHAT_FORK_NETWORK || hre.network.name +}); + extendConfig((config: HardhatConfig) => { if (process.env.EXPORT !== "true") { config.external = { ...config.external, deployments: { + hardhat: [], bsctestnet: [ "node_modules/@venusprotocol/oracle/deployments/bsctestnet", "node_modules/@venusprotocol/venus-protocol/deployments/bsctestnet", "node_modules/@venusprotocol/protocol-reserve/deployments/bsctestnet", + "node_modules/@venusprotocol/governance-contracts/deployments/bsctestnet", ], sepolia: [ "node_modules/@venusprotocol/oracle/deployments/sepolia", "node_modules/@venusprotocol/venus-protocol/deployments/sepolia", "node_modules/@venusprotocol/protocol-reserve/deployments/sepolia", + "node_modules/@venusprotocol/governance-contracts/deployments/sepolia", ], ethereum: [ "node_modules/@venusprotocol/oracle/deployments/ethereum", "node_modules/@venusprotocol/venus-protocol/deployments/ethereum", "node_modules/@venusprotocol/protocol-reserve/deployments/ethereum", + "node_modules/@venusprotocol/governance-contracts/deployments/ethereum", ], bscmainnet: [ "node_modules/@venusprotocol/oracle/deployments/bscmainnet", "node_modules/@venusprotocol/venus-protocol/deployments/bscmainnet", "node_modules/@venusprotocol/protocol-reserve/deployments/bscmainnet", + "node_modules/@venusprotocol/governance-contracts/deployments/bscmainnet", ], opbnbmainnet: [ "node_modules/@venusprotocol/oracle/deployments/opbnbmainnet", "node_modules/@venusprotocol/protocol-reserve/deployments/opbnbmainnet", + "node_modules/@venusprotocol/governance-contracts/deployments/opbnbmainnet", ], opbnbtestnet: [ "node_modules/@venusprotocol/oracle/deployments/opbnbtestnet", "node_modules/@venusprotocol/protocol-reserve/deployments/opbnbtestnet", + "node_modules/@venusprotocol/governance-contracts/deployments/opbnbtestnet", ], arbitrumsepolia: [ "node_modules/@venusprotocol/oracle/deployments/arbitrumsepolia", "node_modules/@venusprotocol/protocol-reserve/deployments/arbitrumsepolia", + "node_modules/@venusprotocol/governance-contracts/deployments/arbitrumsepolia", + ], + arbitrumone: [ + "node_modules/@venusprotocol/protocol-reserve/deployments/arbitrumone", + "node_modules/@venusprotocol/governance-contracts/deployments/arbitrumsepolia", ], - arbitrumone: ["node_modules/@venusprotocol/protocol-reserve/deployments/arbitrumone"], }, }; + if (process.env.HARDHAT_FORK_NETWORK) { + config.external.deployments!.hardhat = [ + `./deployments/${process.env.HARDHAT_FORK_NETWORK}`, + `node_modules/@venusprotocol/oracle/deployments/${process.env.HARDHAT_FORK_NETWORK}`, + `node_modules/@venusprotocol/venus-protocol/deployments/${process.env.HARDHAT_FORK_NETWORK}`, + `node_modules/@venusprotocol/protocol-reserve/deployments/${process.env.HARDHAT_FORK_NETWORK}`, + `node_modules/@venusprotocol/governance-contracts/deployments/${process.env.HARDHAT_FORK_NETWORK}`, + ] + } } }); @@ -217,7 +254,15 @@ const config: HardhatUserConfig = { hardhat: { allowUnlimitedContractSize: true, loggingEnabled: false, - live: false, + live: !!process.env.HARDHAT_FORK_NETWORK, + forking: process.env.HARDHAT_FORK_NETWORK + ? { + url: getRpcUrl(process.env.HARDHAT_FORK_NETWORK), + blockNumber: process.env.HARDHAT_FORK_NUMBER + ? parseInt(process.env.HARDHAT_FORK_NUMBER) + : undefined, + } + : undefined, }, development: { url: "http://127.0.0.1:8545/", diff --git a/helpers/deploymentUtils.ts b/helpers/deploymentUtils.ts index acdfcfc0c..e1c9af439 100644 --- a/helpers/deploymentUtils.ts +++ b/helpers/deploymentUtils.ts @@ -1,4 +1,4 @@ -import { ethers } from "hardhat"; +import { ethers, getNamedAccounts, deployments } from "hardhat"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { Comptroller, ERC20, MockToken } from "../typechain"; @@ -12,9 +12,7 @@ import { getTokenConfig, } from "./deploymentConfig"; -export const toAddress = async (addressOrAlias: string, hre: HardhatRuntimeEnvironment): Promise => { - const { getNamedAccounts } = hre; - const { deployments } = hre; +export const toAddress = async (addressOrAlias: string): Promise => { if (addressOrAlias.startsWith("0x")) { return addressOrAlias; } diff --git a/tsconfig.json b/tsconfig.json index 3f95231ec..979599aeb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,6 @@ "@nomiclabs/hardhat-ethers": ["./node_modules/hardhat-deploy-ethers"] } }, - "include": ["./typechain", "./deploy", "./helpers"], + "include": ["./typechain", "./deploy", "./helpers", "./type-extensions.ts"], "files": ["./hardhat.config.ts"] } diff --git a/type-extensions.ts b/type-extensions.ts new file mode 100644 index 000000000..42faf3f64 --- /dev/null +++ b/type-extensions.ts @@ -0,0 +1,9 @@ +import "hardhat/types/runtime"; + +declare module "hardhat/types/runtime" { + // This is an example of an extension to the Hardhat Runtime Environment. + // This new field will be available in tasks' actions, scripts, and tests. + export interface HardhatRuntimeEnvironment { + getNetworkName: () => string; + } +} \ No newline at end of file From 451eb4a795f31c1872bc18c61900bb1a257b877b Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 15:20:29 -0300 Subject: [PATCH 02/11] refactor: remove duplicate logs --- deploy/008-deploy-comptrollers.ts | 5 ++-- deploy/009-deploy-vtokens.ts | 3 --- deploy/013-vip-based-config.ts | 41 +++++++++++++------------------ deploy/019-deploy-ir-models.ts | 2 -- helpers/deploymentUtils.ts | 7 ------ 5 files changed, 19 insertions(+), 39 deletions(-) diff --git a/deploy/008-deploy-comptrollers.ts b/deploy/008-deploy-comptrollers.ts index 40bdd9665..7572afe3f 100644 --- a/deploy/008-deploy-comptrollers.ts +++ b/deploy/008-deploy-comptrollers.ts @@ -38,10 +38,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const unregisteredPools = await getUnregisteredPools(poolConfig, hre); for (const pool of unregisteredPools) { - // Deploying a proxy for Comptroller - console.log(`Deploying a proxy for Comptroller of the pool ${pool.name}`); const Comptroller = await ethers.getContractFactory("Comptroller"); - + + // Deploying a proxy for Comptroller await deploy(`Comptroller_${pool.id}`, { from: deployer, contract: "BeaconProxy", diff --git a/deploy/009-deploy-vtokens.ts b/deploy/009-deploy-vtokens.ts index 34ebc9428..c83fd6458 100644 --- a/deploy/009-deploy-vtokens.ts +++ b/deploy/009-deploy-vtokens.ts @@ -80,7 +80,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { if (rateModel === InterestRateModels.JumpRate.toString()) { const [b, m, j, k] = [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_].map(mantissaToBps); const rateModelName = `JumpRateModelV2_base${b}bps_slope${m}bps_jump${j}bps_kink${k}bps`; - console.log(`Deploying interest rate model ${rateModelName}`); const result: DeployResult = await deploy(rateModelName, { from: deployer, contract: "JumpRateModelV2", @@ -101,7 +100,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { } else { const [b, m] = [baseRatePerYear, multiplierPerYear].map(mantissaToBps); const rateModelName = `WhitePaperInterestRateModel_base${b}bps_slope${m}bps`; - console.log(`Deploying interest rate model ${rateModelName}`); const result: DeployResult = await deploy(rateModelName, { from: deployer, contract: "WhitePaperInterestRateModel", @@ -113,7 +111,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { rateModelAddress = result.address; } - console.log(`Deploying VToken proxy for ${symbol}`); const VToken = await ethers.getContractFactory("VToken"); const underlyingDecimals = Number(await tokenContract.decimals()); const vTokenDecimals = 8; diff --git a/deploy/013-vip-based-config.ts b/deploy/013-vip-based-config.ts index 9689ac4c6..c38819862 100644 --- a/deploy/013-vip-based-config.ts +++ b/deploy/013-vip-based-config.ts @@ -1,6 +1,6 @@ import { BigNumberish } from "ethers"; import { defaultAbiCoder, parseEther } from "ethers/lib/utils"; -import { ethers } from "hardhat"; +import { ethers, network, deployments } from "hardhat"; import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; @@ -76,7 +76,6 @@ const setRewardSpeed = async ( const configureRewards = async ( unregisteredRewardDistributors: PoolConfig[], owner: string, - hre: HardhatRuntimeEnvironment, ): Promise => { const commands = await Promise.all( unregisteredRewardDistributors.map(async (pool: PoolConfig) => { @@ -86,7 +85,7 @@ const configureRewards = async ( const contractName = `RewardsDistributor_${pool.id}_${idx}`; const rewardsDistributor = await ethers.getContract(contractName); return [ - ...(await acceptOwnership(contractName, owner, hre)), + ...(await acceptOwnership(contractName, owner)), await addRewardsDistributor(rewardsDistributor, pool, rewardConfig), await setRewardSpeed(pool, rewardsDistributor, rewardConfig), ]; @@ -101,13 +100,12 @@ const configureRewards = async ( const acceptOwnership = async ( contractName: string, targetOwner: string, - hre: HardhatRuntimeEnvironment, ): Promise => { - if (!hre.network.live) { + if (!network.live) { return []; } const abi = ["function owner() view returns (address)"]; - const deployment = await hre.deployments.get(contractName); + const deployment = await deployments.get(contractName); const contract = await ethers.getContractAt(abi, deployment.address); if ((await contract.owner()) === targetOwner) { return []; @@ -156,14 +154,13 @@ const addPool = (poolRegistry: PoolRegistry, comptroller: Comptroller, pool: Poo const addPools = async ( unregisteredPools: PoolConfig[], poolsOwner: string, - hre: HardhatRuntimeEnvironment, ): Promise => { const poolRegistry = await ethers.getContract("PoolRegistry"); const commands = await Promise.all( unregisteredPools.map(async (pool: PoolConfig) => { const comptroller = await ethers.getContract(`Comptroller_${pool.id}`); return [ - ...(await acceptOwnership(`Comptroller_${pool.id}`, poolsOwner, hre)), + ...(await acceptOwnership(`Comptroller_${pool.id}`, poolsOwner)), await setOracle(comptroller, pool), addPool(poolRegistry, comptroller, pool), ]; @@ -175,7 +172,6 @@ const addPools = async ( const transferInitialLiquidity = async ( vTokenConfig: VTokenConfig, deploymentConfig: DeploymentConfig, - hre: HardhatRuntimeEnvironment, ): Promise => { if (!hre.network.live) { return []; @@ -262,7 +258,6 @@ const setReduceReservesBlockDelta = async ( const addMarkets = async ( unregisteredVTokens: PoolConfig[], deploymentConfig: DeploymentConfig, - hre: HardhatRuntimeEnvironment, ) => { const poolRegistry = await ethers.getContract("PoolRegistry"); const poolCommands = await Promise.all( @@ -275,10 +270,10 @@ const addMarkets = async ( console.log("Adding market " + name + " to pool " + pool.name); return [ - ...(await transferInitialLiquidity(vTokenConfig, deploymentConfig, hre)), + ...(await transferInitialLiquidity(vTokenConfig, deploymentConfig)), ...(await approvePoolRegistry(poolRegistry, vTokenConfig, deploymentConfig)), await setReduceReservesBlockDelta(vToken.address, vTokenConfig), - await addMarket(poolRegistry, vToken.address, vTokenConfig, hre), + await addMarket(poolRegistry, vToken.address, vTokenConfig), ]; }), ); @@ -302,15 +297,13 @@ const hasPermission = async ( targetContract: string, method: string, caller: string, - hre: HardhatRuntimeEnvironment, ): Promise => { - const role = makeRole(hre.network.live, targetContract, method); + const role = makeRole(network.live, targetContract, method); return accessControl.hasRole(role, caller); }; const configureAccessControls = async ( deploymentConfig: DeploymentConfig, - hre: HardhatRuntimeEnvironment, ): Promise => { const { accessControlConfig, preconfiguredAddresses } = deploymentConfig; const accessControlManagerAddress = await toAddress( @@ -325,7 +318,7 @@ const configureAccessControls = async ( const { caller, target, method } = entry; const callerAddress = await toAddress(caller); const targetAddress = await toAddress(target); - if (await hasPermission(accessControlManager, targetAddress, method, callerAddress, hre)) { + if (await hasPermission(accessControlManager, targetAddress, method, callerAddress)) { return []; } return [ @@ -372,16 +365,16 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const deploymentConfig = await getConfig(hre.getNetworkName()); const { poolConfig, preconfiguredAddresses } = deploymentConfig; - const unregisteredPools = await getUnregisteredPools(poolConfig, hre); - const unregisteredVTokens = await getUnregisteredVTokens(poolConfig, hre); - const unregisteredRewardsDistributors = await getUnregisteredRewardsDistributors(poolConfig, hre); + const unregisteredPools = await getUnregisteredPools(poolConfig); + const unregisteredVTokens = await getUnregisteredVTokens(poolConfig); + const unregisteredRewardsDistributors = await getUnregisteredRewardsDistributors(poolConfig); const owner = preconfiguredAddresses.NormalTimelock || deployer; const commands = [ - ...(await configureAccessControls(deploymentConfig, hre)), - ...(await acceptOwnership("PoolRegistry", owner, hre)), - ...(await addPools(unregisteredPools, owner, hre)), - ...(await addMarkets(unregisteredVTokens, deploymentConfig, hre)), - ...(await configureRewards(unregisteredRewardsDistributors, owner, hre)), + ...(await configureAccessControls(deploymentConfig)), + ...(await acceptOwnership("PoolRegistry", owner)), + ...(await addPools(unregisteredPools, owner)), + ...(await addMarkets(unregisteredVTokens, deploymentConfig)), + ...(await configureRewards(unregisteredRewardsDistributors, owner)), ]; if (hre.network.live) { diff --git a/deploy/019-deploy-ir-models.ts b/deploy/019-deploy-ir-models.ts index eb5ac03b6..727916509 100644 --- a/deploy/019-deploy-ir-models.ts +++ b/deploy/019-deploy-ir-models.ts @@ -31,7 +31,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { if (rateModel === InterestRateModels.JumpRate.toString()) { const [b, m, j, k] = [baseRatePerYear, multiplierPerYear, jumpMultiplierPerYear, kink_].map(mantissaToBps); const rateModelName = `JumpRateModelV2_base${b}bps_slope${m}bps_jump${j}bps_kink${k}bps`; - console.log(`Deploying interest rate model ${rateModelName}`); await deploy(rateModelName, { from: deployer, contract: "JumpRateModelV2", @@ -51,7 +50,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { } else { const [b, m] = [baseRatePerYear, multiplierPerYear].map(mantissaToBps); const rateModelName = `WhitePaperInterestRateModel_base${b}bps_slope${m}bps`; - console.log(`Deploying interest rate model ${rateModelName}`); await deploy(rateModelName, { from: deployer, contract: "WhitePaperInterestRateModel", diff --git a/helpers/deploymentUtils.ts b/helpers/deploymentUtils.ts index e1c9af439..3a80ba2bd 100644 --- a/helpers/deploymentUtils.ts +++ b/helpers/deploymentUtils.ts @@ -1,5 +1,4 @@ import { ethers, getNamedAccounts, deployments } from "hardhat"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; import { Comptroller, ERC20, MockToken } from "../typechain"; import { @@ -39,9 +38,7 @@ export const getUnderlyingToken = async (assetSymbol: string, tokensConfig: Toke export const getUnregisteredPools = async ( poolConfig: PoolConfig[], - hre: HardhatRuntimeEnvironment, ): Promise => { - const { deployments } = hre; const registry = await ethers.getContract("PoolRegistry"); const registeredPools = (await registry.getAllPools()).map((p: { comptroller: string }) => p.comptroller); const isRegistered = await Promise.all( @@ -59,9 +56,7 @@ export const getUnregisteredPools = async ( export const getUnregisteredVTokens = async ( poolConfig: PoolConfig[], - hre: HardhatRuntimeEnvironment, ): Promise => { - const { deployments } = hre; const registry = await ethers.getContract("PoolRegistry"); const registeredPools = await registry.getAllPools(); const comptrollers = await Promise.all( @@ -96,9 +91,7 @@ export const getUnregisteredVTokens = async ( export const getUnregisteredRewardsDistributors = async ( poolConfig: PoolConfig[], - hre: HardhatRuntimeEnvironment, ): Promise => { - const { deployments } = hre; const registry = await ethers.getContract("PoolRegistry"); const registeredPools = await registry.getAllPools(); const comptrollers = await Promise.all( From 203f2698b5211daae84eb43c2dbf02a8ebc087c2 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 15:20:52 -0300 Subject: [PATCH 03/11] fix: correct symbol in crv reward config --- helpers/deploymentConfig.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index 02c6670d9..75693a8eb 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -3807,7 +3807,7 @@ export const globalConfig: NetworkConfig = { // 3600 XVS for Borrowers { asset: "XVS", - markets: ["vCRV", "crvUSD"], + markets: ["CRV", "crvUSD"], supplySpeeds: ["925925925925925", "3703703703703703"], borrowSpeeds: ["1388888888888888", "5555555555555555"], }, @@ -3819,7 +3819,7 @@ export const globalConfig: NetworkConfig = { }, { asset: "XVS", - markets: ["vCRV", "crvUSD"], + markets: ["CRV", "crvUSD"], supplySpeeds: ["694444444444444", "694444444444444"], borrowSpeeds: ["1041666666666666", "1041666666666666"], }, From ae8369e929e2a39cf0cea222b796a4776965e74d Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 15:30:06 -0300 Subject: [PATCH 04/11] fix: skip networks where PSR hasnt been deployed yet --- deploy/014-shortfall-protocolshare.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deploy/014-shortfall-protocolshare.ts b/deploy/014-shortfall-protocolshare.ts index 3eddcc8b1..a44f20145 100644 --- a/deploy/014-shortfall-protocolshare.ts +++ b/deploy/014-shortfall-protocolshare.ts @@ -69,4 +69,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { }; func.tags = ["Shortfall", "il"]; +// RiskFund not deployed on these networks +func.skip = async hre => + hre.getNetworkName() === "sepolia" || + hre.getNetworkName() === "opbnbtestnet" || + hre.getNetworkName() === "opbnbmainnet" || + hre.getNetworkName() === "ethereum"; + + export default func; From cca355f3e7a4f58a7b069f7802bd601ee78f045e Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 15:30:22 -0300 Subject: [PATCH 05/11] refactor: remove duplicate scripts --- deploy/016-deploy-beacon-implementations.ts | 40 --------------------- deploy/017-update-pool-registry.ts | 35 ------------------ 2 files changed, 75 deletions(-) delete mode 100644 deploy/016-deploy-beacon-implementations.ts delete mode 100644 deploy/017-update-pool-registry.ts diff --git a/deploy/016-deploy-beacon-implementations.ts b/deploy/016-deploy-beacon-implementations.ts deleted file mode 100644 index 7ec853be7..000000000 --- a/deploy/016-deploy-beacon-implementations.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { ethers } from "hardhat"; -import { DeployFunction } from "hardhat-deploy/types"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; - -import { getMaxBorrowRateMantissa } from "../helpers/deploymentConfig"; -import { getBlockOrTimestampBasedDeploymentInfo } from "../helpers/deploymentUtils"; - -// This deploy script deploys implementations for Comptroller and/or VToken that should be updated through a VIP afterwards -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployments, getNamedAccounts } = hre; - const { deploy } = deployments; - const { deployer } = await getNamedAccounts(); - - const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); - - const poolRegistry = await ethers.getContract("PoolRegistry"); - const maxBorrowRateMantissa = getMaxBorrowRateMantissa(hre.getNetworkName()); - - // Comptroller Implementation - await deploy("ComptrollerImpl", { - contract: "Comptroller", - from: deployer, - args: [poolRegistry.address], - log: true, - autoMine: true, - }); - - // VToken Implementation - await deploy("VTokenImpl", { - contract: "VToken", - from: deployer, - args: [isTimeBased, blocksPerYear, maxBorrowRateMantissa], - log: true, - autoMine: true, - }); -}; - -func.tags = ["Implementations"]; - -export default func; diff --git a/deploy/017-update-pool-registry.ts b/deploy/017-update-pool-registry.ts deleted file mode 100644 index 6094667ad..000000000 --- a/deploy/017-update-pool-registry.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { DeployFunction } from "hardhat-deploy/types"; -import { HardhatRuntimeEnvironment } from "hardhat/types"; - -import { getConfig } from "../helpers/deploymentConfig"; -import { toAddress } from "../helpers/deploymentUtils"; - -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployments, getNamedAccounts } = hre; - const { deploy, catchUnknownSigner } = deployments; - const { deployer } = await getNamedAccounts(); - const { preconfiguredAddresses } = await getConfig(hre.getNetworkName()); - const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer"); - const defaultProxyAdmin = await hre.artifacts.readArtifact( - "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", - ); - await catchUnknownSigner( - deploy("PoolRegistry", { - from: deployer, - contract: "PoolRegistry", - proxy: { - owner: proxyOwnerAddress, - proxyContract: "OptimizedTransparentUpgradeableProxy", - viaAdminContract: { - name: "DefaultProxyAdmin", - artifact: defaultProxyAdmin, - }, - }, - autoMine: true, - log: true, - }), - ); -}; - -func.tags = ["update-pool-registry"]; -export default func; From b5e17226cb1b4644735c6ff22d925569b14f2986 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 15:30:44 -0300 Subject: [PATCH 06/11] refactor: check owner before transfering --- deploy/018-native-token-gateway.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/018-native-token-gateway.ts b/deploy/018-native-token-gateway.ts index ae2e34dc0..b5ee80714 100644 --- a/deploy/018-native-token-gateway.ts +++ b/deploy/018-native-token-gateway.ts @@ -133,7 +133,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const nativeTokenGateway = await ethers.getContract(`NativeTokenGateway_${vWNativeInfo.name}`); const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; - if (hre.network.live) { + if (hre.network.live && await nativeTokenGateway.owner() !== targetOwner) { const tx = await nativeTokenGateway.transferOwnership(targetOwner); await tx.wait(); console.log(`Transferred ownership of NativeTokenGateway_${vWNativeInfo.name} to Timelock`); From 0ff1968fb750c99bbdd067653fc8ebdc77cb58e1 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 16:11:11 -0300 Subject: [PATCH 07/11] fix: send to treasury only assets that were minted --- deploy/011-initial-liquidity.ts | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/deploy/011-initial-liquidity.ts b/deploy/011-initial-liquidity.ts index ff8d2cf1d..4fe2c4eff 100644 --- a/deploy/011-initial-liquidity.ts +++ b/deploy/011-initial-liquidity.ts @@ -1,4 +1,5 @@ import { BigNumber } from "ethers"; +import { getNetworkName } from "hardhat"; import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; @@ -20,9 +21,9 @@ const sumAmounts = async (tokens: { symbol: string; amount: BigNumber }[]) => { return amounts; }; -const faucetTokens = async (deploymentConfig: DeploymentConfig, hre: HardhatRuntimeEnvironment) => { +const faucetTokens = async (deploymentConfig: DeploymentConfig) => { const { poolConfig, tokensConfig } = deploymentConfig; - const unregisteredVTokens = await getUnregisteredVTokens(poolConfig, hre); + const unregisteredVTokens = await getUnregisteredVTokens(poolConfig); const vTokenConfigs = unregisteredVTokens.map((p: PoolConfig) => p.vtokens).flat(); const assetsToFaucet = vTokenConfigs .map((v: { asset: string }) => getTokenConfig(v.asset, tokensConfig)) @@ -42,17 +43,17 @@ const faucetTokens = async (deploymentConfig: DeploymentConfig, hre: HardhatRunt const tx = await tokenContract.faucet(amount, { gasLimit: 5000000 }); await tx.wait(1); } + return vTokensToFaucet }; -const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig, hre: HardhatRuntimeEnvironment) => { - if (hre.getNetworkName() == "bscmainnet" || hre.getNetworkName() == "ethereum") { +const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig, tokensToFaucet: VTokenConfig[]) => { + if (getNetworkName() == "bscmainnet" || getNetworkName() == "ethereum") { return; } - const { poolConfig, tokensConfig, preconfiguredAddresses } = deploymentConfig; - const unregisteredVTokens = await getUnregisteredVTokens(poolConfig, hre); - const vTokenConfigs = unregisteredVTokens.map((p: PoolConfig) => p.vtokens).flat(); + + const { tokensConfig, preconfiguredAddresses } = deploymentConfig; - const amounts = vTokenConfigs.map((token: VTokenConfig) => ({ + const amounts = tokensToFaucet.map((token: VTokenConfig) => ({ symbol: token.asset, amount: BigNumber.from(token.initialSupply), })); @@ -60,10 +61,7 @@ const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig for (const [symbol, amount] of Object.entries(totalAmounts)) { const tokenContract = await getUnderlyingToken(symbol, tokensConfig); console.log(`Sending ${amount} ${symbol} to VTreasury`); - console.log(`Token Contract: ${tokenContract.address}`); - console.log(`Token Contract: ${amount.toString()}`); const treasuryAddress = await toAddress(preconfiguredAddresses.VTreasury || "VTreasury"); - console.log(`Token Contract: ${treasuryAddress}`); const tx = await tokenContract.transfer(treasuryAddress, amount, { gasLimit: 5000000 }); await tx.wait(1); @@ -72,8 +70,8 @@ const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const deploymentConfig = await getConfig(hre.getNetworkName()); - await faucetTokens(deploymentConfig, hre); - await sendInitialLiquidityToTreasury(deploymentConfig, hre); + const assetsToFaucet = await faucetTokens(deploymentConfig); + await sendInitialLiquidityToTreasury(deploymentConfig, assetsToFaucet); }; func.tags = ["InitialLiquidity", "il"]; From d922d09c1962d15c4d1214916a5b3eddce8eb482 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 16:19:10 -0300 Subject: [PATCH 08/11] fix: compare lowercase addresses --- deploy/012-transfer-pools-ownership.ts | 50 +++++++++++++------------- deploy/018-native-token-gateway.ts | 2 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/deploy/012-transfer-pools-ownership.ts b/deploy/012-transfer-pools-ownership.ts index 028e9fc60..1a2ca23cc 100644 --- a/deploy/012-transfer-pools-ownership.ts +++ b/deploy/012-transfer-pools-ownership.ts @@ -4,29 +4,6 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"; import { PoolConfig, getConfig } from "../helpers/deploymentConfig"; -const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - const { deployer } = await getNamedAccounts(); - const { poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); - const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; - - const rewardsDistributors = poolConfig - .map((pool: PoolConfig) => { - const rewards = pool.rewards || []; - return rewards.map((_, idx: number) => `RewardsDistributor_${pool.id}_${idx}`); - }) - .flat(); - - const comptrollers = poolConfig.map((pool: PoolConfig) => `Comptroller_${pool.id}`); - - const contracts = { - singleStepOwnership: ["ComptrollerBeacon", "VTokenBeacon"], - twoStepOwnership: ["PoolRegistry", ...comptrollers, ...rewardsDistributors], - }; - - await transferSingleStepOwnerships(contracts.singleStepOwnership, targetOwner); - await transfer2StepOwnerships(contracts.twoStepOwnership, targetOwner); -}; - const transfer2StepOwnerships = async (contractNames: string[], targetOwner: string) => { const abi = [ "function owner() view returns (address)", @@ -40,7 +17,7 @@ const transfer2StepOwnerships = async (contractNames: string[], targetOwner: str const pendingOwner = await contract.pendingOwner(); let tx; - if (owner !== targetOwner && pendingOwner !== targetOwner) { + if (owner.toLowerCase() !== targetOwner.toLowerCase() && pendingOwner.toLowerCase() !== targetOwner.toLowerCase()) { tx = await contract.transferOwnership(targetOwner); await tx.wait(1); const pendingOwner = await contract.pendingOwner(); @@ -59,7 +36,7 @@ const transferSingleStepOwnerships = async (contractNames: string[], targetOwner const owner = await contract.owner(); let tx; - if (owner !== targetOwner) { + if (owner.toLowerCase() !== targetOwner.toLowerCase()) { tx = await contract.transferOwnership(targetOwner); await tx.wait(1); const newOwner = await contract.owner(); @@ -70,6 +47,29 @@ const transferSingleStepOwnerships = async (contractNames: string[], targetOwner } }; +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployer } = await getNamedAccounts(); + const { poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); + const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; + + const rewardsDistributors = poolConfig + .map((pool: PoolConfig) => { + const rewards = pool.rewards || []; + return rewards.map((_, idx: number) => `RewardsDistributor_${pool.id}_${idx}`); + }) + .flat(); + + const comptrollers = poolConfig.map((pool: PoolConfig) => `Comptroller_${pool.id}`); + + const contracts = { + singleStepOwnership: ["ComptrollerBeacon", "VTokenBeacon"], + twoStepOwnership: ["PoolRegistry", ...comptrollers, ...rewardsDistributors], + }; + + await transferSingleStepOwnerships(contracts.singleStepOwnership, targetOwner); + await transfer2StepOwnerships(contracts.twoStepOwnership, targetOwner); +}; + func.tags = ["TransferPoolsOwnership", "il"]; func.id = "transfer_pools_ownership"; // id required to prevent re-execution export default func; diff --git a/deploy/018-native-token-gateway.ts b/deploy/018-native-token-gateway.ts index b5ee80714..aa1c36cb9 100644 --- a/deploy/018-native-token-gateway.ts +++ b/deploy/018-native-token-gateway.ts @@ -133,7 +133,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const nativeTokenGateway = await ethers.getContract(`NativeTokenGateway_${vWNativeInfo.name}`); const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; - if (hre.network.live && await nativeTokenGateway.owner() !== targetOwner) { + if (hre.network.live && (await nativeTokenGateway.owner()).toLowerCase() !== targetOwner.toLowerCase()) { const tx = await nativeTokenGateway.transferOwnership(targetOwner); await tx.wait(); console.log(`Transferred ownership of NativeTokenGateway_${vWNativeInfo.name} to Timelock`); From 2a01c759ad08033beaf2c5bbc8d60899ba255481 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Tue, 24 Sep 2024 17:44:22 -0300 Subject: [PATCH 09/11] chore: :shirt: --- .eslint-tsconfig | 2 +- deploy/001-deploy-mock-tokens.ts | 2 +- deploy/008-deploy-comptrollers.ts | 4 ++-- deploy/009-deploy-vtokens.ts | 2 +- deploy/010-deploy-reward-distributors.ts | 6 ++---- deploy/011-initial-liquidity.ts | 4 ++-- deploy/013-vip-based-config.ts | 23 ++++++----------------- deploy/014-shortfall-protocolshare.ts | 1 - hardhat.config.ts | 22 +++++++++------------- helpers/deploymentUtils.ts | 14 ++++---------- type-extensions.ts | 2 +- 11 files changed, 29 insertions(+), 53 deletions(-) diff --git a/.eslint-tsconfig b/.eslint-tsconfig index f3d56b89b..7cf6ed892 100644 --- a/.eslint-tsconfig +++ b/.eslint-tsconfig @@ -1,4 +1,4 @@ { "extends": "./tsconfig.json", - "include": ["jest.config.js", ".eslintrc.js", "tests", "scenario", "deploy", "docgen-templates", "commitlint.config.js", "./hardhat.config.zksync.ts"] + "include": ["jest.config.js", ".eslintrc.js", "tests", "scenario", "deploy", "docgen-templates", "commitlint.config.js", "./hardhat.config.zksync.ts", "type-extensions.ts"] } diff --git a/deploy/001-deploy-mock-tokens.ts b/deploy/001-deploy-mock-tokens.ts index 3ed63103c..d4ba52349 100644 --- a/deploy/001-deploy-mock-tokens.ts +++ b/deploy/001-deploy-mock-tokens.ts @@ -27,6 +27,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { func.tags = ["MockTokens"]; -func.skip = async hre => hre.network.live +func.skip = async hre => hre.network.live; export default func; diff --git a/deploy/008-deploy-comptrollers.ts b/deploy/008-deploy-comptrollers.ts index 7572afe3f..c16f7c596 100644 --- a/deploy/008-deploy-comptrollers.ts +++ b/deploy/008-deploy-comptrollers.ts @@ -36,10 +36,10 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { skipIfAlreadyDeployed: true, }); - const unregisteredPools = await getUnregisteredPools(poolConfig, hre); + const unregisteredPools = await getUnregisteredPools(poolConfig); for (const pool of unregisteredPools) { const Comptroller = await ethers.getContractFactory("Comptroller"); - + // Deploying a proxy for Comptroller await deploy(`Comptroller_${pool.id}`, { from: deployer, diff --git a/deploy/009-deploy-vtokens.ts b/deploy/009-deploy-vtokens.ts index c83fd6458..72122ac99 100644 --- a/deploy/009-deploy-vtokens.ts +++ b/deploy/009-deploy-vtokens.ts @@ -47,7 +47,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { skipIfAlreadyDeployed: true, }); - const poolsWithUnregisteredVTokens = await getUnregisteredVTokens(poolConfig, hre); + const poolsWithUnregisteredVTokens = await getUnregisteredVTokens(poolConfig); for (const pool of poolsWithUnregisteredVTokens) { const comptrollerProxy = await ethers.getContract(`Comptroller_${pool.id}`); diff --git a/deploy/010-deploy-reward-distributors.ts b/deploy/010-deploy-reward-distributors.ts index ecf5b91db..780681634 100644 --- a/deploy/010-deploy-reward-distributors.ts +++ b/deploy/010-deploy-reward-distributors.ts @@ -18,15 +18,13 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const { tokensConfig, poolConfig, preconfiguredAddresses } = await getConfig(hre.getNetworkName()); const { isTimeBased, blocksPerYear } = getBlockOrTimestampBasedDeploymentInfo(hre.getNetworkName()); - const accessControlAddress = await toAddress( - preconfiguredAddresses.AccessControlManager || "AccessControlManager", - ); + const accessControlAddress = await toAddress(preconfiguredAddresses.AccessControlManager || "AccessControlManager"); const proxyOwnerAddress = await toAddress(preconfiguredAddresses.NormalTimelock || "account:deployer"); const defaultProxyAdmin = await hre.artifacts.readArtifact( "hardhat-deploy/solc_0.8/openzeppelin/proxy/transparent/ProxyAdmin.sol:ProxyAdmin", ); - const pools = await getUnregisteredRewardsDistributors(poolConfig, hre); + const pools = await getUnregisteredRewardsDistributors(poolConfig); await deploy("RewardsDistributorImpl", { contract: "RewardsDistributor", diff --git a/deploy/011-initial-liquidity.ts b/deploy/011-initial-liquidity.ts index 4fe2c4eff..54a509529 100644 --- a/deploy/011-initial-liquidity.ts +++ b/deploy/011-initial-liquidity.ts @@ -43,14 +43,14 @@ const faucetTokens = async (deploymentConfig: DeploymentConfig) => { const tx = await tokenContract.faucet(amount, { gasLimit: 5000000 }); await tx.wait(1); } - return vTokensToFaucet + return vTokensToFaucet; }; const sendInitialLiquidityToTreasury = async (deploymentConfig: DeploymentConfig, tokensToFaucet: VTokenConfig[]) => { if (getNetworkName() == "bscmainnet" || getNetworkName() == "ethereum") { return; } - + const { tokensConfig, preconfiguredAddresses } = deploymentConfig; const amounts = tokensToFaucet.map((token: VTokenConfig) => ({ diff --git a/deploy/013-vip-based-config.ts b/deploy/013-vip-based-config.ts index c38819862..6204d25be 100644 --- a/deploy/013-vip-based-config.ts +++ b/deploy/013-vip-based-config.ts @@ -1,6 +1,6 @@ import { BigNumberish } from "ethers"; import { defaultAbiCoder, parseEther } from "ethers/lib/utils"; -import { ethers, network, deployments } from "hardhat"; +import { deployments, ethers, network } from "hardhat"; import { DeployFunction } from "hardhat-deploy/types"; import { HardhatRuntimeEnvironment } from "hardhat/types"; @@ -97,10 +97,7 @@ const configureRewards = async ( return commands.flat(); }; -const acceptOwnership = async ( - contractName: string, - targetOwner: string, -): Promise => { +const acceptOwnership = async (contractName: string, targetOwner: string): Promise => { if (!network.live) { return []; } @@ -151,10 +148,7 @@ const addPool = (poolRegistry: PoolRegistry, comptroller: Comptroller, pool: Poo }; }; -const addPools = async ( - unregisteredPools: PoolConfig[], - poolsOwner: string, -): Promise => { +const addPools = async (unregisteredPools: PoolConfig[], poolsOwner: string): Promise => { const poolRegistry = await ethers.getContract("PoolRegistry"); const commands = await Promise.all( unregisteredPools.map(async (pool: PoolConfig) => { @@ -173,7 +167,7 @@ const transferInitialLiquidity = async ( vTokenConfig: VTokenConfig, deploymentConfig: DeploymentConfig, ): Promise => { - if (!hre.network.live) { + if (!network.live) { return []; } const { preconfiguredAddresses, tokensConfig } = deploymentConfig; @@ -255,10 +249,7 @@ const setReduceReservesBlockDelta = async ( }; }; -const addMarkets = async ( - unregisteredVTokens: PoolConfig[], - deploymentConfig: DeploymentConfig, -) => { +const addMarkets = async (unregisteredVTokens: PoolConfig[], deploymentConfig: DeploymentConfig) => { const poolRegistry = await ethers.getContract("PoolRegistry"); const poolCommands = await Promise.all( unregisteredVTokens.map(async (pool: PoolConfig) => { @@ -302,9 +293,7 @@ const hasPermission = async ( return accessControl.hasRole(role, caller); }; -const configureAccessControls = async ( - deploymentConfig: DeploymentConfig, -): Promise => { +const configureAccessControls = async (deploymentConfig: DeploymentConfig): Promise => { const { accessControlConfig, preconfiguredAddresses } = deploymentConfig; const accessControlManagerAddress = await toAddress( preconfiguredAddresses.AccessControlManager || "AccessControlManager", diff --git a/deploy/014-shortfall-protocolshare.ts b/deploy/014-shortfall-protocolshare.ts index a44f20145..7abbbdee3 100644 --- a/deploy/014-shortfall-protocolshare.ts +++ b/deploy/014-shortfall-protocolshare.ts @@ -76,5 +76,4 @@ func.skip = async hre => hre.getNetworkName() === "opbnbmainnet" || hre.getNetworkName() === "ethereum"; - export default func; diff --git a/hardhat.config.ts b/hardhat.config.ts index 8a033fbff..3239cd683 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -22,20 +22,18 @@ dotenv.config(); const DEPLOYER_PRIVATE_KEY = process.env.DEPLOYER_PRIVATE_KEY; const getRpcUrl = (networkName: string): string => { - let uri + let uri; if (networkName) { uri = process.env[`ARCHIVE_NODE_${networkName}`]; } if (!uri) { - throw new Error( - `invalid uri or network not supported by node provider : ${uri}` - ); + throw new Error(`invalid uri or network not supported by node provider : ${uri}`); } return uri; -} +}; -extendEnvironment((hre) => { - hre.getNetworkName = () => process.env.HARDHAT_FORK_NETWORK || hre.network.name +extendEnvironment(hre => { + hre.getNetworkName = () => process.env.HARDHAT_FORK_NETWORK || hre.network.name; }); extendConfig((config: HardhatConfig) => { @@ -96,7 +94,7 @@ extendConfig((config: HardhatConfig) => { `node_modules/@venusprotocol/venus-protocol/deployments/${process.env.HARDHAT_FORK_NETWORK}`, `node_modules/@venusprotocol/protocol-reserve/deployments/${process.env.HARDHAT_FORK_NETWORK}`, `node_modules/@venusprotocol/governance-contracts/deployments/${process.env.HARDHAT_FORK_NETWORK}`, - ] + ]; } } }); @@ -257,11 +255,9 @@ const config: HardhatUserConfig = { live: !!process.env.HARDHAT_FORK_NETWORK, forking: process.env.HARDHAT_FORK_NETWORK ? { - url: getRpcUrl(process.env.HARDHAT_FORK_NETWORK), - blockNumber: process.env.HARDHAT_FORK_NUMBER - ? parseInt(process.env.HARDHAT_FORK_NUMBER) - : undefined, - } + url: getRpcUrl(process.env.HARDHAT_FORK_NETWORK), + blockNumber: process.env.HARDHAT_FORK_NUMBER ? parseInt(process.env.HARDHAT_FORK_NUMBER) : undefined, + } : undefined, }, development: { diff --git a/helpers/deploymentUtils.ts b/helpers/deploymentUtils.ts index 3a80ba2bd..e578f25d6 100644 --- a/helpers/deploymentUtils.ts +++ b/helpers/deploymentUtils.ts @@ -1,4 +1,4 @@ -import { ethers, getNamedAccounts, deployments } from "hardhat"; +import { deployments, ethers, getNamedAccounts } from "hardhat"; import { Comptroller, ERC20, MockToken } from "../typechain"; import { @@ -36,9 +36,7 @@ export const getUnderlyingToken = async (assetSymbol: string, tokensConfig: Toke return ethers.getContractAt("@openzeppelin/contracts/token/ERC20/ERC20.sol:ERC20", underlyingAddress); }; -export const getUnregisteredPools = async ( - poolConfig: PoolConfig[], -): Promise => { +export const getUnregisteredPools = async (poolConfig: PoolConfig[]): Promise => { const registry = await ethers.getContract("PoolRegistry"); const registeredPools = (await registry.getAllPools()).map((p: { comptroller: string }) => p.comptroller); const isRegistered = await Promise.all( @@ -54,9 +52,7 @@ export const getUnregisteredPools = async ( return poolConfig.filter((_, idx: number) => !isRegistered[idx]); }; -export const getUnregisteredVTokens = async ( - poolConfig: PoolConfig[], -): Promise => { +export const getUnregisteredVTokens = async (poolConfig: PoolConfig[]): Promise => { const registry = await ethers.getContract("PoolRegistry"); const registeredPools = await registry.getAllPools(); const comptrollers = await Promise.all( @@ -89,9 +85,7 @@ export const getUnregisteredVTokens = async ( ); }; -export const getUnregisteredRewardsDistributors = async ( - poolConfig: PoolConfig[], -): Promise => { +export const getUnregisteredRewardsDistributors = async (poolConfig: PoolConfig[]): Promise => { const registry = await ethers.getContract("PoolRegistry"); const registeredPools = await registry.getAllPools(); const comptrollers = await Promise.all( diff --git a/type-extensions.ts b/type-extensions.ts index 42faf3f64..2fae4ac31 100644 --- a/type-extensions.ts +++ b/type-extensions.ts @@ -6,4 +6,4 @@ declare module "hardhat/types/runtime" { export interface HardhatRuntimeEnvironment { getNetworkName: () => string; } -} \ No newline at end of file +} From e4a1558f003bbc0b7073c8efc7842f732bd21038 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Wed, 16 Oct 2024 13:34:50 -0300 Subject: [PATCH 10/11] docs: udpate readme with forked deployments details --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 48cc9cc89..9b5d1b7d3 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,15 @@ npx hardhat deploy - In the deployment scripts you have added `tags` for example: - `func.tags = ["MockTokens"];` - Once this is done, adding `--tags ",..."` to the deployment command will execute only the scripts containing the tags. +### Dry Run / Forked Deployments +To simulate what contracts would be deployed on a given network the deployment scripts support running on a forked network. To run the deployment scripts on a forked network the `HARDHAT_FORK_NETWORK` env variable needs to be set. + +For example +```bash +HARDHAT_FORK_NETWORK=ethereum npx hardhat deploy +``` + + ### Deployed Contracts Deployed contract abis and addresses are exported in the `deployments` directory. To create a summary export of all contracts deployed to a network run From e1cfa653a01642396f008185d089208281d27161 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Wed, 16 Oct 2024 13:44:54 -0300 Subject: [PATCH 11/11] refactor: remove lowercasing addresses; compare checksummed addresses --- deploy/012-transfer-pools-ownership.ts | 4 ++-- deploy/018-native-token-gateway.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/012-transfer-pools-ownership.ts b/deploy/012-transfer-pools-ownership.ts index 1a2ca23cc..01e97f3d1 100644 --- a/deploy/012-transfer-pools-ownership.ts +++ b/deploy/012-transfer-pools-ownership.ts @@ -17,7 +17,7 @@ const transfer2StepOwnerships = async (contractNames: string[], targetOwner: str const pendingOwner = await contract.pendingOwner(); let tx; - if (owner.toLowerCase() !== targetOwner.toLowerCase() && pendingOwner.toLowerCase() !== targetOwner.toLowerCase()) { + if (owner !== targetOwner && pendingOwner !== targetOwner) { tx = await contract.transferOwnership(targetOwner); await tx.wait(1); const pendingOwner = await contract.pendingOwner(); @@ -36,7 +36,7 @@ const transferSingleStepOwnerships = async (contractNames: string[], targetOwner const owner = await contract.owner(); let tx; - if (owner.toLowerCase() !== targetOwner.toLowerCase()) { + if (owner !== targetOwner) { tx = await contract.transferOwnership(targetOwner); await tx.wait(1); const newOwner = await contract.owner(); diff --git a/deploy/018-native-token-gateway.ts b/deploy/018-native-token-gateway.ts index aa1c36cb9..b56570ff2 100644 --- a/deploy/018-native-token-gateway.ts +++ b/deploy/018-native-token-gateway.ts @@ -133,7 +133,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const nativeTokenGateway = await ethers.getContract(`NativeTokenGateway_${vWNativeInfo.name}`); const targetOwner = preconfiguredAddresses.NormalTimelock || deployer; - if (hre.network.live && (await nativeTokenGateway.owner()).toLowerCase() !== targetOwner.toLowerCase()) { + if (hre.network.live && (await nativeTokenGateway.owner()) !== targetOwner) { const tx = await nativeTokenGateway.transferOwnership(targetOwner); await tx.wait(); console.log(`Transferred ownership of NativeTokenGateway_${vWNativeInfo.name} to Timelock`);