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
2 changes: 1 addition & 1 deletion contracts/Hyperdrive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ contract Hyperdrive is MultiToken {
uint256 poolShareDelta,
uint256 poolBondDelta,
uint256 sharePayment
) = HyperdriveMath.calculateBaseInGivenBondsOut(
) = HyperdriveMath.calculateSharesInGivenBondsOut(
shareReserves,
bondReserves,
totalSupply[AssetId._LP_ASSET_ID],
Expand Down
2 changes: 1 addition & 1 deletion contracts/libraries/AssetId.sol
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ library AssetId {
uint256 _id
)
internal
view
pure
returns (AssetIdPrefix _prefix, uint256 _data, uint256 _timestamp)
{
// [identifier: 8 bits][data: 216 bits][timestamp: 32 bits]
Expand Down
5 changes: 0 additions & 5 deletions contracts/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@ library Errors {
error FixedPointMath_NegativeOrZeroInput();
error FixedPointMath_NegativeInput();

/// ######################
/// ### HyperdriveMath ###
/// ######################
error HyperdriveMath_BaseWithNonzeroTime();

/// ###############
/// ### AssetId ###
/// ###############
Expand Down
65 changes: 37 additions & 28 deletions contracts/libraries/HyperdriveMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ library HyperdriveMath {
/// the capital efficiency of the AMM. Otherwise, the APR would be 0%
/// when share_reserves = bond_reserves, which would ensure that half
/// of the pool reserves couldn't be used to provide liquidity.
/// @param _amountIn The amount of the asset that is provided.
/// @param _amountIn The amount to be traded. This quantity is denominated
/// in shares if bonds are being traded out and bonds if shares are
/// being traded out.
/// @param _timeRemaining The amount of time until maturity in seconds.
/// @param _timeStretch The time stretch parameter.
/// @param _sharePrice The share price.
Expand Down Expand Up @@ -122,45 +124,49 @@ library HyperdriveMath {
uint256 userDelta
)
{
// TODO: See if this is actually true.
//
// This pricing model only supports the purchasing of bonds when
// timeRemaining = 1.
if (_isBondOut && _timeRemaining < 1) {
revert Errors.HyperdriveMath_BaseWithNonzeroTime();
}
uint256 flat = _amountIn.mulDown(
FixedPointMath.ONE_18.sub(_timeRemaining)
);
if (_isBondOut) {
// If bonds are being purchased, then the entire trade occurs on the
// curved portion since t = 1.
uint256 amountOut = YieldSpaceMath.calculateOutGivenIn(
_shareReserves,
_bondReserves,
// We consider (1-timeRemaining)*amountIn of the bonds being
// purchased to be fully matured and we use the remaining
// timeRemaining*amountIn shares to purchase newly minted bonds on a
// YieldSpace curve configured to timeRemaining = 1.
uint256 curveIn = _amountIn.mulDown(_timeRemaining);
uint256 curveOut = YieldSpaceMath.calculateOutGivenIn(
// Credit the share reserves by the flat trade.
_shareReserves.add(flat),
// Debit the bond reserves by the flat trade.
_bondReserves.sub(flat.mulDown(_sharePrice)),
_bondReserveAdjustment,
_amountIn,
curveIn,
FixedPointMath.ONE_18,
_timeStretch,
_sharePrice,
_initialSharePrice,
_isBondOut
);
return (_amountIn, amountOut, amountOut);
return (
_amountIn,
curveOut,
flat.mulDown(_sharePrice).add(curveOut)
);
} else {
// Since we are trading bonds, it's possible that timeRemaining < 1.
// We consider (1-timeRemaining)*amountIn of the bonds to be fully
// matured and timeRemaining*amountIn of the bonds to be newly
// minted. The fully matured bonds are redeemed one-to-one to base
// (our result is given in shares, so we divide the one-to-one
// redemption by the share price) and the newly minted bonds are
// traded on a YieldSpace curve configured to timeRemaining = 1.
uint256 flat = _amountIn
.mulDown(FixedPointMath.ONE_18.sub(_timeRemaining))
.divDown(_sharePrice);
uint256 curveIn = _amountIn.mulDown(_timeRemaining);
flat = flat.divDown(_sharePrice);
uint256 curveIn = _amountIn.mulDown(_timeRemaining).divDown(
_sharePrice
);
uint256 curveOut = YieldSpaceMath.calculateOutGivenIn(
// Debit the share reserves by the flat trade.
_shareReserves.sub(flat.divDown(_initialSharePrice)),
_shareReserves.sub(flat),
// Credit the bond reserves by the flat trade.
_bondReserves.add(flat),
_bondReserves.add(flat.mulDown(_sharePrice)),
_bondReserveAdjustment,
curveIn,
FixedPointMath.ONE_18,
Expand All @@ -169,7 +175,8 @@ library HyperdriveMath {
_initialSharePrice,
_isBondOut
);
return (flat.add(curveOut), curveIn, flat.add(curveOut));
uint256 shareDelta = flat.add(curveOut);
return (shareDelta, curveIn, shareDelta);
}
}

Expand All @@ -191,7 +198,7 @@ library HyperdriveMath {
/// @return poolBondDelta The delta that should be applied to the pool's
/// bond reserves.
/// @return userDelta The amount of assets the user should receive.
function calculateBaseInGivenBondsOut(
function calculateSharesInGivenBondsOut(
uint256 _shareReserves,
uint256 _bondReserves,
uint256 _bondReserveAdjustment,
Expand Down Expand Up @@ -220,12 +227,14 @@ library HyperdriveMath {
uint256 flat = _amountOut
.mulDown(FixedPointMath.ONE_18.sub(_timeRemaining))
.divDown(_sharePrice);
uint256 curveOut = _amountOut.mulDown(_timeRemaining);
uint256 curveOut = _amountOut.mulDown(_timeRemaining).divDown(
_sharePrice
);
uint256 curveIn = YieldSpaceMath.calculateInGivenOut(
// Credit the share reserves by the flat trade.
_shareReserves.add(flat.divDown(_sharePrice)),
_shareReserves.add(flat),
// Debit the bond reserves by the flat trade.
_bondReserves.sub(flat),
_bondReserves.sub(flat.mulDown(_sharePrice)),
_bondReserveAdjustment,
curveOut,
FixedPointMath.ONE_18,
Expand All @@ -234,7 +243,7 @@ library HyperdriveMath {
_initialSharePrice,
false
);
return (flat.add(curveIn), curveIn, flat.add(curveIn));
return (flat.add(curveIn), curveOut, flat.add(curveIn));
}

// TODO: Use an allocation scheme that doesn't punish early LPs.
Expand Down