arnaucube
arnaucube/poseidon-solidity-examplePublic Self-hosted repository
poseidon-solidity-example/lib/forge-std/test/StdUtils.t.sol
lib/forge-std/test/StdUtils.t.solRaw
  1// SPDX-License-Identifier: MIT
  2pragma solidity >=0.7.0 <0.9.0;
  3
  4import "../src/Test.sol";
  5
  6contract StdUtilsMock is StdUtils {
  7    // We deploy a mock version so we can properly test expected reverts.
  8    function getTokenBalances_(address token, address[] memory addresses)
  9        external
 10        returns (uint256[] memory balances)
 11    {
 12        return getTokenBalances(token, addresses);
 13    }
 14}
 15
 16contract StdUtilsTest is Test {
 17    /*//////////////////////////////////////////////////////////////////////////
 18                                     BOUND UINT
 19    //////////////////////////////////////////////////////////////////////////*/
 20
 21    function testBound() public {
 22        assertEq(bound(uint256(5), 0, 4), 0);
 23        assertEq(bound(uint256(0), 69, 69), 69);
 24        assertEq(bound(uint256(0), 68, 69), 68);
 25        assertEq(bound(uint256(10), 150, 190), 174);
 26        assertEq(bound(uint256(300), 2800, 3200), 3107);
 27        assertEq(bound(uint256(9999), 1337, 6666), 4669);
 28    }
 29
 30    function testBound_WithinRange() public {
 31        assertEq(bound(uint256(51), 50, 150), 51);
 32        assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150));
 33        assertEq(bound(uint256(149), 50, 150), 149);
 34        assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150));
 35    }
 36
 37    function testBound_EdgeCoverage() public {
 38        assertEq(bound(uint256(0), 50, 150), 50);
 39        assertEq(bound(uint256(1), 50, 150), 51);
 40        assertEq(bound(uint256(2), 50, 150), 52);
 41        assertEq(bound(uint256(3), 50, 150), 53);
 42        assertEq(bound(type(uint256).max, 50, 150), 150);
 43        assertEq(bound(type(uint256).max - 1, 50, 150), 149);
 44        assertEq(bound(type(uint256).max - 2, 50, 150), 148);
 45        assertEq(bound(type(uint256).max - 3, 50, 150), 147);
 46    }
 47
 48    function testBound_DistributionIsEven(uint256 min, uint256 size) public {
 49        size = size % 100 + 1;
 50        min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size);
 51        uint256 max = min + size - 1;
 52        uint256 result;
 53
 54        for (uint256 i = 1; i <= size * 4; ++i) {
 55            // x > max
 56            result = bound(max + i, min, max);
 57            assertEq(result, min + (i - 1) % size);
 58            // x < min
 59            result = bound(min - i, min, max);
 60            assertEq(result, max - (i - 1) % size);
 61        }
 62    }
 63
 64    function testBound(uint256 num, uint256 min, uint256 max) public {
 65        if (min > max) (min, max) = (max, min);
 66
 67        uint256 result = bound(num, min, max);
 68
 69        assertGe(result, min);
 70        assertLe(result, max);
 71        assertEq(result, bound(result, min, max));
 72        if (num >= min && num <= max) assertEq(result, num);
 73    }
 74
 75    function testBoundUint256Max() public {
 76        assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1);
 77        assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max);
 78    }
 79
 80    function testCannotBoundMaxLessThanMin() public {
 81        vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min."));
 82        bound(uint256(5), 100, 10);
 83    }
 84
 85    function testCannotBoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public {
 86        vm.assume(min > max);
 87        vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min."));
 88        bound(num, min, max);
 89    }
 90
 91    /*//////////////////////////////////////////////////////////////////////////
 92                                     BOUND INT
 93    //////////////////////////////////////////////////////////////////////////*/
 94
 95    function testBoundInt() public {
 96        assertEq(bound(-3, 0, 4), 2);
 97        assertEq(bound(0, -69, -69), -69);
 98        assertEq(bound(0, -69, -68), -68);
 99        assertEq(bound(-10, 150, 190), 154);
100        assertEq(bound(-300, 2800, 3200), 2908);
101        assertEq(bound(9999, -1337, 6666), 1995);
102    }
103
104    function testBoundInt_WithinRange() public {
105        assertEq(bound(51, -50, 150), 51);
106        assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150));
107        assertEq(bound(149, -50, 150), 149);
108        assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150));
109    }
110
111    function testBoundInt_EdgeCoverage() public {
112        assertEq(bound(type(int256).min, -50, 150), -50);
113        assertEq(bound(type(int256).min + 1, -50, 150), -49);
114        assertEq(bound(type(int256).min + 2, -50, 150), -48);
115        assertEq(bound(type(int256).min + 3, -50, 150), -47);
116        assertEq(bound(type(int256).min, 10, 150), 10);
117        assertEq(bound(type(int256).min + 1, 10, 150), 11);
118        assertEq(bound(type(int256).min + 2, 10, 150), 12);
119        assertEq(bound(type(int256).min + 3, 10, 150), 13);
120
121        assertEq(bound(type(int256).max, -50, 150), 150);
122        assertEq(bound(type(int256).max - 1, -50, 150), 149);
123        assertEq(bound(type(int256).max - 2, -50, 150), 148);
124        assertEq(bound(type(int256).max - 3, -50, 150), 147);
125        assertEq(bound(type(int256).max, -50, -10), -10);
126        assertEq(bound(type(int256).max - 1, -50, -10), -11);
127        assertEq(bound(type(int256).max - 2, -50, -10), -12);
128        assertEq(bound(type(int256).max - 3, -50, -10), -13);
129    }
130
131    function testBoundInt_DistributionIsEven(int256 min, uint256 size) public {
132        size = size % 100 + 1;
133        min = bound(min, -int256(size / 2), int256(size - size / 2));
134        int256 max = min + int256(size) - 1;
135        int256 result;
136
137        for (uint256 i = 1; i <= size * 4; ++i) {
138            // x > max
139            result = bound(max + int256(i), min, max);
140            assertEq(result, min + int256((i - 1) % size));
141            // x < min
142            result = bound(min - int256(i), min, max);
143            assertEq(result, max - int256((i - 1) % size));
144        }
145    }
146
147    function testBoundInt(int256 num, int256 min, int256 max) public {
148        if (min > max) (min, max) = (max, min);
149
150        int256 result = bound(num, min, max);
151
152        assertGe(result, min);
153        assertLe(result, max);
154        assertEq(result, bound(result, min, max));
155        if (num >= min && num <= max) assertEq(result, num);
156    }
157
158    function testBoundIntInt256Max() public {
159        assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1);
160        assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max);
161    }
162
163    function testBoundIntInt256Min() public {
164        assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min);
165        assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1);
166    }
167
168    function testCannotBoundIntMaxLessThanMin() public {
169        vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min."));
170        bound(-5, 100, 10);
171    }
172
173    function testCannotBoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public {
174        vm.assume(min > max);
175        vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min."));
176        bound(num, min, max);
177    }
178
179    /*//////////////////////////////////////////////////////////////////////////
180                                   BYTES TO UINT
181    //////////////////////////////////////////////////////////////////////////*/
182
183    function testBytesToUint() external {
184        bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
185        bytes memory two = hex"02";
186        bytes memory millionEther = hex"d3c21bcecceda1000000";
187
188        assertEq(bytesToUint(maxUint), type(uint256).max);
189        assertEq(bytesToUint(two), 2);
190        assertEq(bytesToUint(millionEther), 1_000_000 ether);
191    }
192
193    function testCannotConvertGT32Bytes() external {
194        bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
195        vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32.");
196        bytesToUint(thirty3Bytes);
197    }
198
199    /*//////////////////////////////////////////////////////////////////////////
200                               COMPUTE CREATE ADDRESS
201    //////////////////////////////////////////////////////////////////////////*/
202
203    function testComputeCreateAddress() external {
204        address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9;
205        uint256 nonce = 14;
206        address createAddress = computeCreateAddress(deployer, nonce);
207        assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45);
208    }
209
210    /*//////////////////////////////////////////////////////////////////////////
211                              COMPUTE CREATE2 ADDRESS
212    //////////////////////////////////////////////////////////////////////////*/
213
214    function testComputeCreate2Address() external {
215        bytes32 salt = bytes32(uint256(31415));
216        bytes32 initcodeHash = keccak256(abi.encode(0x6080));
217        address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9;
218        address create2Address = computeCreate2Address(salt, initcodeHash, deployer);
219        assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3);
220    }
221}
222
223contract StdUtilsForkTest is Test {
224    /*//////////////////////////////////////////////////////////////////////////
225                                  GET TOKEN BALANCES
226    //////////////////////////////////////////////////////////////////////////*/
227
228    address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE;
229    address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170;
230    address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA;
231    address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385;
232
233    address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;
234    address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17;
235    address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52;
236
237    function setUp() public {
238        // All tests of the `getTokenBalances` method are fork tests using live contracts.
239        vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900});
240    }
241
242    function testCannotGetTokenBalances_NonTokenContract() external {
243        // We deploy a mock version so we can properly test the revert.
244        StdUtilsMock stdUtils = new StdUtilsMock();
245
246        // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function,
247        // so the `balanceOf` call should revert.
248        address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f);
249        address[] memory addresses = new address[](1);
250        addresses[0] = USDC_HOLDER_0;
251
252        vm.expectRevert("Multicall3: call failed");
253        stdUtils.getTokenBalances_(token, addresses);
254    }
255
256    function testCannotGetTokenBalances_EOA() external {
257        address eoa = vm.addr({privateKey: 1});
258        address[] memory addresses = new address[](1);
259        addresses[0] = USDC_HOLDER_0;
260        vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract.");
261        getTokenBalances(eoa, addresses);
262    }
263
264    function testGetTokenBalances_Empty() external {
265        address[] memory addresses = new address[](0);
266        uint256[] memory balances = getTokenBalances(USDC, addresses);
267        assertEq(balances.length, 0);
268    }
269
270    function testGetTokenBalances_USDC() external {
271        address[] memory addresses = new address[](2);
272        addresses[0] = USDC_HOLDER_0;
273        addresses[1] = USDC_HOLDER_1;
274        uint256[] memory balances = getTokenBalances(USDC, addresses);
275        assertEq(balances[0], 159_000_000_000_000);
276        assertEq(balances[1], 131_350_000_000_000);
277    }
278
279    function testGetTokenBalances_SHIB() external {
280        address[] memory addresses = new address[](3);
281        addresses[0] = SHIB_HOLDER_0;
282        addresses[1] = SHIB_HOLDER_1;
283        addresses[2] = SHIB_HOLDER_2;
284        uint256[] memory balances = getTokenBalances(SHIB, addresses);
285        assertEq(balances[0], 3_323_256_285_484.42e18);
286        assertEq(balances[1], 1_271_702_771_149.99999928e18);
287        assertEq(balances[2], 606_357_106_247e18);
288    }
289}