SignedMath.t.sol 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.20;
  3. import {Test} from "forge-std/Test.sol";
  4. import {Math} from "../../../contracts/utils/math/Math.sol";
  5. import {SignedMath} from "../../../contracts/utils/math/SignedMath.sol";
  6. contract SignedMathTest is Test {
  7. // MIN
  8. function testMin(int256 a, int256 b) public {
  9. int256 result = SignedMath.min(a, b);
  10. assertLe(result, a);
  11. assertLe(result, b);
  12. assertTrue(result == a || result == b);
  13. }
  14. // MAX
  15. function testMax(int256 a, int256 b) public {
  16. int256 result = SignedMath.max(a, b);
  17. assertGe(result, a);
  18. assertGe(result, b);
  19. assertTrue(result == a || result == b);
  20. }
  21. // AVERAGE
  22. // 1. simple test, not full int256 range
  23. function testAverage1(int256 a, int256 b) public {
  24. a = bound(a, type(int256).min / 2, type(int256).max / 2);
  25. b = bound(b, type(int256).min / 2, type(int256).max / 2);
  26. int256 result = SignedMath.average(a, b);
  27. assertEq(result, (a + b) / 2);
  28. }
  29. // 2. more complex test, full int256 range
  30. function testAverage2(int256 a, int256 b) public {
  31. (int256 result, int256 min, int256 max) = (
  32. SignedMath.average(a, b),
  33. SignedMath.min(a, b),
  34. SignedMath.max(a, b)
  35. );
  36. // average must be between `a` and `b`
  37. assertGe(result, min);
  38. assertLe(result, max);
  39. unchecked {
  40. // must be unchecked in order to support `a = type(int256).min, b = type(int256).max`
  41. uint256 deltaLower = uint256(result - min);
  42. uint256 deltaUpper = uint256(max - result);
  43. uint256 remainder = uint256((a & 1) ^ (b & 1));
  44. assertEq(remainder, Math.max(deltaLower, deltaUpper) - Math.min(deltaLower, deltaUpper));
  45. }
  46. }
  47. // ABS
  48. function testAbs(int256 a) public {
  49. uint256 result = SignedMath.abs(a);
  50. unchecked {
  51. // must be unchecked in order to support `n = type(int256).min`
  52. assertEq(result, a < 0 ? uint256(-a) : uint256(a));
  53. }
  54. }
  55. }