From 5cb1c512e4f96faa8f4f7feb1159a144a4627719 Mon Sep 17 00:00:00 2001 From: "John McClure (pickleback)" Date: Mon, 26 Aug 2024 18:22:48 -0500 Subject: [PATCH 1/5] add deployment config for gnosis wsteth sxdai --- hardhat.config.gnosis.ts | 43 ++++++++ hardhat.config.ts | 2 +- .../config/gnosis/chainlink-coordinator.ts | 14 +++ .../config/gnosis/erc4626-coordinator.ts | 14 +++ tasks/deploy/config/gnosis/factory.ts | 74 ++++++++++++++ tasks/deploy/config/gnosis/index.ts | 5 + tasks/deploy/config/gnosis/sxdai-182day.ts | 83 ++++++++++++++++ tasks/deploy/config/gnosis/wsteth-182day.ts | 98 +++++++++++++++++++ tasks/deploy/lib/constants.ts | 26 +++++ 9 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 hardhat.config.gnosis.ts create mode 100644 tasks/deploy/config/gnosis/chainlink-coordinator.ts create mode 100644 tasks/deploy/config/gnosis/erc4626-coordinator.ts create mode 100644 tasks/deploy/config/gnosis/factory.ts create mode 100644 tasks/deploy/config/gnosis/index.ts create mode 100644 tasks/deploy/config/gnosis/sxdai-182day.ts create mode 100644 tasks/deploy/config/gnosis/wsteth-182day.ts diff --git a/hardhat.config.gnosis.ts b/hardhat.config.gnosis.ts new file mode 100644 index 000000000..c866df053 --- /dev/null +++ b/hardhat.config.gnosis.ts @@ -0,0 +1,43 @@ +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 { + GNOSIS_CHAINLINK_COORDINATOR, + GNOSIS_ERC4626_COORDINATOR, + GNOSIS_FACTORY, + GNOSIS_SXDAI_182DAY, + GNOSIS_WSTETH_182DAY, +} from "./tasks/deploy/config/gnosis"; + +const { env } = process; + +const config: HardhatUserConfig = { + ...baseConfig, + networks: { + gnosis: { + live: true, + url: env.HYPERDRIVE_ETHEREUM_URL!, + accounts: [env.DEPLOYER_PRIVATE_KEY!, env.PAUSER_PRIVATE_KEY!], + hyperdriveDeploy: { + factories: [GNOSIS_FACTORY], + coordinators: [ + GNOSIS_CHAINLINK_COORDINATOR, + GNOSIS_ERC4626_COORDINATOR, + ], + instances: [GNOSIS_WSTETH_182DAY, GNOSIS_SXDAI_182DAY], + checkpointRewarders: [], + checkpointSubrewarders: [], + }, + }, + }, + etherscan: { + apiKey: env.GNOSISSCAN_API_KEY ?? "", + }, +}; + +export default config; diff --git a/hardhat.config.ts b/hardhat.config.ts index 8bfac322e..9eed3b6b9 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -13,7 +13,7 @@ const config: HardhatUserConfig = { viaIR: false, optimizer: { enabled: true, - runs: 10000000, + runs: 13000, }, evmVersion: "paris", metadata: { diff --git a/tasks/deploy/config/gnosis/chainlink-coordinator.ts b/tasks/deploy/config/gnosis/chainlink-coordinator.ts new file mode 100644 index 000000000..ad8fd1258 --- /dev/null +++ b/tasks/deploy/config/gnosis/chainlink-coordinator.ts @@ -0,0 +1,14 @@ +import { HyperdriveCoordinatorConfig } from "../../lib"; +import { GNOSIS_FACTORY_NAME } from "./factory"; + +export const GNOSIS_CHAINLINK_COORDINATOR_NAME = + "ElementDAO Chainlink Hyperdrive Deployer Coordinator"; +export const GNOSIS_CHAINLINK_COORDINATOR: HyperdriveCoordinatorConfig<"Chainlink"> = + { + name: GNOSIS_CHAINLINK_COORDINATOR_NAME, + prefix: "Chainlink", + targetCount: 5, + factoryAddress: async (hre) => + hre.hyperdriveDeploy.deployments.byName(GNOSIS_FACTORY_NAME) + .address, + }; diff --git a/tasks/deploy/config/gnosis/erc4626-coordinator.ts b/tasks/deploy/config/gnosis/erc4626-coordinator.ts new file mode 100644 index 000000000..526d24688 --- /dev/null +++ b/tasks/deploy/config/gnosis/erc4626-coordinator.ts @@ -0,0 +1,14 @@ +import { HyperdriveCoordinatorConfig } from "../../lib"; +import { GNOSIS_FACTORY_NAME } from "./factory"; + +export const GNOSIS_ERC4626_COORDINATOR_NAME = + "ElementDAO ERC4626 Hyperdrive Deployer Coordinator"; +export const GNOSIS_ERC4626_COORDINATOR: HyperdriveCoordinatorConfig<"ERC4626"> = + { + name: GNOSIS_ERC4626_COORDINATOR_NAME, + prefix: "ERC4626", + targetCount: 5, + factoryAddress: async (hre) => + hre.hyperdriveDeploy.deployments.byName(GNOSIS_FACTORY_NAME) + .address, + }; diff --git a/tasks/deploy/config/gnosis/factory.ts b/tasks/deploy/config/gnosis/factory.ts new file mode 100644 index 000000000..ddbba0bcc --- /dev/null +++ b/tasks/deploy/config/gnosis/factory.ts @@ -0,0 +1,74 @@ +import { Address, parseEther, zeroAddress } from "viem"; +import { HyperdriveFactoryConfig, parseDuration } from "../../lib"; + +// The name of the factory. +export const GNOSIS_FACTORY_NAME = "ElementDAO Hyperdrive Factory"; + +// The name of the forwarder factory. +export const GNOSIS_FACTORY_FORWARDER_NAME = + "ElementDAO ERC20 Factory Forwarder"; + +export const GNOSIS_FACTORY: HyperdriveFactoryConfig = { + name: GNOSIS_FACTORY_NAME, + prepare: async (hre, options) => { + await hre.hyperdriveDeploy.ensureDeployed( + GNOSIS_FACTORY_FORWARDER_NAME, + "ERC20ForwarderFactory", + [GNOSIS_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( + GNOSIS_FACTORY_FORWARDER_NAME, + ).address, + linkerCodeHash: await ( + await hre.viem.getContractAt( + "ERC20ForwarderFactory", + hre.hyperdriveDeploy.deployments.byName( + GNOSIS_FACTORY_FORWARDER_NAME, + ).address, + ) + ).read.ERC20LINK_HASH(), + }, + GNOSIS_FACTORY_NAME, + ], +}; diff --git a/tasks/deploy/config/gnosis/index.ts b/tasks/deploy/config/gnosis/index.ts new file mode 100644 index 000000000..0edc2d351 --- /dev/null +++ b/tasks/deploy/config/gnosis/index.ts @@ -0,0 +1,5 @@ +export * from "./chainlink-coordinator"; +export * from "./erc4626-coordinator"; +export * from "./factory"; +export * from "./sxdai-182day"; +export * from "./wsteth-182day"; diff --git a/tasks/deploy/config/gnosis/sxdai-182day.ts b/tasks/deploy/config/gnosis/sxdai-182day.ts new file mode 100644 index 000000000..ec4127c7a --- /dev/null +++ b/tasks/deploy/config/gnosis/sxdai-182day.ts @@ -0,0 +1,83 @@ +import { Address, keccak256, parseEther, toBytes, zeroAddress } from "viem"; +import { + HyperdriveInstanceConfig, + getLinkerDetails, + normalizeFee, + parseDuration, + toBytes32, +} from "../../lib"; +import { + SIX_MONTHS, + SXDAI_ADDRESS_GNOSIS, + WXDAI_ADDRESS_GNOSIS, +} from "../../lib/constants"; +import { GNOSIS_ERC4626_COORDINATOR_NAME } from "./erc4626-coordinator"; +import { GNOSIS_FACTORY_NAME } from "./factory"; + +// The name of the pool. +export const GNOSIS_SXDAI_182DAY_NAME = "ElementDAO 182 Day sxDAI Hyperdrive"; + +// The initial contribution of the pool. +const CONTRIBUTION = parseEther("100"); + +export const GNOSIS_SXDAI_182DAY: HyperdriveInstanceConfig<"ERC4626"> = { + name: GNOSIS_SXDAI_182DAY_NAME, + prefix: "ERC4626", + coordinatorAddress: async (hre) => + hre.hyperdriveDeploy.deployments.byName(GNOSIS_ERC4626_COORDINATOR_NAME) + .address, + deploymentId: keccak256(toBytes(GNOSIS_SXDAI_182DAY_NAME)), + salt: toBytes32("0x69420"), + extraData: "0x", + contribution: CONTRIBUTION, + fixedAPR: parseEther("0.06"), + 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", + WXDAI_ADDRESS_GNOSIS, + ); + let tx = await baseToken.write.approve([ + hre.hyperdriveDeploy.deployments.byName( + GNOSIS_ERC4626_COORDINATOR_NAME, + ).address, + CONTRIBUTION, + ]); + let pc = await hre.viem.getPublicClient(); + await pc.waitForTransactionReceipt({ hash: tx }); + }, + poolDeployConfig: async (hre) => { + return { + baseToken: WXDAI_ADDRESS_GNOSIS, + vaultSharesToken: SXDAI_ADDRESS_GNOSIS, + 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(GNOSIS_FACTORY_NAME) + .address, + )), + fees: { + curve: parseEther("0.01"), + flat: normalizeFee(parseEther("0.0005"), SIX_MONTHS), + governanceLP: parseEther("0.15"), + governanceZombie: parseEther("0.03"), + }, + }; + }, +}; diff --git a/tasks/deploy/config/gnosis/wsteth-182day.ts b/tasks/deploy/config/gnosis/wsteth-182day.ts new file mode 100644 index 000000000..3297f137e --- /dev/null +++ b/tasks/deploy/config/gnosis/wsteth-182day.ts @@ -0,0 +1,98 @@ +import { + Address, + encodeAbiParameters, + keccak256, + parseAbiParameters, + parseEther, + toBytes, + zeroAddress, +} from "viem"; +import { + HyperdriveInstanceConfig, + getLinkerDetails, + normalizeFee, + parseDuration, + toBytes32, +} from "../../lib"; +import { + CHAINLINK_AGGREGATOR_WSTETH_ETH_PROXY_GNOSIS, + SIX_MONTHS, + WSTETH_ADDRESS_GNOSIS, +} from "../../lib/constants"; +import { GNOSIS_CHAINLINK_COORDINATOR_NAME } from "./chainlink-coordinator"; +import { GNOSIS_FACTORY_NAME } from "./factory"; + +// The name of the pool. +export const GNOSIS_WSTETH_182DAY_NAME = "ElementDAO 182 Day wstETH Hyperdrive"; + +// The initial contribution of the pool. +const CONTRIBUTION = parseEther("0.01"); + +export const GNOSIS_WSTETH_182DAY: HyperdriveInstanceConfig<"Chainlink"> = { + name: GNOSIS_WSTETH_182DAY_NAME, + prefix: "Chainlink", + coordinatorAddress: async (hre) => + hre.hyperdriveDeploy.deployments.byName( + GNOSIS_CHAINLINK_COORDINATOR_NAME, + ).address, + deploymentId: keccak256(toBytes(GNOSIS_WSTETH_182DAY_NAME)), + salt: toBytes32("0xababe"), + extraData: encodeAbiParameters(parseAbiParameters("address, uint8"), [ + CHAINLINK_AGGREGATOR_WSTETH_ETH_PROXY_GNOSIS, + 18, + ]), + contribution: CONTRIBUTION, + fixedAPR: parseEther("0.029"), + timestretchAPR: parseEther("0.035"), + options: async (hre) => ({ + extraData: encodeAbiParameters(parseAbiParameters("address, uint8"), [ + CHAINLINK_AGGREGATOR_WSTETH_ETH_PROXY_GNOSIS, + 18, + ]), + asBase: false, + destination: (await hre.getNamedAccounts())["deployer"] as Address, + }), + // Prepare to deploy the contract by setting approvals. + prepare: async (hre) => { + let vaultSharesToken = await hre.viem.getContractAt( + "contracts/src/interfaces/IERC20.sol:IERC20", + WSTETH_ADDRESS_GNOSIS, + ); + let tx = await vaultSharesToken.write.approve([ + hre.hyperdriveDeploy.deployments.byName( + GNOSIS_CHAINLINK_COORDINATOR_NAME, + ).address, + CONTRIBUTION, + ]); + let pc = await hre.viem.getPublicClient(); + await pc.waitForTransactionReceipt({ hash: tx }); + }, + poolDeployConfig: async (hre) => { + return { + baseToken: zeroAddress, + vaultSharesToken: WSTETH_ADDRESS_GNOSIS, + circuitBreakerDelta: parseEther("0.035"), + minimumShareReserves: parseEther("0.001"), + 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(GNOSIS_FACTORY_NAME) + .address, + )), + fees: { + curve: parseEther("0.01"), + flat: normalizeFee(parseEther("0.0005"), SIX_MONTHS), + governanceLP: parseEther("0.15"), + governanceZombie: parseEther("0.03"), + }, + }; + }, +}; diff --git a/tasks/deploy/lib/constants.ts b/tasks/deploy/lib/constants.ts index 1f7cfc4a3..bd8bbcb29 100644 --- a/tasks/deploy/lib/constants.ts +++ b/tasks/deploy/lib/constants.ts @@ -91,6 +91,32 @@ export const WSTETH_WHALE_MAINNET = export const SEPOLIA_USDE_ADDRESS = "0x9458CaACa74249AbBE9E964b3Ce155B98EC88EF2" as Address; +// ╭─────────────────────────────────────────────────────────╮ +// │ Gnosis Addresses │ +// ╰─────────────────────────────────────────────────────────╯ + +export const CHAINLINK_AGGREGATOR_ADDRESS_GNOSIS = + "0x6dcF8CE1982Fc71E7128407c7c6Ce4B0C1722F55" as Address; + +export const CHAINLINK_AGGREGATOR_WSTETH_ETH_PROXY_GNOSIS = + "0x0064AC007fF665CF8D0D3Af5E0AD1c26a3f853eA" as Address; + +export const SXDAI_ADDRESS_GNOSIS = + "0xaf204776c7245bF4147c2612BF6e5972Ee483701" as Address; + +export const WXDAI_ADDRESS_GNOSIS = + "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d" as Address; + +export const WSTETH_ADDRESS_GNOSIS = + "0x6C76971f98945AE98dD7d4DFcA8711ebea946eA6" as Address; + +// ╭─────────────────────────────────────────────────────────╮ +// │ Gnosis Whales │ +// ╰─────────────────────────────────────────────────────────╯ + +export const WSTETH_WHALE_GNOSIS = + "0x458cD345B4C05e8DF39d0A07220feb4Ec19F5e6f" as Address; + // ╭─────────────────────────────────────────────────────────╮ // │ Durations │ // ╰─────────────────────────────────────────────────────────╯ From a763d8c4d0bf3a8e2a7c6267bf7f26fbd3f61753 Mon Sep 17 00:00:00 2001 From: "John McClure (pickleback)" Date: Mon, 26 Aug 2024 19:37:02 -0500 Subject: [PATCH 2/5] gnosis fork prep --- scripts/deploy-fork.sh | 14 +++++-- scripts/fund-fork-accounts.sh | 48 +++++++++++++-------- tasks/fork/index.ts | 1 + tasks/fork/mint-wsteth.ts | 22 ++++++---- tasks/fork/mint-wxdai.ts | 78 +++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 29 deletions(-) create mode 100644 tasks/fork/mint-wxdai.ts diff --git a/scripts/deploy-fork.sh b/scripts/deploy-fork.sh index df2717573..1c4f06d8b 100755 --- a/scripts/deploy-fork.sh +++ b/scripts/deploy-fork.sh @@ -3,7 +3,6 @@ set -e # Mint some of each instance's token to the deployer address. -export NETWORK='mainnet_fork' sh scripts/fund-fork-accounts.sh # Deploy factory, coordinators, and instances. @@ -11,7 +10,14 @@ npx hardhat deploy:hyperdrive --network mainnet_fork --config hardhat.config.mai # Extract the deployed contract addresses to `artifacts/addresses.json` # for use with the delvtech/infra address server. -cat ./deployments.local.json | jq '.mainnet_fork | { +if ["$NETWORK" == "mainnet_fork"]; then + cat ./deployments.local.json | jq ".mainnet_fork | { hyperdriveRegistry: .["DELV Hyperdrive Registry"].address, - }' >./artifacts/addresses.json -cp ./deployments.local.json ./artifacts/ + }" >./artifacts/addresses.json + cp ./deployments.local.json ./artifacts/ +else + cat ./deployments.json | jq ".$NETWORK | { + hyperdriveRegistry: .["DELV Hyperdrive Registry"].address, + }" >./artifacts/addresses.json + cp ./deployments.json ./artifacts/ +fi diff --git a/scripts/fund-fork-accounts.sh b/scripts/fund-fork-accounts.sh index 536d515c0..7bab00f91 100755 --- a/scripts/fund-fork-accounts.sh +++ b/scripts/fund-fork-accounts.sh @@ -19,24 +19,36 @@ fi for address in "${addresses[@]}" do echo "funding ${address}..." + echo " - funding eth..." npx hardhat fork:mint-eth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding dai..." - npx hardhat fork:mint-dai --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding eeth..." - npx hardhat fork:mint-eeth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding ezeth..." - npx hardhat fork:mint-ezeth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding reth..." - npx hardhat fork:mint-reth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding sdai..." - npx hardhat fork:mint-sdai --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding steth..." - npx hardhat fork:mint-steth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding usde..." - npx hardhat fork:mint-usde --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding wsteth..." - npx hardhat fork:mint-wsteth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - echo " - funding usdc..." - npx hardhat fork:mint-usdc --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + + if [ "$NETWORK" = "mainnet_fork"]; then + echo " - funding dai..." + npx hardhat fork:mint-dai --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding eeth..." + npx hardhat fork:mint-eeth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding ezeth..." + npx hardhat fork:mint-ezeth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding reth..." + npx hardhat fork:mint-reth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding sdai..." + npx hardhat fork:mint-sdai --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding steth..." + npx hardhat fork:mint-steth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding usde..." + npx hardhat fork:mint-usde --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding wsteth..." + npx hardhat fork:mint-wsteth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding usdc..." + npx hardhat fork:mint-usdc --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + fi + + if [ "$NETWORK" = "gnosis" ]; then + echo " - funding wsteth..." + npx hardhat fork:mint-wsteth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + echo " - funding wxdai..." + npx hardhat fork:mint-wxdai --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" + fi + done diff --git a/tasks/fork/index.ts b/tasks/fork/index.ts index c7bdc2c5a..b0a761634 100644 --- a/tasks/fork/index.ts +++ b/tasks/fork/index.ts @@ -10,3 +10,4 @@ export * from "./mint-steth"; export * from "./mint-usdc"; export * from "./mint-usde"; export * from "./mint-wsteth"; +export * from "./mint-wxdai"; diff --git a/tasks/fork/mint-wsteth.ts b/tasks/fork/mint-wsteth.ts index 991747cd8..48f465ab3 100644 --- a/tasks/fork/mint-wsteth.ts +++ b/tasks/fork/mint-wsteth.ts @@ -3,8 +3,8 @@ import { Address, encodeFunctionData, parseEther, zeroAddress } from "viem"; import { HyperdriveDeployBaseTask, HyperdriveDeployBaseTaskParams, + WSTETH_ADDRESS_GNOSIS, WSTETH_ADDRESS_MAINNET, - WSTETH_WHALE_MAINNET, } from "../deploy"; export type MintWSTETHParams = HyperdriveDeployBaseTaskParams & { @@ -33,16 +33,24 @@ HyperdriveDeployBaseTask( .setAction( async ( { address, amount }: Required, - { viem, artifacts, getNamedAccounts }, + { viem, artifacts, getNamedAccounts, network }, ) => { if (address === zeroAddress) { address = (await getNamedAccounts())["deployer"]; } + let wstethAddress = + network.name === "gnosis" + ? WSTETH_ADDRESS_GNOSIS + : WSTETH_ADDRESS_MAINNET; + let wstethWhale = + network.name === "gnosis" + ? WSTETH_ADDRESS_GNOSIS + : WSTETH_ADDRESS_MAINNET; let contract = await viem.getContractAt( "solmate/tokens/ERC20.sol:ERC20", - WSTETH_ADDRESS_MAINNET, + wstethAddress, ); - let balance = await contract.read.balanceOf([WSTETH_WHALE_MAINNET]); + let balance = await contract.read.balanceOf([wstethWhale]); if (balance < parseEther(amount)) { console.log( "ERROR: insufficient funds in WSTETH whale account, skipping...", @@ -64,12 +72,12 @@ HyperdriveDeployBaseTask( mode: "anvil", }); await tc.setBalance({ - address: WSTETH_WHALE_MAINNET, + address: wstethWhale, value: parseEther("1"), }); let tx = await tc.sendUnsignedTransaction({ - from: WSTETH_WHALE_MAINNET, - to: WSTETH_ADDRESS_MAINNET, + from: wstethWhale, + to: wstethAddress, data: transferData, }); let pc = await viem.getPublicClient(); diff --git a/tasks/fork/mint-wxdai.ts b/tasks/fork/mint-wxdai.ts new file mode 100644 index 000000000..fd1aa9a4e --- /dev/null +++ b/tasks/fork/mint-wxdai.ts @@ -0,0 +1,78 @@ +import { task, types } from "hardhat/config"; +import { Address, encodeFunctionData, parseEther, zeroAddress } from "viem"; +import { + HyperdriveDeployBaseTask, + HyperdriveDeployBaseTaskParams, + SXDAI_ADDRESS_GNOSIS, + WXDAI_ADDRESS_GNOSIS, +} from "../deploy"; + +export type MintWXDAIParams = HyperdriveDeployBaseTaskParams & { + address: string; + amount: string; +}; + +HyperdriveDeployBaseTask( + task( + "fork:mint-wxdai", + "Mints the specified amount of WXDAI to the input address", + ), +) + .addOptionalParam( + "address", + "address to send WXDAI", + zeroAddress, + types.string, + ) + .addOptionalParam( + "amount", + "amount (in ether) to mint", + "10000", + types.string, + ) + .setAction( + async ( + { address, amount }: Required, + { viem, artifacts, getNamedAccounts }, + ) => { + if (address === zeroAddress) { + address = (await getNamedAccounts())["deployer"]; + } + let contract = await viem.getContractAt( + "solmate/tokens/ERC20.sol:ERC20", + WXDAI_ADDRESS_GNOSIS, + ); + let balance = await contract.read.balanceOf([SXDAI_ADDRESS_GNOSIS]); + if (balance < parseEther(amount)) { + console.log( + "ERROR: insufficient funds in WXDAI whale account, skipping...", + ); + return; + } + + let transferData = encodeFunctionData({ + abi: ( + await artifacts.readArtifact( + "solmate/tokens/ERC20.sol:ERC20", + ) + ).abi, + functionName: "transfer", + args: [address as Address, parseEther(amount!)], + }); + + let tc = await viem.getTestClient({ + mode: "anvil", + }); + await tc.setBalance({ + address: SXDAI_ADDRESS_GNOSIS, + value: parseEther("1"), + }); + let tx = await tc.sendUnsignedTransaction({ + from: SXDAI_ADDRESS_GNOSIS, + to: WXDAI_ADDRESS_GNOSIS, + data: transferData, + }); + let pc = await viem.getPublicClient(); + await pc.waitForTransactionReceipt({ hash: tx }); + }, + ); From 761a05f66bea5506e0e0ee2a7699c40a441d7a75 Mon Sep 17 00:00:00 2001 From: "John McClure (pickleback)" Date: Tue, 27 Aug 2024 02:41:48 -0500 Subject: [PATCH 3/5] update funding script --- scripts/deploy-fork.sh | 20 ++++++++++++++++---- scripts/deploy.sh | 22 +++++++++++----------- scripts/fund-fork-accounts.sh | 11 ++++++----- tasks/fork/mint-wsteth.ts | 6 ++++-- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/scripts/deploy-fork.sh b/scripts/deploy-fork.sh index 1c4f06d8b..ce6e6b0fd 100755 --- a/scripts/deploy-fork.sh +++ b/scripts/deploy-fork.sh @@ -2,22 +2,34 @@ set -e +# Ensure that the NETWORK variable is defined. +if [[ -z "$NETWORK" ]]; then + echo 'Error: $NETWORK must be set' + exit 1 +fi + +# Ensure that the ADMIN variable is defined. +if [[ -z "$ADMIN" ]]; then + echo 'Error: $ADMIN must be set' + exit 1 +fi + # Mint some of each instance's token to the deployer address. sh scripts/fund-fork-accounts.sh # Deploy factory, coordinators, and instances. -npx hardhat deploy:hyperdrive --network mainnet_fork --config hardhat.config.mainnet_fork.ts --show-stack-traces +npx hardhat deploy:hyperdrive --network $NETWORK --config hardhat.config.$NETWORK.ts --show-stack-traces # Extract the deployed contract addresses to `artifacts/addresses.json` # for use with the delvtech/infra address server. -if ["$NETWORK" == "mainnet_fork"]; then +if [ "$NETWORK" == "mainnet_fork" ]; then cat ./deployments.local.json | jq ".mainnet_fork | { - hyperdriveRegistry: .["DELV Hyperdrive Registry"].address, + hyperdriveRegistry: .[\"DELV Hyperdrive Registry\"].address, }" >./artifacts/addresses.json cp ./deployments.local.json ./artifacts/ else cat ./deployments.json | jq ".$NETWORK | { - hyperdriveRegistry: .["DELV Hyperdrive Registry"].address, + hyperdriveRegistry: .[\"DELV Hyperdrive Registry\"].address, }" >./artifacts/addresses.json cp ./deployments.json ./artifacts/ fi diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 659e9bfe9..4d4231cf6 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -4,27 +4,27 @@ set -e # Ensure that the network variable is defined if [[ -z "${NETWORK}" ]]; then - echo 'Error: $NETWORK must be set' - exit 1 + echo 'Error: $NETWORK must be set' + exit 1 fi # When deploying to "live" networks, ensure that the repository is equivalent # to the latest remote tag. This avoids accidentally deploying out-of-date or # ambiguously versioned contracts. if [[ "${NETWORK}" != "anvil" && "${NETWORK}" != "hardhat" && "${NETWORK}" != "mainnet_fork" ]]; then - git remote update - tag=$(git describe --tags --abbrev=0) - diff=$(git diff ${tag} --raw -- contracts lib) - if [[ ! -z "${diff}" ]]; then - echo "$diff" - echo "Error: repository contents must match tag ${tag}" - exit 1 - fi + git remote update + tag=$(git describe --tags --abbrev=0) + diff=$(git diff ${tag} --raw -- contracts lib) + if [[ ! -z "${diff}" ]]; then + echo "$diff" + echo "Error: repository contents must match tag ${tag}" + exit 1 + fi fi config_filename="hardhat.config.${NETWORK}.ts" if [[ "${NETWORK}" == "hardhat" ]]; then - config_filename="hardhat.config.ts" + config_filename="hardhat.config.ts" fi npx hardhat deploy:hyperdrive --show-stack-traces --network ${NETWORK} --config "$config_filename" npx hardhat deploy:verify --show-stack-traces --network ${NETWORK} --config "$config_filename" diff --git a/scripts/fund-fork-accounts.sh b/scripts/fund-fork-accounts.sh index 7bab00f91..e0fd74aa9 100755 --- a/scripts/fund-fork-accounts.sh +++ b/scripts/fund-fork-accounts.sh @@ -12,7 +12,7 @@ fi if [[ -z "$ADMIN" ]]; then addresses=('0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266' '0x70997970C51812dc3A010C7d01b50e0d17dc79C8' '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC' '0x90F79bf6EB2c4f870365E785982E1f101E93b906' '0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65' '0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc' '0x976EA74026E726554dB657fA54763abd0C3a0aa9' '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955' '0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f' '0xa0Ee7A142d267C1f36714E4a8F75612F20a79720') else - addresses=("${ADMIN}") + addresses=( "$ADMIN" ) fi # Mint tokens to all of the default anvil accounts. @@ -20,10 +20,9 @@ for address in "${addresses[@]}" do echo "funding ${address}..." - echo " - funding eth..." - npx hardhat fork:mint-eth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" - - if [ "$NETWORK" = "mainnet_fork"]; then + if [ "$NETWORK" = "mainnet_fork" ]; then + echo " - funding eth..." + npx hardhat fork:mint-eth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" echo " - funding dai..." npx hardhat fork:mint-dai --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" echo " - funding eeth..." @@ -45,6 +44,8 @@ do fi if [ "$NETWORK" = "gnosis" ]; then + echo " - funding xdai..." + npx hardhat fork:mint-eth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" echo " - funding wsteth..." npx hardhat fork:mint-wsteth --address "${address}" --network "${NETWORK}" --config "hardhat.config.${NETWORK}.ts" echo " - funding wxdai..." diff --git a/tasks/fork/mint-wsteth.ts b/tasks/fork/mint-wsteth.ts index 48f465ab3..543e86ef2 100644 --- a/tasks/fork/mint-wsteth.ts +++ b/tasks/fork/mint-wsteth.ts @@ -5,6 +5,8 @@ import { HyperdriveDeployBaseTaskParams, WSTETH_ADDRESS_GNOSIS, WSTETH_ADDRESS_MAINNET, + WSTETH_WHALE_GNOSIS, + WSTETH_WHALE_MAINNET, } from "../deploy"; export type MintWSTETHParams = HyperdriveDeployBaseTaskParams & { @@ -44,8 +46,8 @@ HyperdriveDeployBaseTask( : WSTETH_ADDRESS_MAINNET; let wstethWhale = network.name === "gnosis" - ? WSTETH_ADDRESS_GNOSIS - : WSTETH_ADDRESS_MAINNET; + ? WSTETH_WHALE_GNOSIS + : WSTETH_WHALE_MAINNET; let contract = await viem.getContractAt( "solmate/tokens/ERC20.sol:ERC20", wstethAddress, From 48f1b063ad1b933778b537502392e74147068678 Mon Sep 17 00:00:00 2001 From: "John McClure (pickleback)" Date: Tue, 27 Aug 2024 02:57:27 -0500 Subject: [PATCH 4/5] add rate incrementing for gnosis wsteth --- tasks/fork/maintain-rate.ts | 180 ++++++++++++++++++++++-------------- 1 file changed, 112 insertions(+), 68 deletions(-) diff --git a/tasks/fork/maintain-rate.ts b/tasks/fork/maintain-rate.ts index da675e1a4..7c0a8598e 100644 --- a/tasks/fork/maintain-rate.ts +++ b/tasks/fork/maintain-rate.ts @@ -1,6 +1,15 @@ import { task, types } from "hardhat/config"; -import { encodeFunctionData, keccak256, parseEther, toHex } from "viem"; import { + encodeAbiParameters, + encodeFunctionData, + keccak256, + parseAbiParameters, + parseEther, + toHex, +} from "viem"; +import { + CHAINLINK_AGGREGATOR_ADDRESS_GNOSIS, + CHAINLINK_AGGREGATOR_WSTETH_ETH_PROXY_GNOSIS, EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, EETH_MEMBERSHIP_MANAGER_ADDRESS_MAINNET, HyperdriveDeployBaseTask, @@ -38,82 +47,117 @@ HyperdriveDeployBaseTask( mode: "anvil", }); let pc = await hre.viem.getPublicClient(); + // Every hour, increase the balance of each vault by an amount proportional to the annual rate. while (true) { console.log("increasing balance of underlying vaults..."); - // For STETH, modify the `beaconBalance` storage slot value. - let slot = keccak256(toHex("lido.Lido.beaconBalance")); - let stethCurrentBalance = BigInt( - (await pc.getStorageAt({ + // Mainnet Pools + if (hre.network.name === "mainnet_fork") { + // For STETH, modify the `beaconBalance` storage slot value. + let slot = keccak256(toHex("lido.Lido.beaconBalance")); + let stethCurrentBalance = BigInt( + (await pc.getStorageAt({ + address: STETH_ADDRESS_MAINNET, + slot, + }))!, + ); + let stethBalanceIncrease = + (stethCurrentBalance * + BigInt(interval) * + parseEther(rate)) / + (365n * 24n * BigInt(1e18)); + await tc.setStorageAt({ address: STETH_ADDRESS_MAINNET, - slot, - }))!, - ); - let stethBalanceIncrease = - (stethCurrentBalance * BigInt(interval) * parseEther(rate)) / - (365n * 24n * BigInt(1e18)); - await tc.setStorageAt({ - address: STETH_ADDRESS_MAINNET, - index: slot, - value: toHex( - BigInt(stethCurrentBalance!) + stethBalanceIncrease, - { - size: 32, - }, - ), - }); - console.log(`steth balance increased by ${stethBalanceIncrease}`); + index: slot, + value: toHex( + BigInt(stethCurrentBalance!) + stethBalanceIncrease, + { + size: 32, + }, + ), + }); + console.log( + `steth balance increased by ${stethBalanceIncrease}`, + ); + + // For RETH, update the ETH balance of the RocketTokenRETH contract. + let rethCurrentBalance = await pc.getBalance({ + address: RETH_ADDRESS_MAINNET, + }); + let rethBalanceIncrease = + (rethCurrentBalance * BigInt(interval) * parseEther(rate)) / + (365n * 24n * BigInt(1e18)); + await tc.setBalance({ + address: RETH_ADDRESS_MAINNET, + value: rethCurrentBalance + rethBalanceIncrease, + }); + console.log(`reth balance increased by ${rethBalanceIncrease}`); + + // TODO: This won't necessarily use the right rate. + // + // For SDAI, nothing needs to be done so long as the underlying `rho` + // value is not recalculated. - // For RETH, update the ETH balance of the RocketTokenRETH contract. - let rethCurrentBalance = await pc.getBalance({ - address: RETH_ADDRESS_MAINNET, - }); - let rethBalanceIncrease = - (rethCurrentBalance * BigInt(interval) * parseEther(rate)) / - (365n * 24n * BigInt(1e18)); - await tc.setBalance({ - address: RETH_ADDRESS_MAINNET, - value: rethCurrentBalance + rethBalanceIncrease, - }); - console.log(`reth balance increased by ${rethBalanceIncrease}`); + // For EETH, we can call rebase on the Etherfi contract using an + // impersonated account. + let etherfi = await hre.viem.getContractAt( + "ILiquidityPool", + EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, + ); + let etherToAdd = + ((await etherfi.read.getTotalPooledEther()) * + BigInt(interval) * + parseEther(rate)) / + (365n * 24n * BigInt(1e18)); + let txData = encodeFunctionData({ + abi: (await hre.artifacts.readArtifact("ILiquidityPool")) + .abi, + functionName: "rebase", + args: [etherToAdd], + }); + await tc.sendUnsignedTransaction({ + from: EETH_MEMBERSHIP_MANAGER_ADDRESS_MAINNET, + to: EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, + data: txData, + }); + await tc.setBalance({ + address: EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, + value: etherToAdd, + }); + console.log(`etherfi total assets increased by ${etherToAdd}`); - // TODO: This won't necessarily use the right rate. - // - // For SDAI, nothing needs to be done so long as the underlying `rho` - // value is not recalculated. + // TODO: This won't necessarily use the right rate. + // + // For Morpho, nothing needs to be done and interest will accrue at + // the market rate. + } else if (hre.network.name === "gnosis") { + // Chainlink wstETH - // For EETH, we can call rebase on the Etherfi contract using an - // impersonated account. - let etherfi = await hre.viem.getContractAt( - "ILiquidityPool", - EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, - ); - let etherToAdd = - ((await etherfi.read.getTotalPooledEther()) * - BigInt(interval) * - parseEther(rate)) / - (365n * 24n * BigInt(1e18)); - let txData = encodeFunctionData({ - abi: (await hre.artifacts.readArtifact("ILiquidityPool")).abi, - functionName: "rebase", - args: [etherToAdd], - }); - await tc.sendUnsignedTransaction({ - from: EETH_MEMBERSHIP_MANAGER_ADDRESS_MAINNET, - to: EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, - data: txData, - }); - await tc.setBalance({ - address: EETH_LIQUIDITY_POOL_ADDRESS_MAINNET, - value: etherToAdd, - }); - console.log(`etherfi total assets increased by ${etherToAdd}`); + // Get the latest round ID and answer. We'll overwrite this round ID + // with the updated answer. + let chainlinkAggregatorContract = await hre.viem.getContractAt( + "contracts/src/interfaces/IChainlinkAggregatorV3.sol:IChainlinkAggregatorV3", + CHAINLINK_AGGREGATOR_WSTETH_ETH_PROXY_GNOSIS, + ); + let [roundId, answer, _, updatedAt] = + await chainlinkAggregatorContract.read.latestRoundData(); + let latestRoundLocation = encodeAbiParameters( + parseAbiParameters("uint32, uint256"), + [Number(roundId), 44n], + ); - // TODO: This won't necessarily use the right rate. - // - // For Morpho, nothing needs to be done and interest will accrue at - // the market rate. + // Accrue interest in the Chainlink wstETH market. We do this by + // overwriting the latest round's answer. + let tc = await hre.viem.getTestClient(); + await tc.setStorageAt({ + address: CHAINLINK_AGGREGATOR_ADDRESS_GNOSIS, + index: latestRoundLocation, + value: + (answer * BigInt(interval) * parseEther(rate)) / + (365n * 24n * BigInt(1e18)), + }); + } await sleep(interval * 60); } From f296b59660cb283f90825787c573d2fe2fb8331b Mon Sep 17 00:00:00 2001 From: "John McClure (pickleback)" Date: Tue, 27 Aug 2024 03:05:52 -0500 Subject: [PATCH 5/5] addressing feedback: update configuration and source addresses from factory --- tasks/deploy/config/gnosis/factory.ts | 2 +- tasks/deploy/config/gnosis/sxdai-182day.ts | 18 +++++++++++------- tasks/deploy/config/gnosis/wsteth-182day.ts | 13 +++++++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/tasks/deploy/config/gnosis/factory.ts b/tasks/deploy/config/gnosis/factory.ts index ddbba0bcc..8899951d2 100644 --- a/tasks/deploy/config/gnosis/factory.ts +++ b/tasks/deploy/config/gnosis/factory.ts @@ -42,7 +42,7 @@ export const GNOSIS_FACTORY: HyperdriveFactoryConfig = { minFixedAPR: parseEther("0.005"), maxFixedAPR: parseEther("0.1"), minTimeStretchAPR: parseEther("0.005"), - maxTimeStretchAPR: parseEther("0.1"), + maxTimeStretchAPR: parseEther("0.2"), minCircuitBreakerDelta: parseEther("0.01"), maxCircuitBreakerDelta: parseEther("0.2"), minFees: { diff --git a/tasks/deploy/config/gnosis/sxdai-182day.ts b/tasks/deploy/config/gnosis/sxdai-182day.ts index ec4127c7a..7726a0f00 100644 --- a/tasks/deploy/config/gnosis/sxdai-182day.ts +++ b/tasks/deploy/config/gnosis/sxdai-182day.ts @@ -1,4 +1,4 @@ -import { Address, keccak256, parseEther, toBytes, zeroAddress } from "viem"; +import { Address, keccak256, parseEther, toBytes } from "viem"; import { HyperdriveInstanceConfig, getLinkerDetails, @@ -53,20 +53,24 @@ export const GNOSIS_SXDAI_182DAY: HyperdriveInstanceConfig<"ERC4626"> = { await pc.waitForTransactionReceipt({ hash: tx }); }, poolDeployConfig: async (hre) => { + let factoryContract = await hre.viem.getContractAt( + "HyperdriveFactory", + hre.hyperdriveDeploy.deployments.byName(GNOSIS_FACTORY_NAME) + .address, + ); return { baseToken: WXDAI_ADDRESS_GNOSIS, vaultSharesToken: SXDAI_ADDRESS_GNOSIS, circuitBreakerDelta: parseEther("0.05"), - minimumShareReserves: parseEther("10"), + minimumShareReserves: parseEther("0.005"), 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, + governance: await factoryContract.read.governance(), + feeCollector: await factoryContract.read.feeCollector(), + sweepCollector: await factoryContract.read.sweepCollector(), + checkpointRewarder: await factoryContract.read.checkpointRewarder(), ...(await getLinkerDetails( hre, hre.hyperdriveDeploy.deployments.byName(GNOSIS_FACTORY_NAME) diff --git a/tasks/deploy/config/gnosis/wsteth-182day.ts b/tasks/deploy/config/gnosis/wsteth-182day.ts index 3297f137e..30f96ebe2 100644 --- a/tasks/deploy/config/gnosis/wsteth-182day.ts +++ b/tasks/deploy/config/gnosis/wsteth-182day.ts @@ -68,6 +68,11 @@ export const GNOSIS_WSTETH_182DAY: HyperdriveInstanceConfig<"Chainlink"> = { await pc.waitForTransactionReceipt({ hash: tx }); }, poolDeployConfig: async (hre) => { + let factoryContract = await hre.viem.getContractAt( + "HyperdriveFactory", + hre.hyperdriveDeploy.deployments.byName(GNOSIS_FACTORY_NAME) + .address, + ); return { baseToken: zeroAddress, vaultSharesToken: WSTETH_ADDRESS_GNOSIS, @@ -78,10 +83,10 @@ export const GNOSIS_WSTETH_182DAY: HyperdriveInstanceConfig<"Chainlink"> = { checkpointDuration: parseDuration("1 day"), timeStretch: 0n, // TODO: Read from the factory. - governance: (await hre.getNamedAccounts())["deployer"] as Address, - feeCollector: zeroAddress, - sweepCollector: zeroAddress, - checkpointRewarder: zeroAddress, + governance: await factoryContract.read.governance(), + feeCollector: await factoryContract.read.feeCollector(), + sweepCollector: await factoryContract.read.sweepCollector(), + checkpointRewarder: await factoryContract.read.checkpointRewarder(), ...(await getLinkerDetails( hre, hre.hyperdriveDeploy.deployments.byName(GNOSIS_FACTORY_NAME)