|
@@ -0,0 +1,70 @@
|
|
|
+// SPDX-License-Identifier: MIT
|
|
|
+
|
|
|
+pragma solidity ^0.8.20;
|
|
|
+
|
|
|
+import {Test} from "forge-std/Test.sol";
|
|
|
+
|
|
|
+import {Math} from "../../../contracts/utils/math/Math.sol";
|
|
|
+import {SignedMath} from "../../../contracts/utils/math/SignedMath.sol";
|
|
|
+
|
|
|
+contract SignedMathTest is Test {
|
|
|
+ // MIN
|
|
|
+ function testMin(int256 a, int256 b) public {
|
|
|
+ int256 result = SignedMath.min(a, b);
|
|
|
+
|
|
|
+ assertLe(result, a);
|
|
|
+ assertLe(result, b);
|
|
|
+ assertTrue(result == a || result == b);
|
|
|
+ }
|
|
|
+
|
|
|
+ // MAX
|
|
|
+ function testMax(int256 a, int256 b) public {
|
|
|
+ int256 result = SignedMath.max(a, b);
|
|
|
+
|
|
|
+ assertGe(result, a);
|
|
|
+ assertGe(result, b);
|
|
|
+ assertTrue(result == a || result == b);
|
|
|
+ }
|
|
|
+
|
|
|
+ // AVERAGE
|
|
|
+ // 1. simple test, not full int256 range
|
|
|
+ function testAverage1(int256 a, int256 b) public {
|
|
|
+ a = bound(a, type(int256).min / 2, type(int256).max / 2);
|
|
|
+ b = bound(b, type(int256).min / 2, type(int256).max / 2);
|
|
|
+
|
|
|
+ int256 result = SignedMath.average(a, b);
|
|
|
+
|
|
|
+ assertEq(result, (a + b) / 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. more complex test, full int256 range
|
|
|
+ function testAverage2(int256 a, int256 b) public {
|
|
|
+ (int256 result, int256 min, int256 max) = (
|
|
|
+ SignedMath.average(a, b),
|
|
|
+ SignedMath.min(a, b),
|
|
|
+ SignedMath.max(a, b)
|
|
|
+ );
|
|
|
+
|
|
|
+ // average must be between `a` and `b`
|
|
|
+ assertGe(result, min);
|
|
|
+ assertLe(result, max);
|
|
|
+
|
|
|
+ unchecked {
|
|
|
+ // must be unchecked in order to support `a = type(int256).min, b = type(int256).max`
|
|
|
+ uint256 deltaLower = uint256(result - min);
|
|
|
+ uint256 deltaUpper = uint256(max - result);
|
|
|
+ uint256 remainder = uint256((a & 1) ^ (b & 1));
|
|
|
+ assertEq(remainder, Math.max(deltaLower, deltaUpper) - Math.min(deltaLower, deltaUpper));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ABS
|
|
|
+ function testAbs(int256 a) public {
|
|
|
+ uint256 result = SignedMath.abs(a);
|
|
|
+
|
|
|
+ unchecked {
|
|
|
+ // must be unchecked in order to support `n = type(int256).min`
|
|
|
+ assertEq(result, a < 0 ? uint256(-a) : uint256(a));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|