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
4 changes: 2 additions & 2 deletions contracts/Hyperdrive.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1149,13 +1149,13 @@ abstract contract Hyperdrive is MultiToken, IHyperdrive {
return
(_positionsOutstanding.mulDown(_averageMaturityTime))
.add(_positionAmount.mulDown(_positionMaturityTime))
.divDown(_positionsOutstanding.add(_positionAmount));
.divUp(_positionsOutstanding.add(_positionAmount));
} else {
if (_positionsOutstanding == _positionAmount) return 0;
return
(_positionsOutstanding.mulDown(_averageMaturityTime))
.sub(_positionAmount.mulDown(_positionMaturityTime))
.divDown(_positionsOutstanding.sub(_positionAmount));
.divUp(_positionsOutstanding.sub(_positionAmount));
}
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/libraries/ERC20Permit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ abstract contract ERC20Permit is IERC20Permit {
}

/// @notice An optional override function to execute and change state before immutable assignment
function _extraConstruction() internal virtual {}
function _extraConstruction() internal virtual {} // solhint-disable-line no-empty-blocks

// --- Token ---
/// @notice Allows a token owner to send tokens to another address
Expand Down
70 changes: 58 additions & 12 deletions contracts/libraries/FixedPointMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@ pragma solidity ^0.8.18;
import "./Errors.sol";

/// @notice A fixed-point math library.
/// @author Element Finance
/// @author Delve
library FixedPointMath {
int256 internal constant _ONE_18 = 1e18;
uint256 public constant ONE_18 = 1e18;

/// @dev Credit to Balancer (https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/solidity-utils/contracts/math/FixedPoint.sol)
/// @param a Fixed point number in 1e18 format.
/// @param b Fixed point number in 1e18 format.
/// @return Result of a + b.
function add(uint256 a, uint256 b) internal pure returns (uint256) {
// Fixed Point addition is the same as regular checked addition

Expand All @@ -19,6 +22,9 @@ library FixedPointMath {
}

/// @dev Credit to Balancer (https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/solidity-utils/contracts/math/FixedPoint.sol)
/// @param a Fixed point number in 1e18 format.
/// @param b Fixed point number in 1e18 format.
/// @return Result of a - b.
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
// Fixed Point addition is the same as regular checked addition

Expand All @@ -27,7 +33,11 @@ library FixedPointMath {
return c;
}

/// @dev Credit to Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @dev Credit to Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @param x Fixed point number in 1e18 format.
/// @param y Fixed point number in 1e18 format.
/// @param d Fixed point number in 1e18 format.
/// @return z The result of x * y / d rounded down.
function mulDivDown(
uint256 x,
uint256 y,
Expand All @@ -47,11 +57,27 @@ library FixedPointMath {
}
}

/// @dev Credit to Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @param a Fixed point number in 1e18 format.
/// @param b Fixed point number in 1e18 format.
/// @return Result of a * b rounded down.
function mulDown(uint256 a, uint256 b) internal pure returns (uint256) {
return (mulDivDown(a, b, 1e18));
}

/// @dev Credit to Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @dev Credit to Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @param a Fixed point number in 1e18 format.
/// @param b Fixed point number in 1e18 format.
/// @return Result of a / b rounded down.
function divDown(uint256 a, uint256 b) internal pure returns (uint256) {
return (mulDivDown(a, 1e18, b)); // Equivalent to (a * 1e18) / b rounded down.
}

/// @dev Credit to Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @param x Fixed point number in 1e18 format.
/// @param y Fixed point number in 1e18 format.
/// @param d Fixed point number in 1e18 format.
/// @return z The result of x * y / d rounded up.
function mulDivUp(
uint256 x,
uint256 y,
Expand All @@ -73,12 +99,27 @@ library FixedPointMath {
}
}

function divDown(uint256 a, uint256 b) internal pure returns (uint256) {
return (mulDivDown(a, 1e18, b)); // Equivalent to (a * 1e18) / b rounded down.
/// @dev Credit to Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @param a Fixed point number in 1e18 format.
/// @param b Fixed point number in 1e18 format.
/// @return The result of a * b rounded up.
function mulUp(uint256 a, uint256 b) internal pure returns (uint256) {
return (mulDivUp(a, b, 1e18));
}

/// @dev Credit to Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @param a Fixed point number in 1e18 format.
/// @param b Fixed point number in 1e18 format.
/// @return The result of a / b rounded up.
function divUp(uint256 a, uint256 b) internal pure returns (uint256) {
return (mulDivUp(a, 1e18, b));
}

/// @dev Exponentiation (x^y) with unsigned 18 decimal fixed point base and exponent.
/// @dev Partially inspired by Balancer LogExpMath library (https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/solidity-utils/contracts/math/LogExpMath.sol)
/// @param x Fixed point number in 1e18 format.
/// @param y Fixed point number in 1e18 format.
/// @return The result of x^y.
function pow(uint256 x, uint256 y) internal pure returns (uint256) {
// Using properties of logarithms we calculate x^y:
// -> ln(x^y) = y * ln(x)
Expand All @@ -99,14 +140,16 @@ library FixedPointMath {
return uint256(exp(ylnx));
}

// Computes e^x in 1e18 fixed point.
// Credit to Remco (https://github.com/recmo/experiment-solexp/blob/main/src/FixedPointMathLib.sol)
/// @dev Computes e^x in 1e18 fixed point.
/// @dev Credit to Remco (https://github.com/recmo/experiment-solexp/blob/main/src/FixedPointMathLib.sol)
/// @param x Fixed point number in 1e18 format.
/// @return r The result of e^x.
function exp(int256 x) internal pure returns (int256 r) {
unchecked {
// Input x is in fixed point format, with scale factor 1/1e18.

// When the result is < 0.5 we return zero. This happens when
// x <= floor(log(0.5e18) * 1e18) ~ -42e18
// x <= floor(log(0.5e-18) * 1e18) ~ -42e18
if (x <= -42139678854452767551) {
return 0;
}
Expand Down Expand Up @@ -169,6 +212,8 @@ library FixedPointMath {
/// @dev Computes ln(x) in 1e18 fixed point.
/// @dev Reverts if x is negative
/// @dev Credit to Remco (https://github.com/recmo/experiment-solexp/blob/main/src/FixedPointMathLib.sol)
/// @param x Fixed point number in 1e18 format.
/// @return Result of ln(x).
function ln(int256 x) internal pure returns (int256) {
if (x <= 0) revert Errors.FixedPointMath_NegativeOrZeroInput();
return _ln(x);
Expand Down Expand Up @@ -238,10 +283,11 @@ library FixedPointMath {
}
}

// Integer log2
// @returns floor(log2(x)) if x is nonzero, otherwise 0. This is the same
// as the location of the highest set bit.
// Credit to Remco (https://github.com/recmo/experiment-solexp/blob/main/src/FixedPointMathLib.sol)
/// @dev Integer log2
/// @dev Credit to Remco (https://github.com/recmo/experiment-solexp/blob/main/src/FixedPointMathLib.sol)
/// @param x Integer
/// @return r The floor(log2(x)) if x is nonzero, otherwise 0. This is the same
/// as the location of the highest set bit.
function _ilog2(uint256 x) private pure returns (uint256 r) {
assembly {
r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x))
Expand Down
24 changes: 13 additions & 11 deletions contracts/libraries/HyperdriveMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ library HyperdriveMath {
uint256 flat = _amountIn.mulDown(
FixedPointMath.ONE_18.sub(_normalizedTimeRemaining)
);

_shareReserves = _shareReserves.add(flat);
_bondReserves = _bondReserves.sub(flat.mulDown(_sharePrice));
uint256 curveIn = _amountIn.mulDown(_normalizedTimeRemaining);
Expand Down Expand Up @@ -211,16 +210,19 @@ library HyperdriveMath {
uint256 curveIn = _amountIn
.mulDown(_normalizedTimeRemaining)
.divDown(_sharePrice);
uint256 curveOut = YieldSpaceMath.calculateOutGivenIn(
_shareReserves,
_bondReserves,
_bondReserveAdjustment,
curveIn,
FixedPointMath.ONE_18.sub(_timeStretch),
_sharePrice,
_initialSharePrice,
_isBaseIn
);
uint256 curveOut = 0;
if (curveIn > 0) {
curveOut = YieldSpaceMath.calculateOutGivenIn(
_shareReserves,
_bondReserves,
_bondReserveAdjustment,
curveIn,
FixedPointMath.ONE_18.sub(_timeStretch),
_sharePrice,
_initialSharePrice,
_isBaseIn
);
}
uint256 shareDelta = flat.add(curveOut);
return (shareDelta, curveIn, shareDelta);
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/libraries/YieldSpaceMath.sol
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ library YieldSpaceMath {
// NOTE: k - shareReserves >= 0 to avoid a complex number
// ((c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (c / mu) * (mu * (shareReserves + amountIn))^(1 - tau))^(1 / (1 - tau)))
uint256 newBondReserves = k.sub(_shareReserves).pow(
FixedPointMath.ONE_18.divDown(_stretchedTimeElapsed)
FixedPointMath.ONE_18.divUp(_stretchedTimeElapsed)
);
// NOTE: bondReserves - newBondReserves >= 0, but I think avoiding a complex number in the step above ensures this never happens
// bondsOut = bondReserves - ( (c / mu) * (mu * shareReserves)^(1 - tau) + bondReserves^(1 - tau) - (c / mu) * (mu * (shareReserves + shareIn))^(1 - tau))^(1 / (1 - tau)))
Expand Down
Loading