Skip to content

Commit

Permalink
implement spearbit suggested optimizations (#572)
Browse files Browse the repository at this point in the history
implement code optimizations from spearbit
  • Loading branch information
jrhea committed Aug 31, 2023
1 parent 662cc79 commit 7ff8680
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 46 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/rust_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
jobs:
test:
name: rust test
runs-on: ubuntu-latest
runs-on: ubuntu-latest-m
steps:
- uses: actions/checkout@v3
with:
Expand All @@ -30,4 +30,4 @@ jobs:
override: true

- name: test cargo
run: cargo test
run: export HYPERDRIVE_FAST_FUZZ_RUNS=100 && export RUSTUP_INIT_SKIP_PATH_CHECK=yes && curl https://sh.rustup.rs -sSf | sh -s -- -y && source $HOME/.cargo/env && rustup default nightly && cargo test
2 changes: 1 addition & 1 deletion .github/workflows/solidity_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
jobs:
test:
name: solidity test
runs-on: ubuntu-latest
runs-on: ubuntu-latest-m
env:
GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }}
MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }}
Expand Down
4 changes: 2 additions & 2 deletions contracts/src/Hyperdrive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ abstract contract Hyperdrive is
_checkpointTime
];
if (checkpoint_.sharePrice != 0 || _checkpointTime > block.timestamp) {
return _checkpoints[_checkpointTime].sharePrice;
return checkpoint_.sharePrice;
}

// Create the share price checkpoint.
Expand Down Expand Up @@ -157,6 +157,6 @@ abstract contract Hyperdrive is
);
}

return checkpoint_.sharePrice;
return _sharePrice;
}
}
12 changes: 4 additions & 8 deletions contracts/src/HyperdriveBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ abstract contract HyperdriveBase is MultiToken, HyperdriveStorage {
/// @param _spotPrice The price without slippage of bonds in terms of base (base/bonds).
/// @param _sharePrice The current price of shares in terms of base (base/shares).
/// @return totalCurveFee The total curve fee. The fee is in terms of bonds.
/// @return governanceCurveFee The curve fee that goes to governance. The fee is in terms of base.
/// @return governanceCurveFee The curve fee that goes to governance. The fee is in terms of bonds.
function _calculateFeesOutGivenSharesIn(
uint256 _amountIn,
uint256 _spotPrice,
Expand Down Expand Up @@ -281,14 +281,10 @@ abstract contract HyperdriveBase is MultiToken, HyperdriveStorage {
.mulDown(_sharePrice)
.mulDown(_amountIn);

// We need the governance fee in terms of base, so we multiply
// the total curve fee by the spot price (base/bonds):
// We leave the governance fee in terms of bonds:
// governanceCurveFee = total_curve_fee * p * phi_gov
// = bonds * base/bonds * phi_gov
// = base * phi_gov
governanceCurveFee = totalCurveFee.mulDown(_spotPrice).mulDown(
_governanceFee
);
// = bonds * phi_gov
governanceCurveFee = totalCurveFee.mulDown(_governanceFee);
}

/// @dev Calculates the fees that go to the LPs and governance.
Expand Down
2 changes: 1 addition & 1 deletion contracts/src/HyperdriveDataProvider.sol
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ abstract contract HyperdriveDataProvider is
uint256 deltaSum = uint256(currentData.data) - uint256(oldData.data);
uint256 deltaTime = uint256(currentData.timestamp) -
uint256(oldData.timestamp);
_revert(abi.encode(deltaSum.divDown(deltaTime * 1e18)));
_revert(abi.encode(deltaSum / deltaTime));
}
}
40 changes: 19 additions & 21 deletions contracts/src/HyperdriveLong.sol
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ abstract contract HyperdriveLong is HyperdriveLP {
// fees that are paid to governance (governanceCurveFee).
(
uint256 totalCurveFee, // bonds
uint256 governanceCurveFee // base
uint256 governanceCurveFee // bonds
) = _calculateFeesOutGivenSharesIn(
_shareAmount,
spotPrice,
Expand All @@ -445,30 +445,28 @@ abstract contract HyperdriveLong is HyperdriveLP {
// receives plus the number of bonds we need to pay to governance.
// In other words, we want to keep the totalCurveFee in the bondReserves; however,
// since the governanceCurveFee will be paid from the sharesReserves we don't
// need it removed from the bondReserves. bondProceeds is in bonds
// and governanceCurveFee is in base so we divide it by the spot price
// to convert it to bonds:
// bonds = bonds + base/(base/bonds)
// need it removed from the bondReserves. bondProceeds and governanceCurveFee
// are already in bonds so no conversion is needed.
// bonds = bonds + bonds
bondReservesDelta =
bondProceeds +
governanceCurveFee.divDown(spotPrice);
bondReservesDelta = bondProceeds + governanceCurveFee;

// Calculate the fees owed to governance in shares. Open longs
// are calculated entirely on the curve so the curve fee is the
// total governance fee. In order to convert it to shares we need to
// multiply it by the spot price and divide it by the share price:
// shares = (bonds * base/bonds) / (base/shares)
// shares = bonds * shares/bonds
// shares = shares
totalGovernanceFee = governanceCurveFee.mulDivDown(
spotPrice,
_sharePrice
);

// Calculate the number of shares to add to the shareReserves.
// shareReservesDelta and totalGovernanceFee denominated in
// shares so we divide governanceCurveFee by the share price (base/shares)
// to convert it to shares:
// shares = shares - base/(base/shares)
// shareReservesDelta, _shareAmount and totalGovernanceFee
// are all denominated in shares:
// shares = shares - shares
shareReservesDelta =
_shareAmount -
governanceCurveFee.divDown(_sharePrice);

// Calculate the fees owed to governance in shares.
// totalGovernanceFee is in base and we want it in shares
// shares = base/(base/shares)
// shares = shares
totalGovernanceFee = governanceCurveFee.divDown(_sharePrice);
shareReservesDelta = _shareAmount - totalGovernanceFee;

return (
shareReservesDelta,
Expand Down
14 changes: 6 additions & 8 deletions contracts/src/libraries/HyperdriveMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ library HyperdriveMath {
uint256 _positionDuration,
uint256 _timeStretch
) internal pure returns (uint256 apr) {
// We are interested calculating the fixed APR for the pool. The rate is calculated by
// dividing current spot price of the bonds by the position duration time, t. To get the
// annual rate, we scale t up to a year.
uint256 annualizedTime = _positionDuration.divDown(365 days);
// We are interested calculating the fixed APR for the pool. The annualized rate
// is given by the following formula:
// r = (1 - p) / (p * t)
// where t = 365 / _positionDuration

uint256 spotPrice = calculateSpotPrice(
_shareReserves,
Expand All @@ -61,10 +61,9 @@ library HyperdriveMath {
_timeStretch
);

// r = (1 - p) / (p * t)
return
(FixedPointMath.ONE_18 - spotPrice).divDown(
spotPrice.mulDown(annualizedTime)
spotPrice.mulDivUp(365 days, _positionDuration)
);
}

Expand All @@ -90,12 +89,11 @@ library HyperdriveMath {
) internal pure returns (uint256 bondReserves) {
// NOTE: Using divDown to convert to fixed point format.
uint256 t = _positionDuration.divDown(365 days);
uint256 tau = FixedPointMath.ONE_18.mulDown(_timeStretch);
// mu * z * (1 + apr * t) ** (1 / tau)
return
_initialSharePrice.mulDown(_shareReserves).mulDown(
(FixedPointMath.ONE_18 + _apr.mulDown(t)).pow(
FixedPointMath.ONE_18.divUp(tau)
FixedPointMath.ONE_18.divUp(_timeStretch)
)
);
}
Expand Down
6 changes: 3 additions & 3 deletions test/units/hyperdrive/FeeTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,9 @@ contract FeeTest is HyperdriveTest {
// total curve fee = ((1 / p) - 1) * phi_curve * c * dz
// ((1/.5)-1) * .1*1*1 = .1
assertEq(curveFee, .1 ether);
// governance curve fee = total curve fee * spot price * phi_gov
// .1 * 0.5 * 0.5 = .025
assertEq(governanceCurveFee, .025 ether);
// governance curve fee = total curve fee * phi_gov
// .1 * 0.5 = .05
assertEq(governanceCurveFee, .05 ether);
}

function test_calcFeesOutGivenBondsIn() public {
Expand Down

0 comments on commit 7ff8680

Please sign in to comment.