Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add forked deployment #442

Open
wants to merge 11 commits into
base: develop
Choose a base branch
from
2 changes: 1 addition & 1 deletion .eslint-tsconfig
Original file line number Diff line number Diff line change
@@ -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"]
}
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 "<tag_name>,<tag_name>..."` 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
Expand Down
6 changes: 4 additions & 2 deletions deploy/001-deploy-mock-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -27,4 +27,6 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {

func.tags = ["MockTokens"];

func.skip = async hre => hre.network.live;

export default func;
14 changes: 7 additions & 7 deletions deploy/004-swap-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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;
5 changes: 2 additions & 3 deletions deploy/006-deploy-pool-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion deploy/007-deploy-pool-lens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 3 additions & 5 deletions deploy/008-deploy-comptrollers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -37,12 +36,11 @@ 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) {
// 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",
Expand Down
12 changes: 4 additions & 8 deletions deploy/009-deploy-vtokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -48,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}`);

Expand Down Expand Up @@ -81,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",
Expand All @@ -102,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",
Expand All @@ -114,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;
Expand Down
13 changes: 5 additions & 8 deletions deploy/010-deploy-reward-distributors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@ 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 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",
Expand Down
28 changes: 13 additions & 15 deletions deploy/011-initial-liquidity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BigNumber } from "ethers";
import { getNetworkName } from "hardhat";
import { DeployFunction } from "hardhat-deploy/types";
import { HardhatRuntimeEnvironment } from "hardhat/types";

Expand All @@ -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))
Expand All @@ -42,38 +43,35 @@ 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.network.name == "bscmainnet" || hre.network.name == "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 amounts = vTokenConfigs.map((token: VTokenConfig) => ({
const { tokensConfig, preconfiguredAddresses } = deploymentConfig;

const amounts = tokensToFaucet.map((token: VTokenConfig) => ({
symbol: token.asset,
amount: BigNumber.from(token.initialSupply),
}));
const totalAmounts = await sumAmounts(amounts);
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", hre);
console.log(`Token Contract: ${treasuryAddress}`);
const treasuryAddress = await toAddress(preconfiguredAddresses.VTreasury || "VTreasury");

const tx = await tokenContract.transfer(treasuryAddress, amount, { gasLimit: 5000000 });
await tx.wait(1);
}
};

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const deploymentConfig = await getConfig(hre.network.name);
await faucetTokens(deploymentConfig, hre);
await sendInitialLiquidityToTreasury(deploymentConfig, hre);
const deploymentConfig = await getConfig(hre.getNetworkName());
const assetsToFaucet = await faucetTokens(deploymentConfig);
await sendInitialLiquidityToTreasury(deploymentConfig, assetsToFaucet);
};

func.tags = ["InitialLiquidity", "il"];
Expand Down
46 changes: 23 additions & 23 deletions deploy/012-transfer-pools-ownership.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.network.name);
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)",
Expand Down Expand Up @@ -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;
Loading
Loading