Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions .github/workflows/testnet_docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,13 @@ jobs:
build-args: |
ADMIN=${{ vars.TESTNET_ADMIN }}
IS_COMPETITION_MODE=true
BASE_TOKEN_NAME=Wrapped Ether
BASE_TOKEN_SYMBOL=WETH
VAULT_NAME=stETH
VAULT_SYMBOL=STETH
VAULT_STARTING_RATE=35000000000000000 # 3.5% APR
HYPERDRIVE_CONTRIBUTION=50000000000000000000000 # 50,000 ETH
HYPERDRIVE_FIXED_RATE=35000000000000000 # 3.5% APR
HYPERDRIVE_INITIAL_SHARE_PRICE=1000000000000000000 # 1 base/share
HYPERDRIVE_MINIMUM_SHARE_RESERVES=1000000000000000 # 1e15
HYPERDRIVE_MINIMUM_TRANSACTION_AMOUNT=1000000000000 # 1e12
HYPERDRIVE_POSITION_DURATION=31536000 # 1 year in seconds
HYPERDRIVE_CHECKPOINT_DURATION=86400 # 1 day in seconds
HYPERDRIVE_TIME_STRETCH_APR=35000000000000000 # 3.5% APR
HYPERDRIVE_ORACLE_SIZE=10 # 10 recorded spot prices
HYPERDRIVE_UPDATE_GAP=3600 # 1 hour in seconds
BASE_TOKEN_NAME=Multi Collateral DAI
BASE_TOKEN_SYMBOL=DAI
VAULT_NAME=sDai
VAULT_SYMBOL=SDAI
VAULT_STARTING_RATE=50000000000000000 # 5% APR
LIDO_STARTING_RATE=35000000000000000 # 3.5% APR
ERC4626_HYPERDRIVE_POSITION_DURATION=31536000 # 1 year in seconds
ERC4626_HYPERDRIVE_CHECKPOINT_DURATION=86400 # 1 day in seconds
STETH_HYPERDRIVE_POSITION_DURATION=31536000 # 1 year in seconds
STETH_HYPERDRIVE_CHECKPOINT_DURATION=86400 # 1 day in seconds
31 changes: 20 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,32 @@ ARG ADMIN
ARG IS_COMPETITION_MODE
ARG BASE_TOKEN_NAME
ARG BASE_TOKEN_SYMBOL
ARG VAULT_NAME
ARG VAULT_SYMBOL
ARG VAULT_STARTING_RATE
ARG HYPERDRIVE_CONTRIBUTION
ARG HYPERDRIVE_FIXED_RATE
ARG HYPERDRIVE_INITIAL_SHARE_PRICE
ARG HYPERDRIVE_MINIMUM_SHARE_RESERVES
ARG HYPERDRIVE_MINIMUM_TRANSACTION_AMOUNT
ARG HYPERDRIVE_POSITION_DURATION
ARG HYPERDRIVE_CHECKPOINT_DURATION
ARG HYPERDRIVE_TIME_STRETCH_APR
ARG HYPERDRIVE_ORACLE_SIZE
ARG HYPERDRIVE_UPDATE_GAP
ARG LIDO_STARTING_RATE
ARG ERC4626_HYPERDRIVE_CONTRIBUTION
ARG ERC4626_HYPERDRIVE_FIXED_RATE
ARG ERC4626_HYPERDRIVE_INITIAL_SHARE_PRICE
ARG ERC4626_HYPERDRIVE_MINIMUM_SHARE_RESERVES
ARG ERC4626_HYPERDRIVE_MINIMUM_TRANSACTION_AMOUNT
ARG ERC4626_HYPERDRIVE_POSITION_DURATION
ARG ERC4626_HYPERDRIVE_CHECKPOINT_DURATION
ARG ERC4626_HYPERDRIVE_TIME_STRETCH_APR
ARG STETH_HYPERDRIVE_CONTRIBUTION
ARG STETH_HYPERDRIVE_FIXED_RATE
ARG STETH_HYPERDRIVE_INITIAL_SHARE_PRICE
ARG STETH_HYPERDRIVE_MINIMUM_SHARE_RESERVES
ARG STETH_HYPERDRIVE_MINIMUM_TRANSACTION_AMOUNT
ARG STETH_HYPERDRIVE_POSITION_DURATION
ARG STETH_HYPERDRIVE_CHECKPOINT_DURATION
ARG STETH_HYPERDRIVE_TIME_STRETCH_APR

# Run anvil as a background process. We run the migrations against this anvil
# node and dump the state into the "./data" directory. At runtime, the consumer
# can start anvil with the "--load-state ./data" flag to start up anvil with
# the post-migrations state.
RUN anvil --dump-state ./data --code-size-limit 9999999999 & \
RUN anvil --dump-state ./data --balance 100000 & \
ANVIL="$!" && \
sleep 2 && \
./migrate.sh && \
Expand Down
3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ test-rust:
lint:
make lint-sol && make lint-rust

# FIXME: Add the code-size-check back once we've created a target2 contract.
lint-sol:
make solhint && make style-check && make spell-check && make warnings-check
make solhint && make style-check && make spell-check && make warnings-check && make code-size-check

code-size-check:
FOUNDRY_PROFILE=production forge build && python3 python/contract_size.py out
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,49 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { ERC4626Hyperdrive } from "../instances/ERC4626Hyperdrive.sol";
import { IERC4626 } from "../interfaces/IERC4626.sol";
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IERC4626HyperdriveDeployer } from "../interfaces/IERC4626HyperdriveDeployer.sol";
import { IHyperdriveCoreDeployer } from "../interfaces/IHyperdriveCoreDeployer.sol";
import { IHyperdriveDeployer } from "../interfaces/IHyperdriveDeployer.sol";
import { IHyperdriveTargetDeployer } from "../interfaces/IHyperdriveTargetDeployer.sol";
import { ONE } from "../libraries/FixedPointMath.sol";

/// @author DELV
/// @title ERC4626HyperdriveDeployer
/// @notice This is a minimal factory which contains only the logic to deploy
/// Hyperdrive and is called by a more complex factory which
/// initializes the Hyperdrive instances and acts as a registry.
/// @dev We use two contracts to avoid any code size limit issues with Hyperdrive.
/// @title HyperdriveDeployerCoordinator
/// @notice This Hyperdrive deployer coordinates the process of deploying the
/// Hyperdrive system utilizing several child deployers.
/// @dev We use multiple deployers to avoid the maximum code size.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
contract ERC4626HyperdriveDeployer is IHyperdriveDeployer {
abstract contract HyperdriveDeployerCoordinator is IHyperdriveDeployer {
/// @notice The contract used to deploy new instances of Hyperdrive.
address public immutable hyperdriveCoreDeployer;
address public immutable coreDeployer;

/// @notice The contract used to deploy new instances of Hyperdrive target0.
/// @notice The contract used to deploy new instances of HyperdriveTarget0.
address public immutable target0Deployer;

/// @notice The contract used to deploy new instances of Hyperdrive target1.
/// @notice The contract used to deploy new instances of HyperdriveTarget1.
address public immutable target1Deployer;

/// @notice The contract used to deploy new instances of Hyperdrive target2.
/// @notice The contract used to deploy new instances of HyperdriveTarget2.
address public immutable target2Deployer;

/// @notice The contract used to deploy new instances of Hyperdrive target3.
/// @notice The contract used to deploy new instances of HyperdriveTarget3.
address public immutable target3Deployer;

/// @notice Initializes the contract with the given parameters.
/// @param _hyperdriveCoreDeployer The contract used to deploy new instances
/// of Hyperdrive.
/// @notice Instantiates the deployer coordinator.
/// @param _coreDeployer The core deployer.
/// @param _target0Deployer The target0 deployer.
/// @param _target1Deployer The target1 deployer.
/// @param _target2Deployer The target2 deployer.
/// @param _target3Deployer The target3 deployer.
constructor(
address _hyperdriveCoreDeployer,
address _coreDeployer,
address _target0Deployer,
address _target1Deployer,
address _target2Deployer,
address _target3Deployer
) {
hyperdriveCoreDeployer = _hyperdriveCoreDeployer;
coreDeployer = _coreDeployer;
target0Deployer = _target0Deployer;
target1Deployer = _target1Deployer;
target2Deployer = _target2Deployer;
Expand All @@ -63,13 +58,10 @@ contract ERC4626HyperdriveDeployer is IHyperdriveDeployer {
IHyperdrive.PoolDeployConfig memory _deployConfig,
bytes memory _extraData
) external override returns (address) {
// Decode the extra data to extract the pool address.
(address pool, ) = abi.decode(_extraData, (address, address[]));

// Convert the deploy config into the pool config and set the initial
// share price.
IHyperdrive.PoolConfig memory _config = _copyPoolConfig(_deployConfig);
_config.initialSharePrice = IERC4626(pool).convertToAssets(ONE);
_config.initialSharePrice = _getInitialSharePrice(_extraData);

// Deploy the target0 contract.
address target0 = IHyperdriveTargetDeployer(target0Deployer).deploy(
Expand All @@ -89,9 +81,9 @@ contract ERC4626HyperdriveDeployer is IHyperdriveDeployer {
_extraData
);

// Deploy the ERC4626Hyperdrive instance.
// Deploy the Hyperdrive instance.
return
IERC4626HyperdriveDeployer(hyperdriveCoreDeployer).deploy(
IHyperdriveCoreDeployer(coreDeployer).deploy(
_config,
_extraData,
target0,
Expand All @@ -101,6 +93,13 @@ contract ERC4626HyperdriveDeployer is IHyperdriveDeployer {
);
}

/// @dev Gets the initial share price of the Hyperdrive pool.
/// @param _extraData The extra data passed to the child deployers.
/// @return The initial share price of the Hyperdrive pool.
function _getInitialSharePrice(
bytes memory _extraData
) internal view virtual returns (uint256);

/// @notice Copies the deploy config into a pool config.
/// @param _deployConfig The deploy configuration of the Hyperdrive pool.
/// @return _config The pool configuration of the Hyperdrive pool.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { IERC4626 } from "../interfaces/IERC4626.sol";
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IERC4626HyperdriveDeployer } from "../interfaces/IERC4626HyperdriveDeployer.sol";
import { ERC4626Hyperdrive } from "../instances/ERC4626Hyperdrive.sol";
import { IERC4626 } from "../../interfaces/IERC4626.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveCoreDeployer } from "../../interfaces/IHyperdriveCoreDeployer.sol";
import { ERC4626Hyperdrive } from "../../instances/erc4626/ERC4626Hyperdrive.sol";

/// @author DELV
/// @title ERC4626HyperdriveCoreDeployer
/// @notice This is a minimal factory which contains only the logic to deploy
/// the hyperdrive contract and is called by a more complex factory which
/// initializes the Hyperdrive instances and acts as a registry.
/// @notice The core deployer for the ERC4626Hyperdrive implementation.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
contract ERC4626HyperdriveCoreDeployer is IERC4626HyperdriveDeployer {
contract ERC4626HyperdriveCoreDeployer is IHyperdriveCoreDeployer {
/// @notice Deploys a Hyperdrive instance with the given parameters.
/// @param _config The configuration of the Hyperdrive pool.
/// @param _extraData The extra data that contains the ERC4626 vault.
Expand All @@ -31,9 +29,8 @@ contract ERC4626HyperdriveCoreDeployer is IERC4626HyperdriveDeployer {
address target2,
address target3
) external override returns (address) {
address pool = abi.decode(_extraData, (address));

// Deploy the ERC4626Hyperdrive instance.
address pool = abi.decode(_extraData, (address));
return (
address(
new ERC4626Hyperdrive(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { IERC4626 } from "../../interfaces/IERC4626.sol";
import { ONE } from "../../libraries/FixedPointMath.sol";
import { HyperdriveDeployerCoordinator } from "../HyperdriveDeployerCoordinator.sol";

/// @author DELV
/// @title ERC4626HyperdriveDeployerCoordinator
/// @notice The deployer coordinator for the ERC4626Hyperdrive implementation.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
contract ERC4626HyperdriveDeployerCoordinator is HyperdriveDeployerCoordinator {
/// @notice Instantiates the deployer coordinator.
/// @param _coreDeployer The core deployer.
/// @param _target0Deployer The target0 deployer.
/// @param _target1Deployer The target1 deployer.
/// @param _target2Deployer The target2 deployer.
/// @param _target3Deployer The target3 deployer.
constructor(
address _coreDeployer,
address _target0Deployer,
address _target1Deployer,
address _target2Deployer,
address _target3Deployer
)
HyperdriveDeployerCoordinator(
_coreDeployer,
_target0Deployer,
_target1Deployer,
_target2Deployer,
_target3Deployer
)
{}

/// @dev Gets the initial share price of the Hyperdrive pool.
/// @param _extraData The extra data passed to the child deployers.
/// @return The initial share price of the Hyperdrive pool.
function _getInitialSharePrice(
bytes memory _extraData
) internal view override returns (uint256) {
// Return the vault's current share price.
IERC4626 pool = IERC4626(abi.decode(_extraData, (address)));
return pool.convertToAssets(ONE);
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { IERC4626 } from "../interfaces/IERC4626.sol";
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IHyperdriveTargetDeployer } from "../interfaces/IHyperdriveTargetDeployer.sol";
import { ERC4626Target0 } from "../instances/ERC4626Target0.sol";
import { ERC4626Target0 } from "../../instances/erc4626/ERC4626Target0.sol";
import { IERC4626 } from "../../interfaces/IERC4626.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol";

/// @author DELV
/// @title ERC4626Target0Deployer
/// @notice This is a minimal factory which contains only the logic to deploy
/// the target0 contract and is called by a more complex factory which
/// initializes the Hyperdrive instances and acts as a registry.
/// @dev We use two contracts to avoid any code size limit issues with Hyperdrive.
/// @notice The target0 deployer for the ERC4626Hyperdrive implementation.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
Expand All @@ -24,8 +21,8 @@ contract ERC4626Target0Deployer is IHyperdriveTargetDeployer {
IHyperdrive.PoolConfig memory _config,
bytes memory _extraData
) external override returns (address) {
(address pool, ) = abi.decode(_extraData, (address, address[]));
// Deploy the ERC4626Target0 instance.
return (address(new ERC4626Target0(_config, IERC4626(pool))));
IERC4626 pool = IERC4626(abi.decode(_extraData, (address)));
return address(new ERC4626Target0(_config, pool));
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { IERC4626 } from "../interfaces/IERC4626.sol";
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IHyperdriveTargetDeployer } from "../interfaces/IHyperdriveTargetDeployer.sol";
import { ERC4626Target1 } from "../instances/ERC4626Target1.sol";
import { ERC4626Target1 } from "../../instances/erc4626/ERC4626Target1.sol";
import { IERC4626 } from "../../interfaces/IERC4626.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol";

/// @author DELV
/// @title ERC4626Target1Deployer
/// @notice This is a minimal factory which contains only the logic to deploy
/// the target1 contract and is called by a more complex factory which
/// initializes the Hyperdrive instances and acts as a registry.
/// @dev We use two contracts to avoid any code size limit issues with Hyperdrive.
/// @notice The target1 deployer for the ERC4626Hyperdrive implementation.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
Expand All @@ -24,8 +21,8 @@ contract ERC4626Target1Deployer is IHyperdriveTargetDeployer {
IHyperdrive.PoolConfig memory _config,
bytes memory _extraData
) external override returns (address) {
(address pool, ) = abi.decode(_extraData, (address, address[]));
// Deploy the ERC4626Target1 instance.
return address(new ERC4626Target1(_config, IERC4626(pool)));
IERC4626 pool = IERC4626(abi.decode(_extraData, (address)));
return address(new ERC4626Target1(_config, pool));
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.8.19;

import { IERC4626 } from "../interfaces/IERC4626.sol";
import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IHyperdriveTargetDeployer } from "../interfaces/IHyperdriveTargetDeployer.sol";
import { ERC4626Target2 } from "../instances/ERC4626Target2.sol";
import { ERC4626Target2 } from "../../instances/erc4626/ERC4626Target2.sol";
import { IERC4626 } from "../../interfaces/IERC4626.sol";
import { IHyperdrive } from "../../interfaces/IHyperdrive.sol";
import { IHyperdriveTargetDeployer } from "../../interfaces/IHyperdriveTargetDeployer.sol";

/// @author DELV
/// @title ERC4626Target2Deployer
/// @notice This is a minimal factory which contains only the logic to deploy
/// the target2 contract and is called by a more complex factory which
/// initializes the Hyperdrive instances and acts as a registry.
/// @dev We use two contracts to avoid any code size limit issues with Hyperdrive.
/// @notice The target2 deployer for the ERC4626Hyperdrive implementation.
/// @custom:disclaimer The language used in this code is for coding convenience
/// only, and is not intended to, and does not, have any
/// particular legal or regulatory significance.
Expand All @@ -24,8 +21,8 @@ contract ERC4626Target2Deployer is IHyperdriveTargetDeployer {
IHyperdrive.PoolConfig memory _config,
bytes memory _extraData
) external override returns (address) {
(address pool, ) = abi.decode(_extraData, (address, address[]));
// Deploy the ERC4626Target2 instance.
return address(new ERC4626Target2(_config, IERC4626(pool)));
IERC4626 pool = IERC4626(abi.decode(_extraData, (address)));
return address(new ERC4626Target2(_config, pool));
}
}
Loading