From 6852203b84991e87ca9d595d33a6f9c63eaca14c Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Wed, 21 Feb 2024 20:06:59 -0600 Subject: [PATCH 1/3] Avoided double-counting the fee in `openLong` --- contracts/src/internal/HyperdriveLong.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/src/internal/HyperdriveLong.sol b/contracts/src/internal/HyperdriveLong.sol index a0e522976..31cdac779 100644 --- a/contracts/src/internal/HyperdriveLong.sol +++ b/contracts/src/internal/HyperdriveLong.sol @@ -389,7 +389,7 @@ abstract contract HyperdriveLong is IHyperdriveEvents, HyperdriveLP { { // Calculate the effect that opening the long should have on the pool's // reserves as well as the amount of bond the trader receives. - bondReservesDelta = HyperdriveMath.calculateOpenLong( + bondProceeds = HyperdriveMath.calculateOpenLong( _effectiveShareReserves(), _marketState.bondReserves, _shareAmount, // amountIn @@ -409,7 +409,7 @@ abstract contract HyperdriveLong is IHyperdriveEvents, HyperdriveLP { if ( _isNegativeInterest( _shareAmount, - bondReservesDelta, + bondProceeds, HyperdriveMath.calculateOpenLongMaxSpotPrice( spotPrice, _curveFee, @@ -433,7 +433,7 @@ abstract contract HyperdriveLong is IHyperdriveEvents, HyperdriveLP { _vaultSharePrice ); - // Calculate the impact of the curve fee on the bond reservse. The curve + // Calculate the impact of the curve fee on the bond reserves. The curve // fee benefits the LPs by causing less bonds to be deducted from the // bond reserves. bondReservesDelta -= curveFee; From 786948cc65b356c9b2ca56f41b2bfd174ef2289a Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Wed, 21 Feb 2024 20:11:07 -0600 Subject: [PATCH 2/3] Renamed `bondProceeds` to `bondReservesDelta` for consistency in `openLong` --- contracts/src/internal/HyperdriveLong.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/src/internal/HyperdriveLong.sol b/contracts/src/internal/HyperdriveLong.sol index 31cdac779..6ef39cf34 100644 --- a/contracts/src/internal/HyperdriveLong.sol +++ b/contracts/src/internal/HyperdriveLong.sol @@ -389,7 +389,7 @@ abstract contract HyperdriveLong is IHyperdriveEvents, HyperdriveLP { { // Calculate the effect that opening the long should have on the pool's // reserves as well as the amount of bond the trader receives. - bondProceeds = HyperdriveMath.calculateOpenLong( + bondReservesDelta = HyperdriveMath.calculateOpenLong( _effectiveShareReserves(), _marketState.bondReserves, _shareAmount, // amountIn @@ -409,7 +409,7 @@ abstract contract HyperdriveLong is IHyperdriveEvents, HyperdriveLP { if ( _isNegativeInterest( _shareAmount, - bondProceeds, + bondReservesDelta, HyperdriveMath.calculateOpenLongMaxSpotPrice( spotPrice, _curveFee, From 2929b055c723d70816c17404fd2c901129f5fd20 Mon Sep 17 00:00:00 2001 From: Alex Towle Date: Mon, 26 Feb 2024 15:12:37 -0600 Subject: [PATCH 3/3] Added a conservative negative interest check for `openLong` --- contracts/src/internal/HyperdriveLong.sol | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/contracts/src/internal/HyperdriveLong.sol b/contracts/src/internal/HyperdriveLong.sol index 6ef39cf34..7ff3b6751 100644 --- a/contracts/src/internal/HyperdriveLong.sol +++ b/contracts/src/internal/HyperdriveLong.sol @@ -460,6 +460,23 @@ abstract contract HyperdriveLong is IHyperdriveEvents, HyperdriveLP { // shares = shares - shares shareReservesDelta = _shareAmount - totalGovernanceFee; + // Ensure that the ending spot price is less than or equal to one. + // Despite the fact that the earlier negative interest check should + // imply this, we perform this check out of an abundance of caution + // since the `pow` function is known to not be monotonic. + if ( + HyperdriveMath.calculateSpotPrice( + _effectiveShareReserves() + shareReservesDelta, + _marketState.bondReserves - bondReservesDelta, + _initialVaultSharePrice, + _timeStretch + ) > ONE + ) { + Errors.throwInsufficientLiquidityError( + IHyperdrive.InsufficientLiquidityReason.NegativeInterest + ); + } + return (shareReservesDelta, bondReservesDelta, totalGovernanceFee); }