diff --git a/src/libraries/MathLib.sol b/src/libraries/MathLib.sol index bfdd419ee..a22efa3a4 100644 --- a/src/libraries/MathLib.sol +++ b/src/libraries/MathLib.sol @@ -7,10 +7,7 @@ uint256 constant WAD = 1e18; /// @author Morpho Labs /// @custom:contact security@morpho.xyz /// @notice Library to manage fixed-point arithmetic. -/// @dev Inspired by https://github.com/morpho-org/morpho-utils. library MathLib { - uint256 internal constant MAX_UINT256 = 2 ** 256 - 1; - /// @dev (x * y) / WAD rounded down. function wMulDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); @@ -32,39 +29,21 @@ library MathLib { } /// @dev (x * y) / denominator rounded down. - function mulDivDown(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) { - // Division by zero if denominator == 0. - // Overflow if - // x * y > type(uint256).max - // <=> y > 0 and x > type(uint256).max / y - assembly { - if or(mul(y, gt(x, div(MAX_UINT256, y))), iszero(denominator)) { revert(0, 0) } - - z := div(mul(x, y), denominator) - } + function mulDivDown(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256) { + return (x * y) / denominator; } /// @dev (x * y) / denominator rounded up. - function mulDivUp(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 z) { - // Underflow if denominator == 0. - // Division by 0 if denominator == 0 (this case cannot occur since the above underflow happens before). - // Overflow if - // x * y + denominator - 1 > type(uint256).max - // <=> x * y > type(uint256).max - denominator + 1 - // <=> y > 0 and x > (type(uint256).max - denominator + 1) / y - assembly { - if or(mul(y, gt(x, div(sub(MAX_UINT256, sub(denominator, 1)), y))), iszero(denominator)) { revert(0, 0) } - - z := div(add(mul(x, y), sub(denominator, 1)), denominator) - } + function mulDivUp(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256) { + return (x * y + (denominator - 1)) / denominator; } /// @dev The sum of the last three terms in a four term taylor series expansion /// to approximate a continuous compound interest rate: e^(nx) - 1. function wTaylorCompounded(uint256 x, uint256 n) internal pure returns (uint256) { uint256 firstTerm = x * n; - uint256 secondTerm = wMulDown(firstTerm, firstTerm) / 2; - uint256 thirdTerm = wMulDown(secondTerm, firstTerm) / 3; + uint256 secondTerm = mulDivDown(firstTerm, firstTerm, 2 * WAD); + uint256 thirdTerm = mulDivDown(secondTerm, firstTerm, 3 * WAD); return firstTerm + secondTerm + thirdTerm; }