@@ -3,7 +3,21 @@ pragma solidity >=0.7.0 <0.9.0;
3
3
4
4
import "../src/Test.sol " ;
5
5
6
+ contract 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
+
6
16
contract StdUtilsTest is Test {
17
+ /*//////////////////////////////////////////////////////////////////////////
18
+ BOUND UINT
19
+ //////////////////////////////////////////////////////////////////////////*/
20
+
7
21
function testBound () public {
8
22
assertEq (bound (uint256 (5 ), 0 , 4 ), 0 );
9
23
assertEq (bound (uint256 (0 ), 69 , 69 ), 69 );
@@ -74,6 +88,10 @@ contract StdUtilsTest is Test {
74
88
bound (num, min, max);
75
89
}
76
90
91
+ /*//////////////////////////////////////////////////////////////////////////
92
+ BOUND INT
93
+ //////////////////////////////////////////////////////////////////////////*/
94
+
77
95
function testBoundInt () public {
78
96
assertEq (bound (- 3 , 0 , 4 ), 2 );
79
97
assertEq (bound (0 , - 69 , - 69 ), - 69 );
@@ -158,34 +176,114 @@ contract StdUtilsTest is Test {
158
176
bound (num, min, max);
159
177
}
160
178
161
- function testGenerateCreateAddress () external {
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 {
162
204
address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9 ;
163
205
uint256 nonce = 14 ;
164
206
address createAddress = computeCreateAddress (deployer, nonce);
165
207
assertEq (createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 );
166
208
}
167
209
168
- function testGenerateCreate2Address () external {
210
+ /*//////////////////////////////////////////////////////////////////////////
211
+ COMPUTE CREATE2 ADDRESS
212
+ //////////////////////////////////////////////////////////////////////////*/
213
+
214
+ function testComputeCreate2Address () external {
169
215
bytes32 salt = bytes32 (uint256 (31415 ));
170
216
bytes32 initcodeHash = keccak256 (abi.encode (0x6080 ));
171
217
address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9 ;
172
218
address create2Address = computeCreate2Address (salt, initcodeHash, deployer);
173
219
assertEq (create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3 );
174
220
}
221
+ }
175
222
176
- function testBytesToUint () external {
177
- bytes memory maxUint = hex " ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff " ;
178
- bytes memory two = hex " 02 " ;
179
- bytes memory millionEther = hex " d3c21bcecceda1000000 " ;
223
+ contract StdUtilsForkTest is Test {
224
+ /*//////////////////////////////////////////////////////////////////////////
225
+ GET TOKEN BALANCES
226
+ //////////////////////////////////////////////////////////////////////////*/
180
227
181
- assertEq (bytesToUint (maxUint), type (uint256 ).max);
182
- assertEq (bytesToUint (two), 2 );
183
- assertEq (bytesToUint (millionEther), 1_000_000 ether);
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 });
184
240
}
185
241
186
- function testCannotConvertGT32Bytes () external {
187
- bytes memory thirty3Bytes = hex "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff " ;
188
- vm.expectRevert ("StdUtils bytesToUint(bytes): Bytes length exceeds 32. " );
189
- bytesToUint (thirty3Bytes);
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 );
190
288
}
191
289
}
0 commit comments