Skip to content

Commit

Permalink
Implemented the mainnet deployment scripts (#1072)
Browse files Browse the repository at this point in the history
* Started writing the mainnet configuration

* Added the mainnet deployment scripts

* Update the version

* Changed the name of the registry

* Fixed the deployment flow

* Updated the scripts

* Fixed the registry script
  • Loading branch information
jalextowle authored Jun 27, 2024
1 parent 7d0c8d9 commit fd37a51
Show file tree
Hide file tree
Showing 16 changed files with 328 additions and 8 deletions.
2 changes: 1 addition & 1 deletion contracts/src/internal/HyperdriveCheckpoint.sol
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ abstract contract HyperdriveCheckpoint is
_checkpointRewarder.excessivelySafeCall(
gasleft(),
0, // value of 0
1024, // max copy of 1 kb
0, // max copy of 0 bytes
abi.encodeCall(
IHyperdriveCheckpointRewarder.claimCheckpointReward,
(msg.sender, checkpointTime, isTrader)
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/libraries/Constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma solidity 0.8.20;
address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

/// @dev The version of the contracts.
string constant VERSION = "v1.0.12";
string constant VERSION = "v1.0.13";

/// @dev The number of targets that must be deployed for a full deployment.
uint256 constant NUM_TARGETS = 4;
Expand Down
40 changes: 40 additions & 0 deletions hardhat.config.mainnet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import "@nomicfoundation/hardhat-foundry";
import "@nomicfoundation/hardhat-toolbox-viem";
import "@nomicfoundation/hardhat-viem";
import "dotenv/config";
import "hardhat-deploy";
import { HardhatUserConfig } from "hardhat/config";
import baseConfig from "./hardhat.config";
import "./tasks";
import {
MAINNET_DAI_182DAY,
MAINNET_ERC4626_COORDINATOR,
MAINNET_FACTORY,
MAINNET_STETH_182DAY,
MAINNET_STETH_COORDINATOR,
} from "./tasks/deploy/config/mainnet";

const { env } = process;

const config: HardhatUserConfig = {
...baseConfig,
networks: {
mainnet: {
live: true,
url: env.HYPERDRIVE_ETHEREUM_URL!,
accounts: [env.DEPLOYER_PRIVATE_KEY!, env.PAUSER_PRIVATE_KEY!],
hyperdriveDeploy: {
factories: [MAINNET_FACTORY],
coordinators: [
MAINNET_ERC4626_COORDINATOR,
MAINNET_STETH_COORDINATOR,
],
instances: [MAINNET_DAI_182DAY, MAINNET_STETH_182DAY],
checkpointRewarders: [],
checkpointSubrewarders: [],
},
},
},
};

export default config;
3 changes: 3 additions & 0 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ const config: HardhatUserConfig = {
deployer: {
default: 0,
},
pauser: {
default: 1,
},
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY ?? "",
Expand Down
3 changes: 2 additions & 1 deletion tasks/deploy/config/anvil/checkpoint-subrewarder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export const ANVIL_CHECKPOINT_SUBREWARDER: HyperdriveCheckpointSubrewarderConfig
hre.hyperdriveDeploy.deployments.byName("CHECKPOINT_REWARDER")
.address,
"0xd94a3A0BfC798b98a700a785D5C610E8a2d5DBD8",
hre.hyperdriveDeploy.deployments.byName("ANVIL_REGISTRY").address,
hre.hyperdriveDeploy.deployments.byName("DELV Hyperdrive Registry")
.address,
hre.hyperdriveDeploy.deployments.byName("BASE_TOKEN").address,
parseEther("1"),
parseEther("1"),
Expand Down
84 changes: 84 additions & 0 deletions tasks/deploy/config/mainnet/dai-182day.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Address, keccak256, parseEther, toBytes, zeroAddress } from "viem";
import {
HyperdriveInstanceConfig,
getLinkerDetails,
normalizeFee,
parseDuration,
toBytes32,
} from "../../lib";
import {
MAINNET_DAI_ADDRESS,
MAINNET_SDAI_ADDRESS,
SIX_MONTHS,
} from "../../lib/constants";
import { MAINNET_ERC4626_COORDINATOR_NAME } from "./erc4626-coordinator";
import { MAINNET_FACTORY_NAME } from "./factory";

// The name of the pool.
export const MAINNET_DAI_182DAY_NAME = "ElementDAO 182 Day sDAI Hyperdrive";

// The initial contribution of the pool.
const CONTRIBUTION = parseEther("100");

export const MAINNET_DAI_182DAY: HyperdriveInstanceConfig<"ERC4626"> = {
name: MAINNET_DAI_182DAY_NAME,
prefix: "ERC4626",
coordinatorAddress: async (hre) =>
hre.hyperdriveDeploy.deployments.byName(
MAINNET_ERC4626_COORDINATOR_NAME,
).address,
deploymentId: keccak256(toBytes(MAINNET_DAI_182DAY_NAME)),
salt: toBytes32("0x69420"),
extraData: "0x",
contribution: CONTRIBUTION,
fixedAPR: parseEther("0.08"),
timestretchAPR: parseEther("0.05"),
options: async (hre) => ({
extraData: "0x",
asBase: true,
destination: (await hre.getNamedAccounts())["deployer"] as Address,
}),
// Prepare to deploy the contract by setting approvals.
prepare: async (hre) => {
let baseToken = await hre.viem.getContractAt(
"contracts/src/interfaces/IERC20.sol:IERC20",
MAINNET_DAI_ADDRESS,
);
let tx = await baseToken.write.approve([
hre.hyperdriveDeploy.deployments.byName(
MAINNET_ERC4626_COORDINATOR_NAME,
).address,
CONTRIBUTION,
]);
let pc = await hre.viem.getPublicClient();
await pc.waitForTransactionReceipt({ hash: tx });
},
poolDeployConfig: async (hre) => {
return {
baseToken: MAINNET_DAI_ADDRESS,
vaultSharesToken: MAINNET_SDAI_ADDRESS,
circuitBreakerDelta: parseEther("0.05"),
minimumShareReserves: parseEther("10"),
minimumTransactionAmount: parseEther("0.001"),
positionDuration: parseDuration(SIX_MONTHS),
checkpointDuration: parseDuration("1 day"),
timeStretch: 0n,
// TODO: Read from the factory.
governance: (await hre.getNamedAccounts())["deployer"] as Address,
feeCollector: zeroAddress,
sweepCollector: zeroAddress,
checkpointRewarder: zeroAddress,
...(await getLinkerDetails(
hre,
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME)
.address,
)),
fees: {
curve: parseEther("0.01"),
flat: normalizeFee(parseEther("0.0005"), SIX_MONTHS),
governanceLP: parseEther("0.15"),
governanceZombie: parseEther("0.03"),
},
};
},
};
14 changes: 14 additions & 0 deletions tasks/deploy/config/mainnet/erc4626-coordinator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { HyperdriveCoordinatorConfig } from "../../lib";
import { MAINNET_FACTORY_NAME } from "./factory";

export const MAINNET_ERC4626_COORDINATOR_NAME =
"ElementDAO ERC4626 Hyperdrive Deployer Coordinator";
export const MAINNET_ERC4626_COORDINATOR: HyperdriveCoordinatorConfig<"ERC4626"> =
{
name: MAINNET_ERC4626_COORDINATOR_NAME,
prefix: "ERC4626",
targetCount: 4,
factoryAddress: async (hre) =>
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME)
.address,
};
74 changes: 74 additions & 0 deletions tasks/deploy/config/mainnet/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Address, parseEther, zeroAddress } from "viem";
import { HyperdriveFactoryConfig, parseDuration } from "../../lib";

// The name of the factory.
export const MAINNET_FACTORY_NAME = "ElementDAO Hyperdrive Factory";

// The name of the forwarder factory.
export const MAINNET_FACTORY_FORWARDER_NAME =
"ElementDAO ERC20 Factory Forwarder";

export const MAINNET_FACTORY: HyperdriveFactoryConfig = {
name: MAINNET_FACTORY_NAME,
prepare: async (hre, options) => {
await hre.hyperdriveDeploy.ensureDeployed(
MAINNET_FACTORY_FORWARDER_NAME,
"ERC20ForwarderFactory",
[MAINNET_FACTORY_FORWARDER_NAME],
options,
);
},
constructorArguments: async (hre) => [
{
governance: (await hre.getNamedAccounts())["deployer"] as Address,
deployerCoordinatorManager: (await hre.getNamedAccounts())[
"deployer"
] as Address,
hyperdriveGovernance: (await hre.getNamedAccounts())[
"deployer"
] as Address,
defaultPausers: [
(await hre.getNamedAccounts())["deployer"] as Address,
(await hre.getNamedAccounts())["pauser"] as Address,
],
feeCollector: zeroAddress,
sweepCollector: zeroAddress,
checkpointRewarder: zeroAddress,
checkpointDurationResolution: parseDuration("1 hours"),
minCheckpointDuration: parseDuration("24 hours"),
maxCheckpointDuration: parseDuration("24 hours"),
minPositionDuration: parseDuration("7 days"),
maxPositionDuration: parseDuration("730 days"),
minFixedAPR: parseEther("0.005"),
maxFixedAPR: parseEther("0.1"),
minTimeStretchAPR: parseEther("0.005"),
maxTimeStretchAPR: parseEther("0.1"),
minCircuitBreakerDelta: parseEther("0.01"),
maxCircuitBreakerDelta: parseEther("0.2"),
minFees: {
curve: parseEther("0.001"),
flat: parseEther("0.0001"),
governanceLP: parseEther("0.15"),
governanceZombie: parseEther("0.03"),
},
maxFees: {
curve: parseEther("0.05"),
flat: parseEther("0.005"),
governanceLP: parseEther("0.15"),
governanceZombie: parseEther("0.03"),
},
linkerFactory: hre.hyperdriveDeploy.deployments.byName(
MAINNET_FACTORY_FORWARDER_NAME,
).address,
linkerCodeHash: await (
await hre.viem.getContractAt(
"ERC20ForwarderFactory",
hre.hyperdriveDeploy.deployments.byName(
MAINNET_FACTORY_FORWARDER_NAME,
).address,
)
).read.ERC20LINK_HASH(),
},
MAINNET_FACTORY_NAME,
],
};
5 changes: 5 additions & 0 deletions tasks/deploy/config/mainnet/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./dai-182day";
export * from "./erc4626-coordinator";
export * from "./factory";
export * from "./steth-182day";
export * from "./steth-coordinator";
80 changes: 80 additions & 0 deletions tasks/deploy/config/mainnet/steth-182day.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Address, keccak256, parseEther, toBytes, zeroAddress } from "viem";
import {
ETH_ADDRESS,
HyperdriveInstanceConfig,
MAINNET_STETH_ADDRESS,
SIX_MONTHS,
getLinkerDetails,
normalizeFee,
parseDuration,
toBytes32,
} from "../../lib";
import { MAINNET_FACTORY_NAME } from "./factory";
import { MAINNET_STETH_COORDINATOR_NAME } from "./steth-coordinator";

// The name of the pool.
export const MAINNET_STETH_182DAY_NAME = "ElementDAO 182 Day stETH Hyperdrive";

// The initial contribution of the pool.
const CONTRIBUTION = parseEther("0.01");

export const MAINNET_STETH_182DAY: HyperdriveInstanceConfig<"StETH"> = {
name: MAINNET_STETH_182DAY_NAME,
prefix: "StETH",
coordinatorAddress: async (hre) =>
hre.hyperdriveDeploy.deployments.byName(MAINNET_STETH_COORDINATOR_NAME)
.address,
deploymentId: keccak256(toBytes(MAINNET_STETH_182DAY_NAME)),
salt: toBytes32("0xababe"),
extraData: "0x",
contribution: CONTRIBUTION,
fixedAPR: parseEther("0.0314"),
timestretchAPR: parseEther("0.035"),
options: async (hre) => ({
asBase: false,
extraData: "0x",
destination: (await hre.getNamedAccounts())["deployer"] as Address,
}),
prepare: async (hre) => {
// approve the coordinator
let vaultSharesToken = await hre.viem.getContractAt(
"ILido",
MAINNET_STETH_ADDRESS,
);
let pc = await hre.viem.getPublicClient();
let tx = await vaultSharesToken.write.approve([
hre.hyperdriveDeploy.deployments.byName(
MAINNET_STETH_COORDINATOR_NAME,
).address,
await vaultSharesToken.read.getPooledEthByShares([CONTRIBUTION]),
]);
await pc.waitForTransactionReceipt({ hash: tx });
},
poolDeployConfig: async (hre) => {
return {
baseToken: ETH_ADDRESS,
vaultSharesToken: MAINNET_STETH_ADDRESS,
circuitBreakerDelta: parseEther("0.035"),
minimumShareReserves: parseEther("0.001"),
minimumTransactionAmount: parseEther("0.001"),
positionDuration: parseDuration(SIX_MONTHS),
checkpointDuration: parseDuration("1 day"),
timeStretch: 0n,
governance: (await hre.getNamedAccounts())["deployer"] as Address,
feeCollector: zeroAddress,
sweepCollector: zeroAddress,
checkpointRewarder: zeroAddress,
...(await getLinkerDetails(
hre,
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME)
.address,
)),
fees: {
curve: parseEther("0.01"),
flat: normalizeFee(parseEther("0.0005"), SIX_MONTHS),
governanceLP: parseEther("0.15"),
governanceZombie: parseEther("0.03"),
},
};
},
};
13 changes: 13 additions & 0 deletions tasks/deploy/config/mainnet/steth-coordinator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { HyperdriveCoordinatorConfig, MAINNET_STETH_ADDRESS } from "../../lib";
import { MAINNET_FACTORY_NAME } from "./factory";

export const MAINNET_STETH_COORDINATOR_NAME =
"ElementDAO stETH Hyperdrive Deployer Coordinator";
export const MAINNET_STETH_COORDINATOR: HyperdriveCoordinatorConfig<"StETH"> = {
name: MAINNET_STETH_COORDINATOR_NAME,
prefix: "StETH",
factoryAddress: async (hre) =>
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME).address,
targetCount: 4,
token: MAINNET_STETH_ADDRESS,
};
3 changes: 2 additions & 1 deletion tasks/deploy/hyperdrive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ HyperdriveDeployBaseTask(

// deploy the registry
await run("deploy:registry", {
name: `${network.name.toUpperCase()}_REGISTRY`,
// TODO: Generalize this.
name: "DELV Hyperdrive Registry",
...rest,
});

Expand Down
5 changes: 5 additions & 0 deletions tasks/deploy/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { Address } from "viem";

export const ETH_ADDRESS =
"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" as Address;

export const MAINNET_DAI_ADDRESS =
"0x6b175474e89094c44da98b954eedeac495271d0f" as Address;

Expand All @@ -23,3 +26,5 @@ export const MAINNET_STETH_WHALE =

export const MAINNET_RETH_WHALE =
"0x1bee69b7dfffa4e2d53c2a2df135c388ad25dcd2" as Address;

export const SIX_MONTHS = "182 days";
4 changes: 2 additions & 2 deletions tasks/deploy/lib/environment-extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "hardhat/types/runtime";
import { ConfigurableTaskDefinition } from "hardhat/types/runtime";
import { Address, ContractConstructorArgs, isHex } from "viem";
import { Deployments } from "./deployments";
import { evaluateValueOrHREFn, toBytes32 } from "./utils";
import { evaluateValueOrHREFn } from "./utils";

/**
* Options accepted by all Hyperdrive deploy tasks
Expand Down Expand Up @@ -403,7 +403,7 @@ extendEnvironment((hre) => {

// Deploy the coordinator
let args = [
toBytes32(coordinatorConfig.name),
coordinatorConfig.name,
factoryAddress,
coreDeployer.address,
...targets,
Expand Down
Loading

0 comments on commit fd37a51

Please sign in to comment.