From 50a2612e8a7d1ee348d06eec7adae0cce66ee8c0 Mon Sep 17 00:00:00 2001 From: MerlinEgalite Date: Thu, 9 Nov 2023 10:29:10 +0300 Subject: [PATCH] fix: return a capped value instead of overflowing --- src/libraries/ErrorsLib.sol | 3 --- src/libraries/MathLib.sol | 14 ++++++++++---- test/MathLibTest.sol | 6 ++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/libraries/ErrorsLib.sol b/src/libraries/ErrorsLib.sol index 6ec213e6..a6f6d8fa 100644 --- a/src/libraries/ErrorsLib.sol +++ b/src/libraries/ErrorsLib.sol @@ -18,9 +18,6 @@ library ErrorsLib { /// @dev Thrown when passing the zero input. string internal constant ZERO_INPUT = "zero input"; - /// @dev Thrown when wExp overflows. - string internal constant WEXP_OVERFLOW = "wExp overflow"; - /// @dev Thrown when the caller is not Morpho. string internal constant NOT_MORPHO = "not Morpho"; } diff --git a/src/libraries/MathLib.sol b/src/libraries/MathLib.sol index ee792787..4ba6894c 100644 --- a/src/libraries/MathLib.sol +++ b/src/libraries/MathLib.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; -import {ErrorsLib} from "./ErrorsLib.sol"; import {WAD} from "../../lib/morpho-blue/src/libraries/MathLib.sol"; int256 constant WAD_INT = int256(WAD); @@ -16,13 +15,20 @@ library MathLib { using {wDivDown} for int256; /// @dev ln(2). - int256 private constant LN2_INT = 0.693147180559945309 ether; + int256 internal constant LN2_INT = 0.693147180559945309 ether; + + /// @dev Above this limit `wExp` would overflow. Instead, we return a capped value. + int256 internal constant UPPER_LIMIT = 135.999582271169154765 ether; + + /// @dev The value of wExp(UPPER_LIMIT). + uint256 internal constant CAPPED_VALUE = 115792089237316195323137357242501015631897353894317901381819896896488577433600; /// @dev Returns an approximation of exp. function wExp(int256 x) internal pure returns (uint256) { unchecked { - // Revert if x > ln(2^256-1) ~ 177. - require(x <= 177.44567822334599921 ether, ErrorsLib.WEXP_OVERFLOW); + // Return a capped value to avoid overflows. + if (x >= UPPER_LIMIT) return CAPPED_VALUE; + // Return zero if x < -(2**255-1) + (ln(2)/2). if (x < type(int256).min + LN2_INT / 2) return 0; diff --git a/test/MathLibTest.sol b/test/MathLibTest.sol index dfe6bb94..aba1ac87 100644 --- a/test/MathLibTest.sol +++ b/test/MathLibTest.sol @@ -32,9 +32,7 @@ contract MathLibTest is Test { } function testWExpTooLarge(int256 x) public { - // Bound between ln(2**256-1) ~ 177 and 2**255-1. - x = bound(x, 178 ether, type(int256).max); - vm.expectRevert(bytes(ErrorsLib.WEXP_OVERFLOW)); - MathLib.wExp(x); + x = bound(x, MathLib.UPPER_LIMIT, type(int256).max); + assertEq(MathLib.wExp(x), MathLib.CAPPED_VALUE); } }