Skip to content

Commit

Permalink
Added guards for the circuit breaker delta to the HyperdriveFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
jalextowle committed May 2, 2024
1 parent 9c80061 commit 1477719
Show file tree
Hide file tree
Showing 19 changed files with 334 additions and 33 deletions.
6 changes: 1 addition & 5 deletions contracts/src/deployers/HyperdriveDeployerCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { IHyperdriveTargetDeployer } from "../interfaces/IHyperdriveTargetDeploy
import { VERSION } from "../libraries/Constants.sol";
import { ONE } from "../libraries/FixedPointMath.sol";

// FIXME: Add the maximumAddLiquidityAPRDelta to `deployAndInitialize`. We need
// min and max parameters for this delta.
//
/// @author DELV
/// @title HyperdriveDeployerCoordinator
/// @notice This Hyperdrive deployer coordinates the process of deploying the
Expand Down Expand Up @@ -505,8 +502,7 @@ abstract contract HyperdriveDeployerCoordinator is
_config.minimumShareReserves = _deployConfig.minimumShareReserves;
_config.minimumTransactionAmount = _deployConfig
.minimumTransactionAmount;
_config.maximumAddLiquidityAPRDelta = _deployConfig
.maximumAddLiquidityAPRDelta;
_config.circuitBreakerDelta = _deployConfig.circuitBreakerDelta;
_config.positionDuration = _deployConfig.positionDuration;
_config.checkpointDuration = _deployConfig.checkpointDuration;
_config.timeStretch = _deployConfig.timeStretch;
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/external/HyperdriveTarget0.sol
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ abstract contract HyperdriveTarget0 is
initialVaultSharePrice: _initialVaultSharePrice,
minimumShareReserves: _minimumShareReserves,
minimumTransactionAmount: _minimumTransactionAmount,
maximumAddLiquidityAPRDelta: _maximumAddLiquidityAPRDelta,
circuitBreakerDelta: _circuitBreakerDelta,
positionDuration: _positionDuration,
checkpointDuration: _checkpointDuration,
timeStretch: _timeStretch,
Expand Down
71 changes: 68 additions & 3 deletions contracts/src/factory/HyperdriveFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { FixedPointMath, ONE } from "../libraries/FixedPointMath.sol";
import { VERSION } from "../libraries/Constants.sol";
import { HyperdriveMath } from "../libraries/HyperdriveMath.sol";

// FIXME: Add the maximumAddLiquidityAPRDelta to `deployAndInitialize`. We need
// min and max parameters for this delta.
//
/// @author DELV
/// @title HyperdriveFactory
/// @notice Deploys hyperdrive instances and initializes them. It also holds a
Expand Down Expand Up @@ -76,6 +73,14 @@ contract HyperdriveFactory is IHyperdriveFactory {
/// deployments.
uint256 public maxPositionDuration;

/// @notice The minimum circuit breaker delta that can be used by
/// new deployments.
uint256 public minCircuitBreakerDelta;

/// @notice The maximum circuit breaker delta that can be used by
/// new deployments.
uint256 public maxCircuitBreakerDelta;

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

Expand Down Expand Up @@ -122,6 +127,12 @@ contract HyperdriveFactory is IHyperdriveFactory {
/// @dev The maximum position duration that can be used in new
/// deployments.
uint256 maxPositionDuration;
/// @dev The minimum circuit breaker delta that can be used in new
/// deployments.
uint256 minCircuitBreakerDelta;
/// @dev The maximum circuit breaker delta that can be used in new
/// deployments.
uint256 maxCircuitBreakerDelta;
/// @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.
Expand Down Expand Up @@ -236,6 +247,17 @@ contract HyperdriveFactory is IHyperdriveFactory {
}
maxPositionDuration = _factoryConfig.maxPositionDuration;

// Ensure that the minimum circuit breaker delta is greater than or
// equal to the maximum circuit breaker delta.
if (
_factoryConfig.minCircuitBreakerDelta >
_factoryConfig.maxCircuitBreakerDelta
) {
revert IHyperdriveFactory.InvalidCircuitBreakerDelta();
}
minCircuitBreakerDelta = _factoryConfig.minCircuitBreakerDelta;
maxCircuitBreakerDelta = _factoryConfig.maxCircuitBreakerDelta;

// Ensure that the minimum fixed APR is less than or equal to the
// maximum fixed APR.
if (_factoryConfig.minFixedAPR > _factoryConfig.maxFixedAPR) {
Expand Down Expand Up @@ -470,6 +492,40 @@ contract HyperdriveFactory is IHyperdriveFactory {
emit MinPositionDurationUpdated(_minPositionDuration);
}

/// @notice Allows governance to update the maximum circuit breaker delta.
/// @param _maxCircuitBreakerDelta The new maximum circuit breaker delta.
function updateMaxCircuitBreakerDelta(
uint256 _maxCircuitBreakerDelta
) external onlyGovernance {
// Ensure that the maximum circuit breaker delta is greater than or
// equal to the minimum circuit breaker delta.
if (_maxCircuitBreakerDelta < minCircuitBreakerDelta) {
revert IHyperdriveFactory.InvalidMaxCircuitBreakerDelta();
}

// Update the maximum circuit breaker delta and emit an event.
maxCircuitBreakerDelta = _maxCircuitBreakerDelta;
emit MaxCircuitBreakerDeltaUpdated(_maxCircuitBreakerDelta);
}

/// @notice Allows governance to update the minimum circuit breaker delta.
/// @param _minCircuitBreakerDelta The new minimum circuit breaker delta.
function updateMinCircuitBreakerDelta(
uint256 _minCircuitBreakerDelta
) external onlyGovernance {
// Ensure that the minimum position duration is greater than or equal
// to the maximum checkpoint duration and is a multiple of the
// checkpoint duration resolution. Also ensure that the minimum position
// duration is less than or equal to the maximum position duration.
if (_minCircuitBreakerDelta > maxCircuitBreakerDelta) {
revert IHyperdriveFactory.InvalidMinCircuitBreakerDelta();
}

// Update the minimum circuit breaker delta and emit an event.
minCircuitBreakerDelta = _minCircuitBreakerDelta;
emit MinCircuitBreakerDeltaUpdated(_minCircuitBreakerDelta);
}

/// @notice Allows governance to update the maximum fixed APR.
/// @param _maxFixedAPR The new maximum fixed APR.
function updateMaxFixedAPR(uint256 _maxFixedAPR) external onlyGovernance {
Expand Down Expand Up @@ -902,6 +958,15 @@ contract HyperdriveFactory is IHyperdriveFactory {
revert IHyperdriveFactory.InvalidPositionDuration();
}

// Ensure that the specified circuit breaker delta is within the minimum
// and maximum circuit breaker deltas.
if (
_config.circuitBreakerDelta < minCircuitBreakerDelta ||
_config.circuitBreakerDelta > maxCircuitBreakerDelta
) {
revert IHyperdriveFactory.InvalidCircuitBreakerDelta();
}

// Ensure that the specified fees are within the minimum and maximum
// fees. The flat fee is annualized so that it is consistent across all
// term lengths.
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/interfaces/IHyperdrive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ interface IHyperdrive is
/// @dev The maximum delta between the last checkpoint's weighted spot
/// APR and the current spot APR for an LP to add liquidity. This
/// protects LPs from sandwich attacks.
uint256 maximumAddLiquidityAPRDelta;
uint256 circuitBreakerDelta;
/// @dev The duration of a position prior to maturity.
uint256 positionDuration;
/// @dev The duration of a checkpoint.
Expand Down Expand Up @@ -130,7 +130,7 @@ interface IHyperdrive is
/// @dev The maximum delta between the last checkpoint's weighted spot
/// APR and the current spot APR for an LP to add liquidity. This
/// protects LPs from sandwich attacks.
uint256 maximumAddLiquidityAPRDelta;
uint256 circuitBreakerDelta;
/// @dev The duration of a position prior to maturity.
uint256 positionDuration;
/// @dev The duration of a checkpoint.
Expand Down
21 changes: 21 additions & 0 deletions contracts/src/interfaces/IHyperdriveFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ interface IHyperdriveFactory {
/// @notice Emitted when the minimum position duration is updated.
event MinPositionDurationUpdated(uint256 newMinPositionDuration);

/// @notice Emitted when the maximum circuit breaker delta is updated.
event MaxCircuitBreakerDeltaUpdated(uint256 newMaxCircuitBreakerDelta);

/// @notice Emitted when the minimum circuit breaker delta is updated.
event MinCircuitBreakerDeltaUpdated(uint256 newMinCircuitBreakerDelta);

/// @notice Emitted when the maximum fixed APR is updated.
event MaxFixedAPRUpdated(uint256 newMaxFixedAPR);

Expand Down Expand Up @@ -168,6 +174,21 @@ interface IHyperdriveFactory {
/// maximum position durations.
error InvalidPositionDuration();

/// @notice Thrown when governance attempts to set the maximum circuit
/// breaker delta to a value that is less than the minimum
/// circuit breaker delta.
error InvalidMaxCircuitBreakerDelta();

/// @notice Thrown when governance attempts to set the minimum circuit
/// breaker delta to a value that is greater than the maximum
/// circuit breaker delta.
error InvalidMinCircuitBreakerDelta();

/// @notice Thrown when the circuit breaker delta passed to
/// `deployAndInitialize` doesn't fall within the range specified by
/// the minimum and maximum circuit breaker delta.
error InvalidCircuitBreakerDelta();

/// @notice Thrown when governance attempts to set the maximum fixed APR to
/// a value that is smaller than the minimum fixed APR.
error InvalidMaxFixedAPR();
Expand Down
11 changes: 3 additions & 8 deletions contracts/src/internal/HyperdriveLP.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ abstract contract HyperdriveLP is
using SafeCast for int256;
using SafeCast for uint256;

// FIXME: Make sure this checkpoint's and the previous checkpoint's weighted
// spot prices are set to non-zero values.
//
/// @dev Allows the first LP to initialize the market with a target APR.
/// @param _contribution The amount of capital to supply. The units of this
/// quantity are either base or vault shares, depending on the value
Expand Down Expand Up @@ -146,8 +143,6 @@ abstract contract HyperdriveLP is
return lpShares;
}

// FIXME: Add circuit breakers.
//
/// @dev Allows LPs to supply liquidity for LP shares.
/// @param _contribution The amount of capital to supply. The units of this
/// quantity are either base or vault shares, depending on the value
Expand Down Expand Up @@ -215,9 +210,9 @@ abstract contract HyperdriveLP is
_positionDuration
);
if (
apr > weightedSpotAPR + _maximumAddLiquidityAPRDelta ||
(weightedSpotAPR > _maximumAddLiquidityAPRDelta &&
apr < weightedSpotAPR - _maximumAddLiquidityAPRDelta)
apr > weightedSpotAPR + _circuitBreakerDelta ||
(weightedSpotAPR > _circuitBreakerDelta &&
apr < weightedSpotAPR - _circuitBreakerDelta)
) {
revert IHyperdrive.CircuitBreakerTriggered();
}
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/internal/HyperdriveStorage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ abstract contract HyperdriveStorage is ReentrancyGuard {
/// @dev The maximum delta between the last checkpoint's weighted spot APR
/// and the current spot APR for an LP to add liquidity. This protects
/// LPs from sandwich attacks.
uint256 internal immutable _maximumAddLiquidityAPRDelta;
uint256 internal immutable _circuitBreakerDelta;

/// @dev The state of the market. This includes the reserves, buffers, and
/// other data used to price trades and maintain solvency.
Expand Down Expand Up @@ -159,7 +159,7 @@ abstract contract HyperdriveStorage is ReentrancyGuard {
// spot APR and the weighted spot APR from the last checkpoint for an
// LP to add liquidity. This mitigates the possibility of LP sandwich
// attacks by making them economically infeasible to pull off.
_maximumAddLiquidityAPRDelta = _config.maximumAddLiquidityAPRDelta;
_circuitBreakerDelta = _config.circuitBreakerDelta;

// Initialize the time configurations. There must be at least one
// checkpoint per term to avoid having a position duration of zero.
Expand Down
10 changes: 7 additions & 3 deletions test/instances/erc4626/ERC4626Hyperdrive.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
maxCheckpointDuration: 1 days,
minPositionDuration: 7 days,
maxPositionDuration: 10 * 365 days,
minCircuitBreakerDelta: 0.15e18,
// NOTE: This is a high max circuit breaker delta to ensure that
// trading during tests isn't impeded by the circuit breaker.
maxCircuitBreakerDelta: 2e18,
minFixedAPR: 0.001e18,
maxFixedAPR: 0.5e18,
minTimeStretchAPR: 0.005e18,
Expand Down Expand Up @@ -141,7 +145,7 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
initialVaultSharePrice: ONE,
minimumShareReserves: ONE,
minimumTransactionAmount: 0.001e18,
maximumAddLiquidityAPRDelta: 1e18,
circuitBreakerDelta: 1e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: ONE.divDown(22.186877016851916266e18),
Expand Down Expand Up @@ -325,7 +329,7 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
linkerCodeHash: factory.linkerCodeHash(),
minimumShareReserves: ONE,
minimumTransactionAmount: 0.001e18,
maximumAddLiquidityAPRDelta: 2e18,
circuitBreakerDelta: 2e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: 0,
Expand Down Expand Up @@ -447,7 +451,7 @@ contract ERC4626HyperdriveTest is HyperdriveTest {
linkerCodeHash: factory.linkerCodeHash(),
minimumShareReserves: ONE,
minimumTransactionAmount: 0.001e18,
maximumAddLiquidityAPRDelta: 2e18,
circuitBreakerDelta: 2e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: 0,
Expand Down
4 changes: 4 additions & 0 deletions test/instances/erc4626/ERC4626Validation.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ abstract contract ERC4626ValidationTest is HyperdriveTest {
maxCheckpointDuration: 1 days,
minPositionDuration: 7 days,
maxPositionDuration: 10 * 365 days,
minCircuitBreakerDelta: 0.15e18,
// NOTE: This is a high max circuit breaker delta to ensure that
// trading during tests isn't impeded by the circuit breaker.
maxCircuitBreakerDelta: 2e18,
minFixedAPR: 0.001e18,
maxFixedAPR: 0.5e18,
minTimeStretchAPR: 0.005e18,
Expand Down
2 changes: 1 addition & 1 deletion test/instances/erc4626/Sweep.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ contract SweepTest is BaseTest, IHyperdriveEvents {
initialVaultSharePrice: ONE,
minimumShareReserves: ONE,
minimumTransactionAmount: 0.001e18,
maximumAddLiquidityAPRDelta: 1e18,
circuitBreakerDelta: 1e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveMath.calculateTimeStretch(0.01e18, 365 days),
Expand Down
4 changes: 4 additions & 0 deletions test/instances/erc4626/UsdcERC4626.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ contract UsdcERC4626 is ERC4626ValidationTest {
maxCheckpointDuration: 1 days,
minPositionDuration: 7 days,
maxPositionDuration: 10 * 365 days,
minCircuitBreakerDelta: 0.15e18,
// NOTE: This is a high max circuit breaker delta to ensure that
// trading during tests isn't impeded by the circuit breaker.
maxCircuitBreakerDelta: 2e18,
minFixedAPR: 0.001e18,
maxFixedAPR: 0.5e18,
minTimeStretchAPR: 0.005e18,
Expand Down
2 changes: 1 addition & 1 deletion test/instances/steth/Sweep.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ contract SweepTest is BaseTest, IHyperdriveEvents {
initialVaultSharePrice: ONE,
minimumShareReserves: 1e15,
minimumTransactionAmount: 1e15,
maximumAddLiquidityAPRDelta: 1e18,
circuitBreakerDelta: 1e18,
positionDuration: 365 days,
checkpointDuration: 1 days,
timeStretch: HyperdriveMath.calculateTimeStretch(0.01e18, 365 days),
Expand Down
2 changes: 2 additions & 0 deletions test/integrations/deployers/ERC4626DeployerCoordinator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ contract ERC4626DeployerCoordinatorTest is DeployerCoordinatorTest {
maxCheckpointDuration: 1 days,
minPositionDuration: 7 days,
maxPositionDuration: 10 * 365 days,
minCircuitBreakerDelta: 0.15e18,
maxCircuitBreakerDelta: 0.6e18,
minFixedAPR: 0.001e18,
maxFixedAPR: 0.5e18,
minTimeStretchAPR: 0.005e18,
Expand Down
2 changes: 2 additions & 0 deletions test/integrations/deployers/RethDeployerCoordinator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ contract RethDeployerCoordinatorTest is DeployerCoordinatorTest {
maxCheckpointDuration: 1 days,
minPositionDuration: 7 days,
maxPositionDuration: 10 * 365 days,
minCircuitBreakerDelta: 0.15e18,
maxCircuitBreakerDelta: 0.6e18,
minFixedAPR: 0.001e18,
maxFixedAPR: 0.5e18,
minTimeStretchAPR: 0.005e18,
Expand Down
2 changes: 2 additions & 0 deletions test/integrations/deployers/StethDeployerCoordinator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ contract StethDeployerCoordinatorTest is DeployerCoordinatorTest {
maxCheckpointDuration: 1 days,
minPositionDuration: 7 days,
maxPositionDuration: 10 * 365 days,
minCircuitBreakerDelta: 0.15e18,
maxCircuitBreakerDelta: 0.6e18,
minFixedAPR: 0.001e18,
maxFixedAPR: 0.5e18,
minTimeStretchAPR: 0.005e18,
Expand Down
Loading

0 comments on commit 1477719

Please sign in to comment.