Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
aa8e9a8
Some general cleanup that resulted in removing a bunch of duplicated …
jalextowle Jan 24, 2024
aa8a4f8
Interface and errors cleanup for `ForwarderFactory`
jalextowle Jan 24, 2024
be31c84
Reverted the change that removed the interface from the errors
jalextowle Jan 24, 2024
d1b4c09
Clearly documented each of the Hyperdrive errors
jalextowle Jan 25, 2024
ec8543a
Group the trading errors into an `InsufficientLiquidity` error
jalextowle Jan 25, 2024
c92336a
Replaced some of the arithmetic underflows with the insufficient liqu…
jalextowle Jan 25, 2024
aee97eb
Addressed the code size issues
jalextowle Jan 25, 2024
056ad7a
Indexed some fields of the `HyperdriveFactory` events
jalextowle Jan 25, 2024
a8b81a0
Added `minTimestretchAPR` and `maxTimestretchAPR` to the factory
jalextowle Jan 25, 2024
7db5c16
Added more safeguards to the factory and deployers
jalextowle Jan 26, 2024
690f718
Added checks for the `minimumShareReserves` and `minimumTransactionAm…
jalextowle Jan 26, 2024
915f2b1
Added guards for the time stretch APR
jalextowle Jan 26, 2024
520bcfd
Added tests for the time stretch APR passed to `deployAndInitialize`
jalextowle Jan 26, 2024
69e8d7e
Merge remote-tracking branch 'origin/main' into jalextowle/cleanup/fa…
jalextowle Jan 26, 2024
8e5c113
Fixed the post-merge issues
jalextowle Jan 26, 2024
671a4fe
merge conflicts
jrhea Jan 26, 2024
2b19035
Update contracts/src/deployers/erc4626/ERC4626HyperdriveDeployerCoord…
jrhea Jan 26, 2024
26f5583
Merge branch 'jalextowle/cleanup/factory-cleanup-pt-2' of github.com:…
jrhea Jan 26, 2024
f547dda
fix natspec
jrhea Jan 26, 2024
4fa2e4a
override number of fuzz runs
jrhea Jan 26, 2024
37dca37
update natspec
jrhea Jan 26, 2024
05eff9a
fix import
jrhea Jan 26, 2024
c288d45
removing old aavev3
jrhea Jan 26, 2024
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
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,3 @@
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/transmissions11/solmate
[submodule "lib/yield-daddy"]
path = lib/yield-daddy
url = https://github.com/timeless-fi/yield-daddy
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ abstract contract HyperdriveDeployerCoordinator is IDeployerCoordinator {
function deploy(
IHyperdrive.PoolDeployConfig memory _deployConfig,
bytes memory _extraData
) external override returns (address) {
) public virtual returns (address) {
// Convert the deploy config into the pool config and set the initial
// vault share price.
IHyperdrive.PoolConfig memory _config = _copyPoolConfig(_deployConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.19;

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

Expand Down Expand Up @@ -34,6 +35,42 @@ contract ERC4626HyperdriveDeployerCoordinator is HyperdriveDeployerCoordinator {
)
{}

/// @notice Deploys a Hyperdrive instance with the given parameters.
/// @param _deployConfig The deploy configuration of the Hyperdrive pool.
/// @param _extraData The extra data that contains the pool and sweep targets.
/// @return The address of the newly deployed ERC4626Hyperdrive Instance.
function deploy(
IHyperdrive.PoolDeployConfig memory _deployConfig,
bytes memory _extraData
) public override returns (address) {
// Ensure that the minimum share reserves are large enough to meet the
// minimum requirements for safety.
//
// NOTE: Some pools may require larger minimum share reserves to be
// considered safe. This is just a sanity check.
if (
_deployConfig.minimumShareReserves <
10 ** (_deployConfig.baseToken.decimals() - 4)
) {
revert IHyperdrive.InvalidMinimumShareReserves();
}

// Ensure that the minimum transaction amount is large enough to meet
// the minimum requirements for safety.
//
// NOTE: Some pools may require larger minimum transaction amounts to be
// considered safe. This is just a sanity check.
if (
_deployConfig.minimumShareReserves <
10 ** (_deployConfig.baseToken.decimals() - 4)
) {
revert IHyperdrive.InvalidMinimumTransactionAmount();
}

// Deploy the Hyperdrive instance.
return super.deploy(_deployConfig, _extraData);
}

/// @dev Gets the initial vault share price of the Hyperdrive pool.
/// @param _extraData The extra data passed to the child deployers.
/// @return The initial vault share price of the Hyperdrive pool.
Expand Down
145 changes: 136 additions & 9 deletions contracts/src/factory/HyperdriveFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { IHyperdrive } from "../interfaces/IHyperdrive.sol";
import { IHyperdriveFactory } from "../interfaces/IHyperdriveFactory.sol";
import { IDeployerCoordinator } from "../interfaces/IDeployerCoordinator.sol";
import { FixedPointMath, ONE } from "../libraries/FixedPointMath.sol";
import { HyperdriveMath } from "../libraries/HyperdriveMath.sol";

/// @author DELV
/// @title HyperdriveFactory
Expand Down Expand Up @@ -61,6 +62,18 @@ contract HyperdriveFactory is IHyperdriveFactory {
/// deployments.
uint256 public maxPositionDuration;

/// @notice The minimum fixed APR that can be used by new deployments.
uint256 public minFixedAPR;

/// @notice The maximum fixed APR that can be used by new deployments.
uint256 public maxFixedAPR;

/// @notice The minimum time stretch APR that can be used by new deployments.
uint256 public minTimeStretchAPR;

/// @notice The maximum time stretch APR that can be used by new deployments.
uint256 public maxTimeStretchAPR;

/// @notice The minimum fee parameters that can be used by new deployments.
IHyperdrive.Fees internal _minFees;

Expand Down Expand Up @@ -93,6 +106,16 @@ contract HyperdriveFactory is IHyperdriveFactory {
/// @dev The maximum position duration that can be used in new
/// deployments.
uint256 maxPositionDuration;
/// @dev The minimum fixed APR that can be used in new deployments.
uint256 minFixedAPR;
/// @dev The maximum fixed APR that can be used in new deployments.
uint256 maxFixedAPR;
/// @dev The minimum time stretch APR that can be used in new
/// deployments.
uint256 minTimeStretchAPR;
/// @dev The maximum time stretch APR that can be used in new
/// deployments.
uint256 maxTimeStretchAPR;
/// @dev The lower bound on the fees that can be used in new deployments.
IHyperdrive.Fees minFees;
/// @dev The upper bound on the fees that can be used in new deployments.
Expand Down Expand Up @@ -175,6 +198,24 @@ contract HyperdriveFactory is IHyperdriveFactory {
}
maxPositionDuration = _factoryConfig.maxPositionDuration;

// Ensure that the minimum fixed APR is less than or equal to the
// maximum fixed APR.
if (_factoryConfig.minFixedAPR > _factoryConfig.maxFixedAPR) {
revert IHyperdriveFactory.InvalidFixedAPR();
}
minFixedAPR = _factoryConfig.minFixedAPR;
maxFixedAPR = _factoryConfig.maxFixedAPR;

// Ensure that the minimum time stretch APR is less than or equal to the
// maximum time stretch APR.
if (
_factoryConfig.minTimeStretchAPR > _factoryConfig.maxTimeStretchAPR
) {
revert IHyperdriveFactory.InvalidTimeStretchAPR();
}
minTimeStretchAPR = _factoryConfig.minTimeStretchAPR;
maxTimeStretchAPR = _factoryConfig.maxTimeStretchAPR;

// Ensure that the max fees are each less than or equal to 100% and set
// the fees.
if (
Expand Down Expand Up @@ -373,6 +414,66 @@ contract HyperdriveFactory is IHyperdriveFactory {
emit MinPositionDurationUpdated(_minPositionDuration);
}

/// @notice Allows governance to update the maximum fixed APR.
/// @param _maxFixedAPR The new maximum fixed APR.
function updateMaxFixedAPR(uint256 _maxFixedAPR) external onlyGovernance {
// Ensure that the maximum fixed APR is greater than or equal to the
// minimum fixed APR.
if (_maxFixedAPR < minFixedAPR) {
revert IHyperdriveFactory.InvalidMaxFixedAPR();
}

// Update the maximum fixed APR and emit an event.
maxFixedAPR = _maxFixedAPR;
emit MaxFixedAPRUpdated(_maxFixedAPR);
}

/// @notice Allows governance to update the minimum fixed APR.
/// @param _minFixedAPR The new minimum fixed APR.
function updateMinFixedAPR(uint256 _minFixedAPR) external onlyGovernance {
// Ensure that the minimum fixed APR is less than or equal to the
// maximum fixed APR.
if (_minFixedAPR > maxFixedAPR) {
revert IHyperdriveFactory.InvalidMinFixedAPR();
}

// Update the minimum fixed APR and emit an event.
minFixedAPR = _minFixedAPR;
emit MinFixedAPRUpdated(_minFixedAPR);
}

/// @notice Allows governance to update the maximum time stretch APR.
/// @param _maxTimeStretchAPR The new maximum time stretch APR.
function updateMaxTimeStretchAPR(
uint256 _maxTimeStretchAPR
) external onlyGovernance {
// Ensure that the maximum time stretch APR is greater than or equal
// to the minimum time stretch APR.
if (_maxTimeStretchAPR < minTimeStretchAPR) {
revert IHyperdriveFactory.InvalidMaxTimeStretchAPR();
}

// Update the maximum time stretch APR and emit an event.
maxTimeStretchAPR = _maxTimeStretchAPR;
emit MaxTimeStretchAPRUpdated(_maxTimeStretchAPR);
}

/// @notice Allows governance to update the minimum time stretch APR.
/// @param _minTimeStretchAPR The new minimum time stretch APR.
function updateMinTimeStretchAPR(
uint256 _minTimeStretchAPR
) external onlyGovernance {
// Ensure that the minimum time stretch APR is less than or equal
// to the maximum time stretch APR.
if (_minTimeStretchAPR > maxTimeStretchAPR) {
revert IHyperdriveFactory.InvalidMinTimeStretchAPR();
}

// Update the minimum time stretch APR and emit an event.
minTimeStretchAPR = _minTimeStretchAPR;
emit MinTimeStretchAPRUpdated(_minTimeStretchAPR);
}

/// @notice Allows governance to update the maximum fee parameters.
/// @param __maxFees The new maximum fee parameters.
function updateMaxFees(
Expand Down Expand Up @@ -472,16 +573,18 @@ contract HyperdriveFactory is IHyperdriveFactory {
/// @param _deployConfig The deploy configuration of the Hyperdrive pool.
/// @param _extraData The extra data that contains data necessary for the
/// specific deployer.
/// @param _contribution Base token to call init with
/// @param _apr The apr to call init with
/// @param _contribution The contribution amount in base to the pool.
/// @param _fixedAPR The fixed APR used to initialize the pool.
/// @param _timeStretchAPR The time stretch APR used to initialize the pool.
/// @param _initializeExtraData The extra data for the `initialize` call.
/// @return The hyperdrive address deployed.
function deployAndInitialize(
address _deployerCoordinator,
IHyperdrive.PoolDeployConfig memory _deployConfig,
bytes memory _extraData,
uint256 _contribution,
uint256 _apr,
uint256 _fixedAPR,
uint256 _timeStretchAPR,
bytes memory _initializeExtraData
) public payable virtual returns (IHyperdrive) {
// Ensure that the target deployer has been registered.
Expand Down Expand Up @@ -530,22 +633,46 @@ contract HyperdriveFactory is IHyperdriveFactory {
// and governance addresses aren't set. This ensures that the
// deployer isn't trying to set these values.
if (
_deployConfig.governance != address(0) ||
_deployConfig.feeCollector != address(0) ||
_deployConfig.linkerFactory != address(0) ||
_deployConfig.linkerCodeHash != bytes32(0) ||
_deployConfig.feeCollector != address(0) ||
_deployConfig.governance != address(0)
_deployConfig.timeStretch != 0
) {
revert IHyperdriveFactory.InvalidDeployConfig();
}

// Ensure that specified fixed APR is within the minimum and maximum
// fixed APRs.
if (_fixedAPR < minFixedAPR || _fixedAPR > maxFixedAPR) {
revert IHyperdriveFactory.InvalidFixedAPR();
}

// Calculate the time stretch using the provided APR and ensure that
// the time stretch falls within a safe range and the guards specified
// by governance.
uint256 lowerBound = _fixedAPR.divDown(2e18).max(0.005e18);
if (
_timeStretchAPR < minTimeStretchAPR.max(lowerBound) ||
_timeStretchAPR >
maxTimeStretchAPR.min(_fixedAPR.max(lowerBound).mulDown(2e18))
) {
revert IHyperdriveFactory.InvalidTimeStretchAPR();
}
uint256 timeStretch = HyperdriveMath.calculateTimeStretch(
_timeStretchAPR,
_deployConfig.positionDuration
);

// Override the config values to the default values set by governance.
// The factory assumes the governance role during deployment so that it
// can set up some initial values; however the governance role will
// ultimately be transferred to the hyperdrive governance address.
_deployConfig.governance = address(this);
_deployConfig.feeCollector = feeCollector;
_deployConfig.linkerFactory = linkerFactory;
_deployConfig.linkerCodeHash = linkerCodeHash;
_deployConfig.feeCollector = feeCollector;
_deployConfig.governance = address(this);
_deployConfig.timeStretch = timeStretch;

// Deploy the Hyperdrive instance with the specified Hyperdrive
// deployer.
Expand Down Expand Up @@ -581,7 +708,7 @@ contract HyperdriveFactory is IHyperdriveFactory {
// Initialize the Hyperdrive instance.
hyperdrive.initialize{ value: _contribution }(
_contribution,
_apr,
_fixedAPR,
IHyperdrive.Options({
destination: msg.sender,
asBase: true,
Expand All @@ -607,7 +734,7 @@ contract HyperdriveFactory is IHyperdriveFactory {
// Initialize the Hyperdrive instance.
hyperdrive.initialize(
_contribution,
_apr,
_fixedAPR,
IHyperdrive.Options({
destination: msg.sender,
asBase: true,
Expand Down
6 changes: 6 additions & 0 deletions contracts/src/instances/steth/StETHBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ abstract contract StETHBase is HyperdriveBase {
if (_minimumShareReserves != 1e15) {
revert IHyperdrive.InvalidMinimumShareReserves();
}

// Ensure that the minimum transaction amount are equal to 1e15. This
// value has been tested to prevent precision issues.
if (_minimumTransactionAmount != 1e15) {
revert IHyperdrive.InvalidMinimumTransactionAmount();
}
}

/// Yield Source ///
Expand Down
3 changes: 3 additions & 0 deletions contracts/src/interfaces/IHyperdrive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ interface IHyperdrive is
/// reserves.
error InvalidMinimumShareReserves();

/// @notice Thrown when the minimum transaction amount is too small.
error InvalidMinimumTransactionAmount();

/// @notice Thrown when the position duration is smaller than the checkpoint
/// duration or is not a multiple of the checkpoint duration.
error InvalidPositionDuration();
Expand Down
20 changes: 20 additions & 0 deletions contracts/src/interfaces/IHyperdriveFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ interface IHyperdriveFactory {

event MinPositionDurationUpdated(uint256 newMinPositionDuration);

event MaxFixedAPRUpdated(uint256 newMaxFixedAPR);

event MinFixedAPRUpdated(uint256 newMinFixedAPR);

event MaxTimeStretchAPRUpdated(uint256 newMaxTimeStretchAPR);

event MinTimeStretchAPRUpdated(uint256 newMinTimeStretchAPR);

event MaxFeesUpdated(IHyperdrive.Fees newMaxFees);

event MinFeesUpdated(IHyperdrive.Fees newMinFees);
Expand Down Expand Up @@ -83,6 +91,18 @@ interface IHyperdriveFactory {

error InvalidPositionDuration();

error InvalidMaxFixedAPR();

error InvalidMinFixedAPR();

error InvalidFixedAPR();

error InvalidMaxTimeStretchAPR();

error InvalidMinTimeStretchAPR();

error InvalidTimeStretchAPR();

error TransferFailed();

error Unauthorized();
Expand Down
Loading