arnaucube
arnaucube/poseidon-solidity-examplePublic Self-hosted repository
poseidon-solidity-example/lib/forge-std/test/StdMath.t.sol
lib/forge-std/test/StdMath.t.solRaw
  1// SPDX-License-Identifier: MIT
  2pragma solidity >=0.8.0 <0.9.0;
  3
  4import "../src/StdMath.sol";
  5import "../src/Test.sol";
  6
  7contract StdMathTest is Test {
  8    function testGetAbs() external {
  9        assertEq(stdMath.abs(-50), 50);
 10        assertEq(stdMath.abs(50), 50);
 11        assertEq(stdMath.abs(-1337), 1337);
 12        assertEq(stdMath.abs(0), 0);
 13
 14        assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1);
 15        assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1));
 16    }
 17
 18    function testGetAbs_Fuzz(int256 a) external {
 19        uint256 manualAbs = getAbs(a);
 20
 21        uint256 abs = stdMath.abs(a);
 22
 23        assertEq(abs, manualAbs);
 24    }
 25
 26    function testGetDelta_Uint() external {
 27        assertEq(stdMath.delta(uint256(0), uint256(0)), 0);
 28        assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337);
 29        assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max);
 30        assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max);
 31        assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max);
 32
 33        assertEq(stdMath.delta(0, uint256(0)), 0);
 34        assertEq(stdMath.delta(1337, uint256(0)), 1337);
 35        assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max);
 36        assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max);
 37        assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max);
 38
 39        assertEq(stdMath.delta(1337, uint256(1337)), 0);
 40        assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0);
 41        assertEq(stdMath.delta(5000, uint256(1250)), 3750);
 42    }
 43
 44    function testGetDelta_Uint_Fuzz(uint256 a, uint256 b) external {
 45        uint256 manualDelta;
 46        if (a > b) {
 47            manualDelta = a - b;
 48        } else {
 49            manualDelta = b - a;
 50        }
 51
 52        uint256 delta = stdMath.delta(a, b);
 53
 54        assertEq(delta, manualDelta);
 55    }
 56
 57    function testGetDelta_Int() external {
 58        assertEq(stdMath.delta(int256(0), int256(0)), 0);
 59        assertEq(stdMath.delta(int256(0), int256(1337)), 1337);
 60        assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1);
 61        assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1);
 62        assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1);
 63
 64        assertEq(stdMath.delta(0, int256(0)), 0);
 65        assertEq(stdMath.delta(1337, int256(0)), 1337);
 66        assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1);
 67        assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1);
 68        assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1);
 69
 70        assertEq(stdMath.delta(-0, int256(0)), 0);
 71        assertEq(stdMath.delta(-1337, int256(0)), 1337);
 72        assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1);
 73        assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1);
 74        assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1);
 75
 76        assertEq(stdMath.delta(int256(0), -0), 0);
 77        assertEq(stdMath.delta(int256(0), -1337), 1337);
 78        assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1);
 79        assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1);
 80        assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1);
 81
 82        assertEq(stdMath.delta(1337, int256(1337)), 0);
 83        assertEq(stdMath.delta(type(int256).max, type(int256).max), 0);
 84        assertEq(stdMath.delta(type(int256).min, type(int256).min), 0);
 85        assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max);
 86        assertEq(stdMath.delta(5000, int256(1250)), 3750);
 87    }
 88
 89    function testGetDelta_Int_Fuzz(int256 a, int256 b) external {
 90        uint256 absA = getAbs(a);
 91        uint256 absB = getAbs(b);
 92        uint256 absDelta = absA > absB ? absA - absB : absB - absA;
 93
 94        uint256 manualDelta;
 95        if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) {
 96            manualDelta = absDelta;
 97        }
 98        // (a < 0 && b >= 0) || (a >= 0 && b < 0)
 99        else {
100            manualDelta = absA + absB;
101        }
102
103        uint256 delta = stdMath.delta(a, b);
104
105        assertEq(delta, manualDelta);
106    }
107
108    function testGetPercentDelta_Uint() external {
109        assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18);
110        assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18);
111        assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18);
112        assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18);
113
114        assertEq(stdMath.percentDelta(1337, uint256(1337)), 0);
115        assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0);
116        assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18);
117        assertEq(stdMath.percentDelta(2500, uint256(2500)), 0);
118        assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18);
119        assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18);
120
121        vm.expectRevert(stdError.divisionError);
122        stdMath.percentDelta(uint256(1), 0);
123    }
124
125    function testGetPercentDelta_Uint_Fuzz(uint192 a, uint192 b) external {
126        vm.assume(b != 0);
127        uint256 manualDelta;
128        if (a > b) {
129            manualDelta = a - b;
130        } else {
131            manualDelta = b - a;
132        }
133
134        uint256 manualPercentDelta = manualDelta * 1e18 / b;
135        uint256 percentDelta = stdMath.percentDelta(a, b);
136
137        assertEq(percentDelta, manualPercentDelta);
138    }
139
140    function testGetPercentDelta_Int() external {
141        assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18);
142        assertEq(stdMath.percentDelta(int256(0), -1337), 1e18);
143        assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18);
144        assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18);
145        assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18);
146        assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18);
147        assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18);
148        assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18);
149
150        assertEq(stdMath.percentDelta(1337, int256(1337)), 0);
151        assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0);
152        assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0);
153
154        assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down
155        assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down
156        assertEq(stdMath.percentDelta(0, int256(2500)), 1e18);
157        assertEq(stdMath.percentDelta(2500, int256(2500)), 0);
158        assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18);
159        assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18);
160
161        vm.expectRevert(stdError.divisionError);
162        stdMath.percentDelta(int256(1), 0);
163    }
164
165    function testGetPercentDelta_Int_Fuzz(int192 a, int192 b) external {
166        vm.assume(b != 0);
167        uint256 absA = getAbs(a);
168        uint256 absB = getAbs(b);
169        uint256 absDelta = absA > absB ? absA - absB : absB - absA;
170
171        uint256 manualDelta;
172        if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) {
173            manualDelta = absDelta;
174        }
175        // (a < 0 && b >= 0) || (a >= 0 && b < 0)
176        else {
177            manualDelta = absA + absB;
178        }
179
180        uint256 manualPercentDelta = manualDelta * 1e18 / absB;
181        uint256 percentDelta = stdMath.percentDelta(a, b);
182
183        assertEq(percentDelta, manualPercentDelta);
184    }
185
186    /*//////////////////////////////////////////////////////////////////////////
187                                   HELPERS
188    //////////////////////////////////////////////////////////////////////////*/
189
190    function getAbs(int256 a) private pure returns (uint256) {
191        if (a < 0) {
192            return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a);
193        }
194
195        return uint256(a);
196    }
197}