Skip to content

Latest commit

 

History

History
888 lines (600 loc) · 18.1 KB

File metadata and controls

888 lines (600 loc) · 18.1 KB

FixedPointMathLib

Arithmetic library with operations for fixed-point numbers.

Custom Errors

ExpOverflow()

error ExpOverflow()

The operation failed, as the output exceeds the maximum value of uint256.

FactorialOverflow()

error FactorialOverflow()

The operation failed, as the output exceeds the maximum value of uint256.

RPowOverflow()

error RPowOverflow()

The operation failed, due to an overflow.

MantissaOverflow()

error MantissaOverflow()

The mantissa is too big to fit.

MulWadFailed()

error MulWadFailed()

The operation failed, due to an multiplication overflow.

SMulWadFailed()

error SMulWadFailed()

The operation failed, due to an multiplication overflow.

DivWadFailed()

error DivWadFailed()

The operation failed, either due to a multiplication overflow, or a division by a zero.

SDivWadFailed()

error SDivWadFailed()

The operation failed, either due to a multiplication overflow, or a division by a zero.

MulDivFailed()

error MulDivFailed()

The operation failed, either due to a multiplication overflow, or a division by a zero.

DivFailed()

error DivFailed()

The division failed, as the denominator is zero.

FullMulDivFailed()

error FullMulDivFailed()

The full precision multiply-divide operation failed, either due
to the result being larger than 256 bits, or a division by a zero.

LnWadUndefined()

error LnWadUndefined()

The output is undefined, as the input is less-than-or-equal to zero.

OutOfDomain()

error OutOfDomain()

The input outside the acceptable domain.

Constants

WAD

uint256 internal constant WAD = 1e18

The scalar of ETH and most ERC20s.

Simplified Fixed Point Operations

mulWad(uint256,uint256)

function mulWad(uint256 x, uint256 y) internal pure returns (uint256 z)

Equivalent to (x * y) / WAD rounded down.

sMulWad(int256,int256)

function sMulWad(int256 x, int256 y) internal pure returns (int256 z)

Equivalent to (x * y) / WAD rounded down.

rawMulWad(uint256,uint256)

function rawMulWad(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Equivalent to (x * y) / WAD rounded down, but without overflow checks.

rawSMulWad(int256,int256)

function rawSMulWad(int256 x, int256 y) internal pure returns (int256 z)

Equivalent to (x * y) / WAD rounded down, but without overflow checks.

mulWadUp(uint256,uint256)

function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256 z)

Equivalent to (x * y) / WAD rounded up.

rawMulWadUp(uint256,uint256)

function rawMulWadUp(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Equivalent to (x * y) / WAD rounded up, but without overflow checks.

divWad(uint256,uint256)

function divWad(uint256 x, uint256 y) internal pure returns (uint256 z)

Equivalent to (x * WAD) / y rounded down.

sDivWad(int256,int256)

function sDivWad(int256 x, int256 y) internal pure returns (int256 z)

Equivalent to (x * WAD) / y rounded down.

rawDivWad(uint256,uint256)

function rawDivWad(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Equivalent to (x * WAD) / y rounded down, but without overflow and divide by zero checks.

rawSDivWad(int256,int256)

function rawSDivWad(int256 x, int256 y) internal pure returns (int256 z)

Equivalent to (x * WAD) / y rounded down, but without overflow and divide by zero checks.

divWadUp(uint256,uint256)

function divWadUp(uint256 x, uint256 y) internal pure returns (uint256 z)

Equivalent to (x * WAD) / y rounded up.

rawDivWadUp(uint256,uint256)

function rawDivWadUp(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Equivalent to (x * WAD) / y rounded up, but without overflow and divide by zero checks.

powWad(int256,int256)

function powWad(int256 x, int256 y) internal pure returns (int256)

Equivalent to x to the power of y.
because x ** y = (e ** ln(x)) ** y = e ** (ln(x) * y).
Note: This function is an approximation.

expWad(int256)

function expWad(int256 x) internal pure returns (int256 r)

Returns exp(x), denominated in WAD.
Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
Note: This function is an approximation. Monotonically increasing.

lnWad(int256)

function lnWad(int256 x) internal pure returns (int256 r)

Returns ln(x), denominated in WAD.
Credit to Remco Bloemen under MIT license: https://2π.com/22/exp-ln
Note: This function is an approximation. Monotonically increasing.

lambertW0Wad(int256)

function lambertW0Wad(int256 x) internal pure returns (int256 w)

Returns W_0(x), denominated in WAD.
See: https://en.wikipedia.org/wiki/Lambert_W_function
a.k.a. Product log function. This is an approximation of the principal branch.
Note: This function is an approximation. Monotonically increasing.

General Number Utilities

fullMulEq(uint256,uint256,uint256,uint256)

function fullMulEq(uint256 a, uint256 b, uint256 x, uint256 y)
    internal
    pure
    returns (bool result)

Returns a * b == x * y, with full precision.

fullMulDiv(uint256,uint256,uint256)

function fullMulDiv(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Calculates floor(x * y / d) with full precision.
Throws if result overflows a uint256 or when d is zero.
Credit to Remco Bloemen under MIT license: https://2π.com/21/muldiv

fullMulDivUnchecked(uint256,uint256,uint256)

function fullMulDivUnchecked(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Calculates floor(x * y / d) with full precision.
Behavior is undefined if d is zero or the final result cannot fit in 256 bits.
Performs the full 512 bit calculation regardless.

fullMulDivUp(uint256,uint256,uint256)

function fullMulDivUp(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Calculates floor(x * y / d) with full precision, rounded up.
Throws if result overflows a uint256 or when d is zero.
Credit to Uniswap-v3-core under MIT license:
https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/FullMath.sol

fullMulDivN(uint256,uint256,uint8)

function fullMulDivN(uint256 x, uint256 y, uint8 n)
    internal
    pure
    returns (uint256 z)

Calculates floor(x * y / 2 ** n) with full precision.
Throws if result overflows a uint256.
Credit to Philogy under MIT license:
https://github.com/SorellaLabs/angstrom/blob/main/contracts/src/libraries/X128MathLib.sol

mulDiv(uint256,uint256,uint256)

function mulDiv(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Returns floor(x * y / d).
Reverts if x * y overflows, or d is zero.

mulDivUp(uint256,uint256,uint256)

function mulDivUp(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Returns ceil(x * y / d).
Reverts if x * y overflows, or d is zero.

invMod(uint256,uint256)

function invMod(uint256 a, uint256 n) internal pure returns (uint256 x)

Returns x, the modular multiplicative inverse of a, such that (a * x) % n == 1.

divUp(uint256,uint256)

function divUp(uint256 x, uint256 d) internal pure returns (uint256 z)

Returns ceil(x / d).
Reverts if d is zero.

zeroFloorSub(uint256,uint256)

function zeroFloorSub(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Returns max(0, x - y). Alias for saturatingSub.

saturatingSub(uint256,uint256)

function saturatingSub(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Returns max(0, x - y).

saturatingAdd(uint256,uint256)

function saturatingAdd(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Returns min(2 ** 256 - 1, x + y).

saturatingMul(uint256,uint256)

function saturatingMul(uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Returns min(2 ** 256 - 1, x * y).

ternary(bool,uint256,uint256)

function ternary(bool condition, uint256 x, uint256 y)
    internal
    pure
    returns (uint256 z)

Returns condition ? x : y, without branching.

ternary(bool,bytes32,bytes32)

function ternary(bool condition, bytes32 x, bytes32 y)
    internal
    pure
    returns (bytes32 z)

Returns condition ? x : y, without branching.

ternary(bool,address,address)

function ternary(bool condition, address x, address y)
    internal
    pure
    returns (address z)

Returns condition ? x : y, without branching.

coalesce(uint256,uint256)

function coalesce(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns x != 0 ? x : y, without branching.

coalesce(bytes32,bytes32)

function coalesce(bytes32 x, bytes32 y) internal pure returns (bytes32 z)

Returns x != bytes32(0) ? x : y, without branching.

coalesce(address,address)

function coalesce(address x, address y) internal pure returns (address z)

Returns x != address(0) ? x : y, without branching.

rpow(uint256,uint256,uint256)

function rpow(uint256 x, uint256 y, uint256 b)
    internal
    pure
    returns (uint256 z)

Exponentiate x to y by squaring, denominated in base b.
Reverts if the computation overflows.

sqrt(uint256)

function sqrt(uint256 x) internal pure returns (uint256 z)

Returns the square root of x, rounded down.

cbrt(uint256)

function cbrt(uint256 x) internal pure returns (uint256 z)

Returns the cube root of x, rounded down.
Credit to bout3fiddy and pcaversaccio under AGPLv3 license:
https://github.com/pcaversaccio/snekmate/blob/main/src/snekmate/utils/math.vy
Formally verified by xuwinnie:
https://github.com/vectorized/solady/blob/main/audits/xuwinnie-solady-cbrt-proof.pdf

sqrtWad(uint256)

function sqrtWad(uint256 x) internal pure returns (uint256 z)

Returns the square root of x, denominated in WAD, rounded down.

cbrtWad(uint256)

function cbrtWad(uint256 x) internal pure returns (uint256 z)

Returns the cube root of x, denominated in WAD, rounded down.
Formally verified by xuwinnie:
https://github.com/vectorized/solady/blob/main/audits/xuwinnie-solady-cbrt-proof.pdf

mulSqrt(uint256,uint256)

function mulSqrt(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns sqrt(x * y). Also called the geometric mean.

factorial(uint256)

function factorial(uint256 x) internal pure returns (uint256 z)

Returns the factorial of x.

log2(uint256)

function log2(uint256 x) internal pure returns (uint256 r)

Returns the log2 of x.
Equivalent to computing the index of the most significant bit (MSB) of x.
Returns 0 if x is zero.

log2Up(uint256)

function log2Up(uint256 x) internal pure returns (uint256 r)

Returns the log2 of x, rounded up.
Returns 0 if x is zero.

log10(uint256)

function log10(uint256 x) internal pure returns (uint256 r)

Returns the log10 of x.
Returns 0 if x is zero.

log10Up(uint256)

function log10Up(uint256 x) internal pure returns (uint256 r)

Returns the log10 of x, rounded up.
Returns 0 if x is zero.

log256(uint256)

function log256(uint256 x) internal pure returns (uint256 r)

Returns the log256 of x.
Returns 0 if x is zero.

log256Up(uint256)

function log256Up(uint256 x) internal pure returns (uint256 r)

Returns the log256 of x, rounded up.
Returns 0 if x is zero.

sci(uint256)

function sci(uint256 x)
    internal
    pure
    returns (uint256 mantissa, uint256 exponent)

Returns the scientific notation format mantissa * 10 ** exponent of x.
Useful for compressing prices (e.g. using 25 bit mantissa and 7 bit exponent).

packSci(uint256)

function packSci(uint256 x) internal pure returns (uint256 packed)

Convenience function for packing x into a smaller number using sci.
The mantissa will be in bits [7..255] (the upper 249 bits).
The exponent will be in bits [0..6] (the lower 7 bits).
Use SafeCastLib to safely ensure that the packed number is small
enough to fit in the desired unsigned integer type:

uint32 packed = SafeCastLib.toUint32(FixedPointMathLib.packSci(777 ether));   

unpackSci(uint256)

function unpackSci(uint256 packed)
    internal
    pure
    returns (uint256 unpacked)

Convenience function for unpacking a packed number from packSci.

avg(uint256,uint256)

function avg(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns the average of x and y. Rounds towards zero.

avg(int256,int256)

function avg(int256 x, int256 y) internal pure returns (int256 z)

Returns the average of x and y. Rounds towards negative infinity.

abs(int256)

function abs(int256 x) internal pure returns (uint256 z)

Returns the absolute value of x.

dist(uint256,uint256)

function dist(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns the absolute distance between x and y.

dist(int256,int256)

function dist(int256 x, int256 y) internal pure returns (uint256 z)

Returns the absolute distance between x and y.

min(uint256,uint256)

function min(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns the minimum of x and y.

min(int256,int256)

function min(int256 x, int256 y) internal pure returns (int256 z)

Returns the minimum of x and y.

max(uint256,uint256)

function max(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns the maximum of x and y.

max(int256,int256)

function max(int256 x, int256 y) internal pure returns (int256 z)

Returns the maximum of x and y.

clamp(uint256,uint256,uint256)

function clamp(uint256 x, uint256 minValue, uint256 maxValue)
    internal
    pure
    returns (uint256 z)

Returns x, bounded to minValue and maxValue.

clamp(int256,int256,int256)

function clamp(int256 x, int256 minValue, int256 maxValue)
    internal
    pure
    returns (int256 z)

Returns x, bounded to minValue and maxValue.

gcd(uint256,uint256)

function gcd(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns greatest common divisor of x and y.

lerp(uint256,uint256,uint256,uint256,uint256)

function lerp(uint256 a, uint256 b, uint256 t, uint256 begin, uint256 end)
    internal
    pure
    returns (uint256)

Returns a + (b - a) * (t - begin) / (end - begin),
with t clamped between begin and end (inclusive).
Agnostic to the order of (a, b) and (end, begin).
If begins == end, returns t <= begin ? a : b.

lerp(int256,int256,int256,int256,int256)

function lerp(int256 a, int256 b, int256 t, int256 begin, int256 end)
    internal
    pure
    returns (int256)

Returns a + (b - a) * (t - begin) / (end - begin).
with t clamped between begin and end (inclusive).
Agnostic to the order of (a, b) and (end, begin).
If begins == end, returns t <= begin ? a : b.

isEven(uint256)

function isEven(uint256 x) internal pure returns (bool)

Returns if x is an even number. Some people may need this.

Raw Number Operations

rawAdd(uint256,uint256)

function rawAdd(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns x + y, without checking for overflow.

rawAdd(int256,int256)

function rawAdd(int256 x, int256 y) internal pure returns (int256 z)

Returns x + y, without checking for overflow.

rawSub(uint256,uint256)

function rawSub(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns x - y, without checking for underflow.

rawSub(int256,int256)

function rawSub(int256 x, int256 y) internal pure returns (int256 z)

Returns x - y, without checking for underflow.

rawMul(uint256,uint256)

function rawMul(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns x * y, without checking for overflow.

rawMul(int256,int256)

function rawMul(int256 x, int256 y) internal pure returns (int256 z)

Returns x * y, without checking for overflow.

rawDiv(uint256,uint256)

function rawDiv(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns x / y, returning 0 if y is zero.

rawSDiv(int256,int256)

function rawSDiv(int256 x, int256 y) internal pure returns (int256 z)

Returns x / y, returning 0 if y is zero.

rawMod(uint256,uint256)

function rawMod(uint256 x, uint256 y) internal pure returns (uint256 z)

Returns x % y, returning 0 if y is zero.

rawSMod(int256,int256)

function rawSMod(int256 x, int256 y) internal pure returns (int256 z)

Returns x % y, returning 0 if y is zero.

rawAddMod(uint256,uint256,uint256)

function rawAddMod(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Returns (x + y) % d, return 0 if d if zero.

rawMulMod(uint256,uint256,uint256)

function rawMulMod(uint256 x, uint256 y, uint256 d)
    internal
    pure
    returns (uint256 z)

Returns (x * y) % d, return 0 if d if zero.