Skip to content

Commit e84bb23

Browse files
authored
Implemented the mainnet deployment scripts (#1072)
* 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
1 parent 7d0c8d9 commit e84bb23

File tree

16 files changed

+328
-8
lines changed

16 files changed

+328
-8
lines changed

contracts/src/internal/HyperdriveCheckpoint.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ abstract contract HyperdriveCheckpoint is
330330
_checkpointRewarder.excessivelySafeCall(
331331
gasleft(),
332332
0, // value of 0
333-
1024, // max copy of 1 kb
333+
0, // max copy of 0 bytes
334334
abi.encodeCall(
335335
IHyperdriveCheckpointRewarder.claimCheckpointReward,
336336
(msg.sender, checkpointTime, isTrader)

contracts/src/libraries/Constants.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pragma solidity 0.8.20;
55
address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
66

77
/// @dev The version of the contracts.
8-
string constant VERSION = "v1.0.12";
8+
string constant VERSION = "v1.0.13";
99

1010
/// @dev The number of targets that must be deployed for a full deployment.
1111
uint256 constant NUM_TARGETS = 4;

hardhat.config.mainnet.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import "@nomicfoundation/hardhat-foundry";
2+
import "@nomicfoundation/hardhat-toolbox-viem";
3+
import "@nomicfoundation/hardhat-viem";
4+
import "dotenv/config";
5+
import "hardhat-deploy";
6+
import { HardhatUserConfig } from "hardhat/config";
7+
import baseConfig from "./hardhat.config";
8+
import "./tasks";
9+
import {
10+
MAINNET_DAI_182DAY,
11+
MAINNET_ERC4626_COORDINATOR,
12+
MAINNET_FACTORY,
13+
MAINNET_STETH_182DAY,
14+
MAINNET_STETH_COORDINATOR,
15+
} from "./tasks/deploy/config/mainnet";
16+
17+
const { env } = process;
18+
19+
const config: HardhatUserConfig = {
20+
...baseConfig,
21+
networks: {
22+
mainnet: {
23+
live: true,
24+
url: env.HYPERDRIVE_ETHEREUM_URL!,
25+
accounts: [env.DEPLOYER_PRIVATE_KEY!, env.PAUSER_PRIVATE_KEY!],
26+
hyperdriveDeploy: {
27+
factories: [MAINNET_FACTORY],
28+
coordinators: [
29+
MAINNET_ERC4626_COORDINATOR,
30+
MAINNET_STETH_COORDINATOR,
31+
],
32+
instances: [MAINNET_DAI_182DAY, MAINNET_STETH_182DAY],
33+
checkpointRewarders: [],
34+
checkpointSubrewarders: [],
35+
},
36+
},
37+
},
38+
};
39+
40+
export default config;

hardhat.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ const config: HardhatUserConfig = {
4646
deployer: {
4747
default: 0,
4848
},
49+
pauser: {
50+
default: 1,
51+
},
4952
},
5053
etherscan: {
5154
apiKey: process.env.ETHERSCAN_API_KEY ?? "",

tasks/deploy/config/anvil/checkpoint-subrewarder.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ export const ANVIL_CHECKPOINT_SUBREWARDER: HyperdriveCheckpointSubrewarderConfig
2929
hre.hyperdriveDeploy.deployments.byName("CHECKPOINT_REWARDER")
3030
.address,
3131
"0xd94a3A0BfC798b98a700a785D5C610E8a2d5DBD8",
32-
hre.hyperdriveDeploy.deployments.byName("ANVIL_REGISTRY").address,
32+
hre.hyperdriveDeploy.deployments.byName("DELV Hyperdrive Registry")
33+
.address,
3334
hre.hyperdriveDeploy.deployments.byName("BASE_TOKEN").address,
3435
parseEther("1"),
3536
parseEther("1"),
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { Address, keccak256, parseEther, toBytes, zeroAddress } from "viem";
2+
import {
3+
HyperdriveInstanceConfig,
4+
getLinkerDetails,
5+
normalizeFee,
6+
parseDuration,
7+
toBytes32,
8+
} from "../../lib";
9+
import {
10+
MAINNET_DAI_ADDRESS,
11+
MAINNET_SDAI_ADDRESS,
12+
SIX_MONTHS,
13+
} from "../../lib/constants";
14+
import { MAINNET_ERC4626_COORDINATOR_NAME } from "./erc4626-coordinator";
15+
import { MAINNET_FACTORY_NAME } from "./factory";
16+
17+
// The name of the pool.
18+
export const MAINNET_DAI_182DAY_NAME = "ElementDAO 182 Day sDAI Hyperdrive";
19+
20+
// The initial contribution of the pool.
21+
const CONTRIBUTION = parseEther("100");
22+
23+
export const MAINNET_DAI_182DAY: HyperdriveInstanceConfig<"ERC4626"> = {
24+
name: MAINNET_DAI_182DAY_NAME,
25+
prefix: "ERC4626",
26+
coordinatorAddress: async (hre) =>
27+
hre.hyperdriveDeploy.deployments.byName(
28+
MAINNET_ERC4626_COORDINATOR_NAME,
29+
).address,
30+
deploymentId: keccak256(toBytes(MAINNET_DAI_182DAY_NAME)),
31+
salt: toBytes32("0x69420"),
32+
extraData: "0x",
33+
contribution: CONTRIBUTION,
34+
fixedAPR: parseEther("0.08"),
35+
timestretchAPR: parseEther("0.05"),
36+
options: async (hre) => ({
37+
extraData: "0x",
38+
asBase: true,
39+
destination: (await hre.getNamedAccounts())["deployer"] as Address,
40+
}),
41+
// Prepare to deploy the contract by setting approvals.
42+
prepare: async (hre) => {
43+
let baseToken = await hre.viem.getContractAt(
44+
"contracts/src/interfaces/IERC20.sol:IERC20",
45+
MAINNET_DAI_ADDRESS,
46+
);
47+
let tx = await baseToken.write.approve([
48+
hre.hyperdriveDeploy.deployments.byName(
49+
MAINNET_ERC4626_COORDINATOR_NAME,
50+
).address,
51+
CONTRIBUTION,
52+
]);
53+
let pc = await hre.viem.getPublicClient();
54+
await pc.waitForTransactionReceipt({ hash: tx });
55+
},
56+
poolDeployConfig: async (hre) => {
57+
return {
58+
baseToken: MAINNET_DAI_ADDRESS,
59+
vaultSharesToken: MAINNET_SDAI_ADDRESS,
60+
circuitBreakerDelta: parseEther("0.05"),
61+
minimumShareReserves: parseEther("10"),
62+
minimumTransactionAmount: parseEther("0.001"),
63+
positionDuration: parseDuration(SIX_MONTHS),
64+
checkpointDuration: parseDuration("1 day"),
65+
timeStretch: 0n,
66+
// TODO: Read from the factory.
67+
governance: (await hre.getNamedAccounts())["deployer"] as Address,
68+
feeCollector: zeroAddress,
69+
sweepCollector: zeroAddress,
70+
checkpointRewarder: zeroAddress,
71+
...(await getLinkerDetails(
72+
hre,
73+
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME)
74+
.address,
75+
)),
76+
fees: {
77+
curve: parseEther("0.01"),
78+
flat: normalizeFee(parseEther("0.0005"), SIX_MONTHS),
79+
governanceLP: parseEther("0.15"),
80+
governanceZombie: parseEther("0.03"),
81+
},
82+
};
83+
},
84+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { HyperdriveCoordinatorConfig } from "../../lib";
2+
import { MAINNET_FACTORY_NAME } from "./factory";
3+
4+
export const MAINNET_ERC4626_COORDINATOR_NAME =
5+
"ElementDAO ERC4626 Hyperdrive Deployer Coordinator";
6+
export const MAINNET_ERC4626_COORDINATOR: HyperdriveCoordinatorConfig<"ERC4626"> =
7+
{
8+
name: MAINNET_ERC4626_COORDINATOR_NAME,
9+
prefix: "ERC4626",
10+
targetCount: 4,
11+
factoryAddress: async (hre) =>
12+
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME)
13+
.address,
14+
};
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { Address, parseEther, zeroAddress } from "viem";
2+
import { HyperdriveFactoryConfig, parseDuration } from "../../lib";
3+
4+
// The name of the factory.
5+
export const MAINNET_FACTORY_NAME = "ElementDAO Hyperdrive Factory";
6+
7+
// The name of the forwarder factory.
8+
export const MAINNET_FACTORY_FORWARDER_NAME =
9+
"ElementDAO ERC20 Factory Forwarder";
10+
11+
export const MAINNET_FACTORY: HyperdriveFactoryConfig = {
12+
name: MAINNET_FACTORY_NAME,
13+
prepare: async (hre, options) => {
14+
await hre.hyperdriveDeploy.ensureDeployed(
15+
MAINNET_FACTORY_FORWARDER_NAME,
16+
"ERC20ForwarderFactory",
17+
[MAINNET_FACTORY_FORWARDER_NAME],
18+
options,
19+
);
20+
},
21+
constructorArguments: async (hre) => [
22+
{
23+
governance: (await hre.getNamedAccounts())["deployer"] as Address,
24+
deployerCoordinatorManager: (await hre.getNamedAccounts())[
25+
"deployer"
26+
] as Address,
27+
hyperdriveGovernance: (await hre.getNamedAccounts())[
28+
"deployer"
29+
] as Address,
30+
defaultPausers: [
31+
(await hre.getNamedAccounts())["deployer"] as Address,
32+
(await hre.getNamedAccounts())["pauser"] as Address,
33+
],
34+
feeCollector: zeroAddress,
35+
sweepCollector: zeroAddress,
36+
checkpointRewarder: zeroAddress,
37+
checkpointDurationResolution: parseDuration("1 hours"),
38+
minCheckpointDuration: parseDuration("24 hours"),
39+
maxCheckpointDuration: parseDuration("24 hours"),
40+
minPositionDuration: parseDuration("7 days"),
41+
maxPositionDuration: parseDuration("730 days"),
42+
minFixedAPR: parseEther("0.005"),
43+
maxFixedAPR: parseEther("0.1"),
44+
minTimeStretchAPR: parseEther("0.005"),
45+
maxTimeStretchAPR: parseEther("0.1"),
46+
minCircuitBreakerDelta: parseEther("0.01"),
47+
maxCircuitBreakerDelta: parseEther("0.2"),
48+
minFees: {
49+
curve: parseEther("0.001"),
50+
flat: parseEther("0.0001"),
51+
governanceLP: parseEther("0.15"),
52+
governanceZombie: parseEther("0.03"),
53+
},
54+
maxFees: {
55+
curve: parseEther("0.05"),
56+
flat: parseEther("0.005"),
57+
governanceLP: parseEther("0.15"),
58+
governanceZombie: parseEther("0.03"),
59+
},
60+
linkerFactory: hre.hyperdriveDeploy.deployments.byName(
61+
MAINNET_FACTORY_FORWARDER_NAME,
62+
).address,
63+
linkerCodeHash: await (
64+
await hre.viem.getContractAt(
65+
"ERC20ForwarderFactory",
66+
hre.hyperdriveDeploy.deployments.byName(
67+
MAINNET_FACTORY_FORWARDER_NAME,
68+
).address,
69+
)
70+
).read.ERC20LINK_HASH(),
71+
},
72+
MAINNET_FACTORY_NAME,
73+
],
74+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from "./dai-182day";
2+
export * from "./erc4626-coordinator";
3+
export * from "./factory";
4+
export * from "./steth-182day";
5+
export * from "./steth-coordinator";
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import { Address, keccak256, parseEther, toBytes, zeroAddress } from "viem";
2+
import {
3+
ETH_ADDRESS,
4+
HyperdriveInstanceConfig,
5+
MAINNET_STETH_ADDRESS,
6+
SIX_MONTHS,
7+
getLinkerDetails,
8+
normalizeFee,
9+
parseDuration,
10+
toBytes32,
11+
} from "../../lib";
12+
import { MAINNET_FACTORY_NAME } from "./factory";
13+
import { MAINNET_STETH_COORDINATOR_NAME } from "./steth-coordinator";
14+
15+
// The name of the pool.
16+
export const MAINNET_STETH_182DAY_NAME = "ElementDAO 182 Day stETH Hyperdrive";
17+
18+
// The initial contribution of the pool.
19+
const CONTRIBUTION = parseEther("0.01");
20+
21+
export const MAINNET_STETH_182DAY: HyperdriveInstanceConfig<"StETH"> = {
22+
name: MAINNET_STETH_182DAY_NAME,
23+
prefix: "StETH",
24+
coordinatorAddress: async (hre) =>
25+
hre.hyperdriveDeploy.deployments.byName(MAINNET_STETH_COORDINATOR_NAME)
26+
.address,
27+
deploymentId: keccak256(toBytes(MAINNET_STETH_182DAY_NAME)),
28+
salt: toBytes32("0xababe"),
29+
extraData: "0x",
30+
contribution: CONTRIBUTION,
31+
fixedAPR: parseEther("0.0314"),
32+
timestretchAPR: parseEther("0.035"),
33+
options: async (hre) => ({
34+
asBase: false,
35+
extraData: "0x",
36+
destination: (await hre.getNamedAccounts())["deployer"] as Address,
37+
}),
38+
prepare: async (hre) => {
39+
// approve the coordinator
40+
let vaultSharesToken = await hre.viem.getContractAt(
41+
"ILido",
42+
MAINNET_STETH_ADDRESS,
43+
);
44+
let pc = await hre.viem.getPublicClient();
45+
let tx = await vaultSharesToken.write.approve([
46+
hre.hyperdriveDeploy.deployments.byName(
47+
MAINNET_STETH_COORDINATOR_NAME,
48+
).address,
49+
await vaultSharesToken.read.getPooledEthByShares([CONTRIBUTION]),
50+
]);
51+
await pc.waitForTransactionReceipt({ hash: tx });
52+
},
53+
poolDeployConfig: async (hre) => {
54+
return {
55+
baseToken: ETH_ADDRESS,
56+
vaultSharesToken: MAINNET_STETH_ADDRESS,
57+
circuitBreakerDelta: parseEther("0.035"),
58+
minimumShareReserves: parseEther("0.001"),
59+
minimumTransactionAmount: parseEther("0.001"),
60+
positionDuration: parseDuration(SIX_MONTHS),
61+
checkpointDuration: parseDuration("1 day"),
62+
timeStretch: 0n,
63+
governance: (await hre.getNamedAccounts())["deployer"] as Address,
64+
feeCollector: zeroAddress,
65+
sweepCollector: zeroAddress,
66+
checkpointRewarder: zeroAddress,
67+
...(await getLinkerDetails(
68+
hre,
69+
hre.hyperdriveDeploy.deployments.byName(MAINNET_FACTORY_NAME)
70+
.address,
71+
)),
72+
fees: {
73+
curve: parseEther("0.01"),
74+
flat: normalizeFee(parseEther("0.0005"), SIX_MONTHS),
75+
governanceLP: parseEther("0.15"),
76+
governanceZombie: parseEther("0.03"),
77+
},
78+
};
79+
},
80+
};

0 commit comments

Comments
 (0)