Skip to content

Commit

Permalink
fix: revert condition wExp underflow
Browse files Browse the repository at this point in the history
  • Loading branch information
MathisGD committed Sep 4, 2023
1 parent 831e3a4 commit 42bb1a0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/irm/libraries/MathLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ library MathLib {
unchecked {
// Revert if x > ln(2^256-1) ~ 177.
require(x <= 177.44567822334599921 ether, ErrorsLib.WEXP_OVERFLOW);
// Revert if x > min / 1e18.
require(x >= type(int256).min + 1 ether, ErrorsLib.WEXP_UNDERFLOW);
// Revert if x < min + (ln(2)/2).
require(x >= type(int256).min + LN2_INT / 2, ErrorsLib.WEXP_UNDERFLOW);

// Decompose x as x = q * ln(2) + r with q an integer and -ln(2)/2 < r <= ln(2)/2.
// q = x / ln(2) rounded half toward zero.
int256 offset = (x < 0) ? - (LN2_INT / 2) : (LN2_INT / 2);
int256 half = (x < 0) ? -(LN2_INT / 2) : (LN2_INT / 2);
// Safe unchecked because x is bounded.
int256 q = (x + offset) / LN2_INT;
int256 q = (x + half) / LN2_INT;
// Safe unchecked because |q * LN2_INT| <= x.
int256 r = x - q * LN2_INT;

Expand Down
14 changes: 11 additions & 3 deletions test/irm/MathLibTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,25 @@ contract MathLibTest is Test {
using MathLib for uint128;
using MathLib for uint256;

int256 private constant LN2_INT = 0.693147180559945309 ether;

function testWExp(int256 x) public {
x = bound(x, - 27 ether, 94 ether);
x = bound(x, -27 ether, 94 ether);
assertApproxEqRel(MathLib.wExp(x), uint256(wadExp(x)), 0.01 ether);
}

function testWExpSmall(int256 x) public {
x = bound(x, type(int256).min + 1 ether, -178 ether);
x = bound(x, type(int256).min + LN2_INT / 2, -178 ether);
assertEq(MathLib.wExp(x), 0);
}

function testWExpTooSmall(int256 x) public {
x = bound(x, type(int256).min, type(int256).min + LN2_INT / 2 - 1);
vm.expectRevert(bytes(ErrorsLib.WEXP_UNDERFLOW));
assertEq(MathLib.wExp(x), 0);
}

function testWExpRevertTooLarge(int256 x) public {
function testWExpTooLarge(int256 x) public {
vm.assume(x >= 178 ether);
vm.expectRevert(bytes(ErrorsLib.WEXP_OVERFLOW));
MathLib.wExp(x);
Expand Down

0 comments on commit 42bb1a0

Please sign in to comment.