@bgd-labs/aave-address-book 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.gitmodules +4 -0
  2. package/CHANGELOG.md +56 -0
  3. package/LICENSE +7 -0
  4. package/README.md +94 -0
  5. package/addressbook_logo.png +0 -0
  6. package/dist/AaveAddressBook.d.ts +17 -0
  7. package/dist/AaveAddressBook.js +20 -0
  8. package/dist/AaveV2Avalanche.d.ts +9 -0
  9. package/dist/AaveV2Avalanche.js +12 -0
  10. package/dist/AaveV2Ethereum.d.ts +9 -0
  11. package/dist/AaveV2Ethereum.js +12 -0
  12. package/dist/AaveV2EthereumAMM.d.ts +9 -0
  13. package/dist/AaveV2EthereumAMM.js +12 -0
  14. package/dist/AaveV2EthereumArc.d.ts +9 -0
  15. package/dist/AaveV2EthereumArc.js +12 -0
  16. package/dist/AaveV2Fuji.d.ts +9 -0
  17. package/dist/AaveV2Fuji.js +12 -0
  18. package/dist/AaveV2Mumbai.d.ts +9 -0
  19. package/dist/AaveV2Mumbai.js +12 -0
  20. package/dist/AaveV2Polygon.d.ts +9 -0
  21. package/dist/AaveV2Polygon.js +12 -0
  22. package/dist/AaveV3Arbitrum.d.ts +9 -0
  23. package/dist/AaveV3Arbitrum.js +12 -0
  24. package/dist/AaveV3Avalanche.d.ts +9 -0
  25. package/dist/AaveV3Avalanche.js +12 -0
  26. package/dist/AaveV3Fantom.d.ts +9 -0
  27. package/dist/AaveV3Fantom.js +12 -0
  28. package/dist/AaveV3FantomTestnet.d.ts +9 -0
  29. package/dist/AaveV3FantomTestnet.js +12 -0
  30. package/dist/AaveV3Fuji.d.ts +9 -0
  31. package/dist/AaveV3Fuji.js +12 -0
  32. package/dist/AaveV3Harmony.d.ts +9 -0
  33. package/dist/AaveV3Harmony.js +12 -0
  34. package/dist/AaveV3Mumbai.d.ts +9 -0
  35. package/dist/AaveV3Mumbai.js +12 -0
  36. package/dist/AaveV3Optimism.d.ts +9 -0
  37. package/dist/AaveV3Optimism.js +12 -0
  38. package/dist/AaveV3OptimismKovan.d.ts +9 -0
  39. package/dist/AaveV3OptimismKovan.js +12 -0
  40. package/dist/AaveV3Polygon.d.ts +9 -0
  41. package/dist/AaveV3Polygon.js +12 -0
  42. package/foundry.toml +8 -0
  43. package/lib/forge-std/.github/workflows/tests.yml +27 -0
  44. package/lib/forge-std/.gitmodules +3 -0
  45. package/lib/forge-std/LICENSE-APACHE +203 -0
  46. package/lib/forge-std/LICENSE-MIT +25 -0
  47. package/lib/forge-std/README.md +246 -0
  48. package/lib/forge-std/lib/ds-test/LICENSE +674 -0
  49. package/lib/forge-std/lib/ds-test/Makefile +14 -0
  50. package/lib/forge-std/lib/ds-test/default.nix +4 -0
  51. package/lib/forge-std/lib/ds-test/demo/demo.sol +222 -0
  52. package/lib/forge-std/lib/ds-test/src/test.sol +469 -0
  53. package/lib/forge-std/src/Script.sol +39 -0
  54. package/lib/forge-std/src/StdJson.sol +118 -0
  55. package/lib/forge-std/src/Test.sol +1134 -0
  56. package/lib/forge-std/src/Vm.sol +231 -0
  57. package/lib/forge-std/src/console.sol +1533 -0
  58. package/lib/forge-std/src/console2.sol +1538 -0
  59. package/lib/forge-std/src/test/Script.t.sol +12 -0
  60. package/lib/forge-std/src/test/StdAssertions.t.sol +591 -0
  61. package/lib/forge-std/src/test/StdCheats.t.sol +282 -0
  62. package/lib/forge-std/src/test/StdError.t.sol +124 -0
  63. package/lib/forge-std/src/test/StdMath.t.sol +200 -0
  64. package/lib/forge-std/src/test/StdStorage.t.sol +321 -0
  65. package/lib/forge-std/src/test/fixtures/broadcast.log.json +187 -0
  66. package/package.json +39 -0
  67. package/src/AaveAddressBook.sol +28 -0
  68. package/src/AaveAddressBookV2.sol +143 -0
  69. package/src/AaveAddressBookV2Testnet.sol +74 -0
  70. package/src/AaveAddressBookV3.sol +166 -0
  71. package/src/AaveAddressBookV3Testnet.sol +120 -0
  72. package/src/AaveGovernanceV2.sol +549 -0
  73. package/src/AaveV2.sol +931 -0
  74. package/src/AaveV2Avalanche.sol +35 -0
  75. package/src/AaveV2Ethereum.sol +36 -0
  76. package/src/AaveV2EthereumAMM.sol +36 -0
  77. package/src/AaveV2EthereumArc.sol +36 -0
  78. package/src/AaveV2Fuji.sol +35 -0
  79. package/src/AaveV2Mumbai.sol +35 -0
  80. package/src/AaveV2Polygon.sol +35 -0
  81. package/src/AaveV3.sol +2406 -0
  82. package/src/AaveV3Arbitrum.sol +34 -0
  83. package/src/AaveV3Avalanche.sol +34 -0
  84. package/src/AaveV3Fantom.sol +34 -0
  85. package/src/AaveV3FantomTestnet.sol +34 -0
  86. package/src/AaveV3Fuji.sol +34 -0
  87. package/src/AaveV3Harmony.sol +34 -0
  88. package/src/AaveV3HarmonyTestnet.sol +34 -0
  89. package/src/AaveV3Mumbai.sol +34 -0
  90. package/src/AaveV3Optimism.sol +34 -0
  91. package/src/AaveV3OptimismKovan.sol +34 -0
  92. package/src/AaveV3Polygon.sol +34 -0
  93. package/src/Common.sol +9 -0
  94. package/src/test/AaveV2Ethereum.t.sol +72 -0
  95. package/src/test/AaveV2Misfits.t.sol +33 -0
  96. package/src/test/AaveV3Avalanche.t.sol +65 -0
  97. package/src/ts/AaveAddressBook.ts +17 -0
  98. package/src/ts/AaveV2Avalanche.ts +11 -0
  99. package/src/ts/AaveV2Ethereum.ts +12 -0
  100. package/src/ts/AaveV2EthereumAMM.ts +12 -0
  101. package/src/ts/AaveV2EthereumArc.ts +12 -0
  102. package/src/ts/AaveV2Fuji.ts +11 -0
  103. package/src/ts/AaveV2Mumbai.ts +11 -0
  104. package/src/ts/AaveV2Polygon.ts +11 -0
  105. package/src/ts/AaveV3Arbitrum.ts +12 -0
  106. package/src/ts/AaveV3Avalanche.ts +12 -0
  107. package/src/ts/AaveV3Fantom.ts +12 -0
  108. package/src/ts/AaveV3FantomTestnet.ts +12 -0
  109. package/src/ts/AaveV3Fuji.ts +12 -0
  110. package/src/ts/AaveV3Harmony.ts +12 -0
  111. package/src/ts/AaveV3Mumbai.ts +12 -0
  112. package/src/ts/AaveV3Optimism.ts +12 -0
  113. package/src/ts/AaveV3OptimismKovan.ts +12 -0
  114. package/src/ts/AaveV3Polygon.ts +12 -0
  115. package/tsconfig.json +101 -0
@@ -0,0 +1,1134 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity >=0.6.0 <0.9.0;
3
+ pragma experimental ABIEncoderV2;
4
+
5
+ import "./Script.sol";
6
+ import "ds-test/test.sol";
7
+
8
+ // Wrappers around Cheatcodes to avoid footguns
9
+ abstract contract Test is DSTest, Script {
10
+ using stdStorage for StdStorage;
11
+
12
+ uint256 internal constant UINT256_MAX =
13
+ 115792089237316195423570985008687907853269984665640564039457584007913129639935;
14
+
15
+ StdStorage internal stdstore;
16
+
17
+ /*//////////////////////////////////////////////////////////////////////////
18
+ STD-LOGS
19
+ //////////////////////////////////////////////////////////////////////////*/
20
+
21
+ event log_array(uint256[] val);
22
+ event log_array(int256[] val);
23
+ event log_array(address[] val);
24
+ event log_named_array(string key, uint256[] val);
25
+ event log_named_array(string key, int256[] val);
26
+ event log_named_array(string key, address[] val);
27
+
28
+ /*//////////////////////////////////////////////////////////////////////////
29
+ STD-CHEATS
30
+ //////////////////////////////////////////////////////////////////////////*/
31
+
32
+ // Skip forward or rewind time by the specified number of seconds
33
+ function skip(uint256 time) internal {
34
+ vm.warp(block.timestamp + time);
35
+ }
36
+
37
+ function rewind(uint256 time) internal {
38
+ vm.warp(block.timestamp - time);
39
+ }
40
+
41
+ // Setup a prank from an address that has some ether
42
+ function hoax(address who) internal {
43
+ vm.deal(who, 1 << 128);
44
+ vm.prank(who);
45
+ }
46
+
47
+ function hoax(address who, uint256 give) internal {
48
+ vm.deal(who, give);
49
+ vm.prank(who);
50
+ }
51
+
52
+ function hoax(address who, address origin) internal {
53
+ vm.deal(who, 1 << 128);
54
+ vm.prank(who, origin);
55
+ }
56
+
57
+ function hoax(address who, address origin, uint256 give) internal {
58
+ vm.deal(who, give);
59
+ vm.prank(who, origin);
60
+ }
61
+
62
+ // Start perpetual prank from an address that has some ether
63
+ function startHoax(address who) internal {
64
+ vm.deal(who, 1 << 128);
65
+ vm.startPrank(who);
66
+ }
67
+
68
+ function startHoax(address who, uint256 give) internal {
69
+ vm.deal(who, give);
70
+ vm.startPrank(who);
71
+ }
72
+
73
+ // Start perpetual prank from an address that has some ether
74
+ // tx.origin is set to the origin parameter
75
+ function startHoax(address who, address origin) internal {
76
+ vm.deal(who, 1 << 128);
77
+ vm.startPrank(who, origin);
78
+ }
79
+
80
+ function startHoax(address who, address origin, uint256 give) internal {
81
+ vm.deal(who, give);
82
+ vm.startPrank(who, origin);
83
+ }
84
+
85
+ function changePrank(address who) internal {
86
+ vm.stopPrank();
87
+ vm.startPrank(who);
88
+ }
89
+
90
+ // creates a labeled address and the corresponding private key
91
+ function makeAddrAndKey(string memory name) internal returns(address addr, uint256 privateKey) {
92
+ privateKey = uint256(keccak256(abi.encodePacked(name)));
93
+ addr = vm.addr(privateKey);
94
+ vm.label(addr, name);
95
+ }
96
+
97
+ // creates a labeled address
98
+ function makeAddr(string memory name) internal returns(address addr) {
99
+ (addr,) = makeAddrAndKey(name);
100
+ }
101
+
102
+ // DEPRECATED: Use `deal` instead
103
+ function tip(address token, address to, uint256 give) internal {
104
+ emit log_named_string("WARNING", "Test tip(address,address,uint256): The `tip` stdcheat has been deprecated. Use `deal` instead.");
105
+ stdstore
106
+ .target(token)
107
+ .sig(0x70a08231)
108
+ .with_key(to)
109
+ .checked_write(give);
110
+ }
111
+
112
+ // The same as Vm's `deal`
113
+ // Use the alternative signature for ERC20 tokens
114
+ function deal(address to, uint256 give) internal {
115
+ vm.deal(to, give);
116
+ }
117
+
118
+ // Set the balance of an account for any ERC20 token
119
+ // Use the alternative signature to update `totalSupply`
120
+ function deal(address token, address to, uint256 give) internal {
121
+ deal(token, to, give, false);
122
+ }
123
+
124
+ function deal(address token, address to, uint256 give, bool adjust) internal {
125
+ // get current balance
126
+ (, bytes memory balData) = token.call(abi.encodeWithSelector(0x70a08231, to));
127
+ uint256 prevBal = abi.decode(balData, (uint256));
128
+
129
+ // update balance
130
+ stdstore
131
+ .target(token)
132
+ .sig(0x70a08231)
133
+ .with_key(to)
134
+ .checked_write(give);
135
+
136
+ // update total supply
137
+ if(adjust){
138
+ (, bytes memory totSupData) = token.call(abi.encodeWithSelector(0x18160ddd));
139
+ uint256 totSup = abi.decode(totSupData, (uint256));
140
+ if(give < prevBal) {
141
+ totSup -= (prevBal - give);
142
+ } else {
143
+ totSup += (give - prevBal);
144
+ }
145
+ stdstore
146
+ .target(token)
147
+ .sig(0x18160ddd)
148
+ .checked_write(totSup);
149
+ }
150
+ }
151
+
152
+ function bound(uint256 x, uint256 min, uint256 max) internal virtual returns (uint256 result) {
153
+ require(min <= max, "Test bound(uint256,uint256,uint256): Max is less than min.");
154
+
155
+ uint256 size = max - min;
156
+
157
+ if (size == 0)
158
+ {
159
+ result = min;
160
+ }
161
+ else if (size == UINT256_MAX)
162
+ {
163
+ result = x;
164
+ }
165
+ else
166
+ {
167
+ ++size; // make `max` inclusive
168
+ uint256 mod = x % size;
169
+ result = min + mod;
170
+ }
171
+
172
+ emit log_named_uint("Bound Result", result);
173
+ }
174
+
175
+ // Deploy a contract by fetching the contract bytecode from
176
+ // the artifacts directory
177
+ // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))`
178
+ function deployCode(string memory what, bytes memory args)
179
+ internal
180
+ returns (address addr)
181
+ {
182
+ bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);
183
+ /// @solidity memory-safe-assembly
184
+ assembly {
185
+ addr := create(0, add(bytecode, 0x20), mload(bytecode))
186
+ }
187
+
188
+ require(
189
+ addr != address(0),
190
+ "Test deployCode(string,bytes): Deployment failed."
191
+ );
192
+ }
193
+
194
+ function deployCode(string memory what)
195
+ internal
196
+ returns (address addr)
197
+ {
198
+ bytes memory bytecode = vm.getCode(what);
199
+ /// @solidity memory-safe-assembly
200
+ assembly {
201
+ addr := create(0, add(bytecode, 0x20), mload(bytecode))
202
+ }
203
+
204
+ require(
205
+ addr != address(0),
206
+ "Test deployCode(string): Deployment failed."
207
+ );
208
+ }
209
+
210
+ /// deploy contract with value on construction
211
+ function deployCode(string memory what, bytes memory args, uint256 val)
212
+ internal
213
+ returns (address addr)
214
+ {
215
+ bytes memory bytecode = abi.encodePacked(vm.getCode(what), args);
216
+ /// @solidity memory-safe-assembly
217
+ assembly {
218
+ addr := create(val, add(bytecode, 0x20), mload(bytecode))
219
+ }
220
+
221
+ require(
222
+ addr != address(0),
223
+ "Test deployCode(string,bytes,uint256): Deployment failed."
224
+ );
225
+ }
226
+
227
+ function deployCode(string memory what, uint256 val)
228
+ internal
229
+ returns (address addr)
230
+ {
231
+ bytes memory bytecode = vm.getCode(what);
232
+ /// @solidity memory-safe-assembly
233
+ assembly {
234
+ addr := create(val, add(bytecode, 0x20), mload(bytecode))
235
+ }
236
+
237
+ require(
238
+ addr != address(0),
239
+ "Test deployCode(string,uint256): Deployment failed."
240
+ );
241
+ }
242
+
243
+ /*//////////////////////////////////////////////////////////////////////////
244
+ STD-ASSERTIONS
245
+ //////////////////////////////////////////////////////////////////////////*/
246
+
247
+ function fail(string memory err) internal virtual {
248
+ emit log_named_string("Error", err);
249
+ fail();
250
+ }
251
+
252
+ function assertFalse(bool data) internal virtual {
253
+ assertTrue(!data);
254
+ }
255
+
256
+ function assertFalse(bool data, string memory err) internal virtual {
257
+ assertTrue(!data, err);
258
+ }
259
+
260
+ function assertEq(bool a, bool b) internal {
261
+ if (a != b) {
262
+ emit log ("Error: a == b not satisfied [bool]");
263
+ emit log_named_string (" Expected", b ? "true" : "false");
264
+ emit log_named_string (" Actual", a ? "true" : "false");
265
+ fail();
266
+ }
267
+ }
268
+
269
+ function assertEq(bool a, bool b, string memory err) internal {
270
+ if (a != b) {
271
+ emit log_named_string("Error", err);
272
+ assertEq(a, b);
273
+ }
274
+ }
275
+
276
+ function assertEq(bytes memory a, bytes memory b) internal {
277
+ assertEq0(a, b);
278
+ }
279
+
280
+ function assertEq(bytes memory a, bytes memory b, string memory err) internal {
281
+ assertEq0(a, b, err);
282
+ }
283
+
284
+ function assertEq(uint256[] memory a, uint256[] memory b) internal {
285
+ if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {
286
+ emit log("Error: a == b not satisfied [uint[]]");
287
+ emit log_named_array(" Expected", b);
288
+ emit log_named_array(" Actual", a);
289
+ fail();
290
+ }
291
+ }
292
+
293
+ function assertEq(int256[] memory a, int256[] memory b) internal {
294
+ if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {
295
+ emit log("Error: a == b not satisfied [int[]]");
296
+ emit log_named_array(" Expected", b);
297
+ emit log_named_array(" Actual", a);
298
+ fail();
299
+ }
300
+ }
301
+
302
+ function assertEq(address[] memory a, address[] memory b) internal {
303
+ if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {
304
+ emit log("Error: a == b not satisfied [address[]]");
305
+ emit log_named_array(" Expected", b);
306
+ emit log_named_array(" Actual", a);
307
+ fail();
308
+ }
309
+ }
310
+
311
+ function assertEq(uint256[] memory a, uint256[] memory b, string memory err) internal {
312
+ if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {
313
+ emit log_named_string("Error", err);
314
+ assertEq(a, b);
315
+ }
316
+ }
317
+
318
+ function assertEq(int256[] memory a, int256[] memory b, string memory err) internal {
319
+ if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {
320
+ emit log_named_string("Error", err);
321
+ assertEq(a, b);
322
+ }
323
+ }
324
+
325
+
326
+ function assertEq(address[] memory a, address[] memory b, string memory err) internal {
327
+ if (keccak256(abi.encode(a)) != keccak256(abi.encode(b))) {
328
+ emit log_named_string("Error", err);
329
+ assertEq(a, b);
330
+ }
331
+ }
332
+
333
+ function assertApproxEqAbs(
334
+ uint256 a,
335
+ uint256 b,
336
+ uint256 maxDelta
337
+ ) internal virtual {
338
+ uint256 delta = stdMath.delta(a, b);
339
+
340
+ if (delta > maxDelta) {
341
+ emit log ("Error: a ~= b not satisfied [uint]");
342
+ emit log_named_uint (" Expected", b);
343
+ emit log_named_uint (" Actual", a);
344
+ emit log_named_uint (" Max Delta", maxDelta);
345
+ emit log_named_uint (" Delta", delta);
346
+ fail();
347
+ }
348
+ }
349
+
350
+ function assertApproxEqAbs(
351
+ uint256 a,
352
+ uint256 b,
353
+ uint256 maxDelta,
354
+ string memory err
355
+ ) internal virtual {
356
+ uint256 delta = stdMath.delta(a, b);
357
+
358
+ if (delta > maxDelta) {
359
+ emit log_named_string ("Error", err);
360
+ assertApproxEqAbs(a, b, maxDelta);
361
+ }
362
+ }
363
+
364
+ function assertApproxEqAbs(
365
+ int256 a,
366
+ int256 b,
367
+ uint256 maxDelta
368
+ ) internal virtual {
369
+ uint256 delta = stdMath.delta(a, b);
370
+
371
+ if (delta > maxDelta) {
372
+ emit log ("Error: a ~= b not satisfied [int]");
373
+ emit log_named_int (" Expected", b);
374
+ emit log_named_int (" Actual", a);
375
+ emit log_named_uint (" Max Delta", maxDelta);
376
+ emit log_named_uint (" Delta", delta);
377
+ fail();
378
+ }
379
+ }
380
+
381
+ function assertApproxEqAbs(
382
+ int256 a,
383
+ int256 b,
384
+ uint256 maxDelta,
385
+ string memory err
386
+ ) internal virtual {
387
+ uint256 delta = stdMath.delta(a, b);
388
+
389
+ if (delta > maxDelta) {
390
+ emit log_named_string ("Error", err);
391
+ assertApproxEqAbs(a, b, maxDelta);
392
+ }
393
+ }
394
+
395
+ function assertApproxEqRel(
396
+ uint256 a,
397
+ uint256 b,
398
+ uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100%
399
+ ) internal virtual {
400
+ if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too.
401
+
402
+ uint256 percentDelta = stdMath.percentDelta(a, b);
403
+
404
+ if (percentDelta > maxPercentDelta) {
405
+ emit log ("Error: a ~= b not satisfied [uint]");
406
+ emit log_named_uint (" Expected", b);
407
+ emit log_named_uint (" Actual", a);
408
+ emit log_named_decimal_uint (" Max % Delta", maxPercentDelta, 18);
409
+ emit log_named_decimal_uint (" % Delta", percentDelta, 18);
410
+ fail();
411
+ }
412
+ }
413
+
414
+ function assertApproxEqRel(
415
+ uint256 a,
416
+ uint256 b,
417
+ uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100%
418
+ string memory err
419
+ ) internal virtual {
420
+ if (b == 0) return assertEq(a, b, err); // If the expected is 0, actual must be too.
421
+
422
+ uint256 percentDelta = stdMath.percentDelta(a, b);
423
+
424
+ if (percentDelta > maxPercentDelta) {
425
+ emit log_named_string ("Error", err);
426
+ assertApproxEqRel(a, b, maxPercentDelta);
427
+ }
428
+ }
429
+
430
+ function assertApproxEqRel(
431
+ int256 a,
432
+ int256 b,
433
+ uint256 maxPercentDelta
434
+ ) internal virtual {
435
+ if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too.
436
+
437
+ uint256 percentDelta = stdMath.percentDelta(a, b);
438
+
439
+ if (percentDelta > maxPercentDelta) {
440
+ emit log ("Error: a ~= b not satisfied [int]");
441
+ emit log_named_int (" Expected", b);
442
+ emit log_named_int (" Actual", a);
443
+ emit log_named_decimal_uint(" Max % Delta", maxPercentDelta, 18);
444
+ emit log_named_decimal_uint(" % Delta", percentDelta, 18);
445
+ fail();
446
+ }
447
+ }
448
+
449
+ function assertApproxEqRel(
450
+ int256 a,
451
+ int256 b,
452
+ uint256 maxPercentDelta,
453
+ string memory err
454
+ ) internal virtual {
455
+ if (b == 0) return assertEq(a, b); // If the expected is 0, actual must be too.
456
+
457
+ uint256 percentDelta = stdMath.percentDelta(a, b);
458
+
459
+ if (percentDelta > maxPercentDelta) {
460
+ emit log_named_string ("Error", err);
461
+ assertApproxEqRel(a, b, maxPercentDelta);
462
+ }
463
+ }
464
+
465
+ /*//////////////////////////////////////////////////////////////
466
+ JSON PARSING
467
+ //////////////////////////////////////////////////////////////*/
468
+
469
+ // Data structures to parse Transaction objects from the broadcast artifact
470
+ // that conform to EIP1559. The Raw structs is what is parsed from the JSON
471
+ // and then converted to the one that is used by the user for better UX.
472
+
473
+ struct RawTx1559 {
474
+ string[] arguments;
475
+ address contractAddress;
476
+ string contractName;
477
+ // json value name = function
478
+ string functionSig;
479
+ bytes32 hash;
480
+ // json value name = tx
481
+ RawTx1559Detail txDetail;
482
+ // json value name = type
483
+ string opcode;
484
+ }
485
+
486
+ struct RawTx1559Detail {
487
+ AccessList[] accessList;
488
+ bytes data;
489
+ address from;
490
+ bytes gas;
491
+ bytes nonce;
492
+ address to;
493
+ bytes txType;
494
+ bytes value;
495
+ }
496
+
497
+ struct Tx1559 {
498
+ string[] arguments;
499
+ address contractAddress;
500
+ string contractName;
501
+ string functionSig;
502
+ bytes32 hash;
503
+ Tx1559Detail txDetail;
504
+ string opcode;
505
+ }
506
+
507
+ struct Tx1559Detail {
508
+ AccessList[] accessList;
509
+ bytes data;
510
+ address from;
511
+ uint256 gas;
512
+ uint256 nonce;
513
+ address to;
514
+ uint256 txType;
515
+ uint256 value;
516
+ }
517
+
518
+ // Data structures to parse Transaction objects from the broadcast artifact
519
+ // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON
520
+ // and then converted to the one that is used by the user for better UX.
521
+
522
+ struct TxLegacy{
523
+ string[] arguments;
524
+ address contractAddress;
525
+ string contractName;
526
+ string functionSig;
527
+ string hash;
528
+ string opcode;
529
+ TxDetailLegacy transaction;
530
+ }
531
+
532
+ struct TxDetailLegacy{
533
+ AccessList[] accessList;
534
+ uint256 chainId;
535
+ bytes data;
536
+ address from;
537
+ uint256 gas;
538
+ uint256 gasPrice;
539
+ bytes32 hash;
540
+ uint256 nonce;
541
+ bytes1 opcode;
542
+ bytes32 r;
543
+ bytes32 s;
544
+ uint256 txType;
545
+ address to;
546
+ uint8 v;
547
+ uint256 value;
548
+ }
549
+
550
+ struct AccessList{
551
+ address accessAddress;
552
+ bytes32[] storageKeys;
553
+ }
554
+
555
+ // Data structures to parse Receipt objects from the broadcast artifact.
556
+ // The Raw structs is what is parsed from the JSON
557
+ // and then converted to the one that is used by the user for better UX.
558
+
559
+ struct RawReceipt {
560
+ bytes32 blockHash;
561
+ bytes blockNumber;
562
+ address contractAddress;
563
+ bytes cumulativeGasUsed;
564
+ bytes effectiveGasPrice;
565
+ address from;
566
+ bytes gasUsed;
567
+ RawReceiptLog[] logs;
568
+ bytes logsBloom;
569
+ bytes status;
570
+ address to;
571
+ bytes32 transactionHash;
572
+ bytes transactionIndex;
573
+ }
574
+
575
+ struct Receipt {
576
+ bytes32 blockHash;
577
+ uint256 blockNumber;
578
+ address contractAddress;
579
+ uint256 cumulativeGasUsed;
580
+ uint256 effectiveGasPrice;
581
+ address from;
582
+ uint256 gasUsed;
583
+ ReceiptLog[] logs;
584
+ bytes logsBloom;
585
+ uint256 status;
586
+ address to;
587
+ bytes32 transactionHash;
588
+ uint256 transactionIndex;
589
+ }
590
+
591
+ // Data structures to parse the entire broadcast artifact, assuming the
592
+ // transactions conform to EIP1559.
593
+
594
+ struct EIP1559ScriptArtifact {
595
+ string[] libraries;
596
+ string path;
597
+ string[] pending;
598
+ Receipt[] receipts;
599
+ uint256 timestamp;
600
+ Tx1559[] transactions;
601
+ TxReturn[] txReturns;
602
+ }
603
+
604
+ struct RawEIP1559ScriptArtifact {
605
+ string[] libraries;
606
+ string path;
607
+ string[] pending;
608
+ RawReceipt[] receipts;
609
+ TxReturn[] txReturns;
610
+ uint256 timestamp;
611
+ RawTx1559[] transactions;
612
+ }
613
+
614
+ struct RawReceiptLog {
615
+ // json value = address
616
+ address logAddress;
617
+ bytes32 blockHash;
618
+ bytes blockNumber;
619
+ bytes data;
620
+ bytes logIndex;
621
+ bool removed;
622
+ bytes32[] topics;
623
+ bytes32 transactionHash;
624
+ bytes transactionIndex;
625
+ bytes transactionLogIndex;
626
+ }
627
+
628
+ struct ReceiptLog {
629
+ // json value = address
630
+ address logAddress;
631
+ bytes32 blockHash;
632
+ uint256 blockNumber;
633
+ bytes data;
634
+ uint256 logIndex;
635
+ bytes32[] topics;
636
+ uint256 transactionIndex;
637
+ uint256 transactionLogIndex;
638
+ bool removed;
639
+ }
640
+
641
+ struct TxReturn {
642
+ string internalType;
643
+ string value;
644
+ }
645
+
646
+
647
+ function readEIP1559ScriptArtifact(string memory path)
648
+ internal
649
+ returns(EIP1559ScriptArtifact memory)
650
+ {
651
+ string memory data = vm.readFile(path);
652
+ bytes memory parsedData = vm.parseJson(data);
653
+ RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact));
654
+ EIP1559ScriptArtifact memory artifact;
655
+ artifact.libraries = rawArtifact.libraries;
656
+ artifact.path = rawArtifact.path;
657
+ artifact.timestamp = rawArtifact.timestamp;
658
+ artifact.pending = rawArtifact.pending;
659
+ artifact.txReturns = rawArtifact.txReturns;
660
+ artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts);
661
+ artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions);
662
+ return artifact;
663
+ }
664
+
665
+ function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs)
666
+ internal pure
667
+ returns (Tx1559[] memory)
668
+ {
669
+ Tx1559[] memory txs = new Tx1559[](rawTxs.length);
670
+ for (uint i; i < rawTxs.length; i++) {
671
+ txs[i] = rawToConvertedEIPTx1559(rawTxs[i]);
672
+ }
673
+ return txs;
674
+ }
675
+
676
+ function rawToConvertedEIPTx1559(RawTx1559 memory rawTx)
677
+ internal pure
678
+ returns (Tx1559 memory)
679
+ {
680
+ Tx1559 memory transaction;
681
+ transaction.arguments = rawTx.arguments;
682
+ transaction.contractName = rawTx.contractName;
683
+ transaction.functionSig = rawTx.functionSig;
684
+ transaction.hash= rawTx.hash;
685
+ transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail);
686
+ transaction.opcode= rawTx.opcode;
687
+ return transaction;
688
+ }
689
+
690
+ function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail)
691
+ internal pure
692
+ returns (Tx1559Detail memory)
693
+ {
694
+ Tx1559Detail memory txDetail;
695
+ txDetail.data = rawDetail.data;
696
+ txDetail.from = rawDetail.from;
697
+ txDetail.to = rawDetail.to;
698
+ txDetail.nonce = bytesToUint(rawDetail.nonce);
699
+ txDetail.txType = bytesToUint(rawDetail.txType);
700
+ txDetail.value = bytesToUint(rawDetail.value);
701
+ txDetail.gas = bytesToUint(rawDetail.gas);
702
+ txDetail.accessList = rawDetail.accessList;
703
+ return txDetail;
704
+
705
+ }
706
+
707
+ function readTx1559s(string memory path)
708
+ internal
709
+ returns (Tx1559[] memory)
710
+ {
711
+ string memory deployData = vm.readFile(path);
712
+ bytes memory parsedDeployData =
713
+ vm.parseJson(deployData, ".transactions");
714
+ RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[]));
715
+ return rawToConvertedEIPTx1559s(rawTxs);
716
+ }
717
+
718
+
719
+ function readTx1559(string memory path, uint256 index)
720
+ internal
721
+ returns (Tx1559 memory)
722
+ {
723
+ string memory deployData = vm.readFile(path);
724
+ string memory key = string(abi.encodePacked(".transactions[",vm.toString(index), "]"));
725
+ bytes memory parsedDeployData =
726
+ vm.parseJson(deployData, key);
727
+ RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559));
728
+ return rawToConvertedEIPTx1559(rawTx);
729
+ }
730
+
731
+
732
+ // Analogous to readTransactions, but for receipts.
733
+ function readReceipts(string memory path)
734
+ internal
735
+ returns (Receipt[] memory)
736
+ {
737
+ string memory deployData = vm.readFile(path);
738
+ bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts");
739
+ RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[]));
740
+ return rawToConvertedReceipts(rawReceipts);
741
+ }
742
+
743
+ function readReceipt(string memory path, uint index)
744
+ internal
745
+ returns (Receipt memory)
746
+ {
747
+ string memory deployData = vm.readFile(path);
748
+ string memory key = string(abi.encodePacked(".receipts[",vm.toString(index), "]"));
749
+ bytes memory parsedDeployData = vm.parseJson(deployData, key);
750
+ RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt));
751
+ return rawToConvertedReceipt(rawReceipt);
752
+ }
753
+
754
+ function rawToConvertedReceipts(RawReceipt[] memory rawReceipts)
755
+ internal pure
756
+ returns(Receipt[] memory)
757
+ {
758
+ Receipt[] memory receipts = new Receipt[](rawReceipts.length);
759
+ for (uint i; i < rawReceipts.length; i++) {
760
+ receipts[i] = rawToConvertedReceipt(rawReceipts[i]);
761
+ }
762
+ return receipts;
763
+ }
764
+
765
+ function rawToConvertedReceipt(RawReceipt memory rawReceipt)
766
+ internal pure
767
+ returns(Receipt memory)
768
+ {
769
+ Receipt memory receipt;
770
+ receipt.blockHash = rawReceipt.blockHash;
771
+ receipt.to = rawReceipt.to;
772
+ receipt.from = rawReceipt.from;
773
+ receipt.contractAddress = rawReceipt.contractAddress;
774
+ receipt.effectiveGasPrice = bytesToUint(rawReceipt.effectiveGasPrice);
775
+ receipt.cumulativeGasUsed= bytesToUint(rawReceipt.cumulativeGasUsed);
776
+ receipt.gasUsed = bytesToUint(rawReceipt.gasUsed);
777
+ receipt.status = bytesToUint(rawReceipt.status);
778
+ receipt.transactionIndex = bytesToUint(rawReceipt.transactionIndex);
779
+ receipt.blockNumber = bytesToUint(rawReceipt.blockNumber);
780
+ receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs);
781
+ receipt.logsBloom = rawReceipt.logsBloom;
782
+ receipt.transactionHash = rawReceipt.transactionHash;
783
+ return receipt;
784
+ }
785
+
786
+ function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs)
787
+ internal pure
788
+ returns (ReceiptLog[] memory)
789
+ {
790
+ ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length);
791
+ for (uint i; i < rawLogs.length; i++) {
792
+ logs[i].logAddress = rawLogs[i].logAddress;
793
+ logs[i].blockHash = rawLogs[i].blockHash;
794
+ logs[i].blockNumber = bytesToUint(rawLogs[i].blockNumber);
795
+ logs[i].data = rawLogs[i].data;
796
+ logs[i].logIndex = bytesToUint(rawLogs[i].logIndex);
797
+ logs[i].topics = rawLogs[i].topics;
798
+ logs[i].transactionIndex = bytesToUint(rawLogs[i].transactionIndex);
799
+ logs[i].transactionLogIndex = bytesToUint(rawLogs[i].transactionLogIndex);
800
+ logs[i].removed = rawLogs[i].removed;
801
+ }
802
+ return logs;
803
+
804
+ }
805
+
806
+ function bytesToUint(bytes memory b) internal pure returns (uint256){
807
+ uint256 number;
808
+ for (uint i=0; i < b.length; i++) {
809
+ number = number + uint(uint8(b[i]))*(2**(8*(b.length-(i+1))));
810
+ }
811
+ return number;
812
+ }
813
+
814
+ }
815
+
816
+ /*//////////////////////////////////////////////////////////////////////////
817
+ STD-ERRORS
818
+ //////////////////////////////////////////////////////////////////////////*/
819
+
820
+ library stdError {
821
+ bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01);
822
+ bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11);
823
+ bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12);
824
+ bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21);
825
+ bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22);
826
+ bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31);
827
+ bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32);
828
+ bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41);
829
+ bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51);
830
+ // DEPRECATED: Use Vm's `expectRevert` without any arguments instead
831
+ bytes public constant lowLevelError = bytes(""); // `0x`
832
+ }
833
+
834
+ /*//////////////////////////////////////////////////////////////////////////
835
+ STD-STORAGE
836
+ //////////////////////////////////////////////////////////////////////////*/
837
+
838
+ struct StdStorage {
839
+ mapping (address => mapping(bytes4 => mapping(bytes32 => uint256))) slots;
840
+ mapping (address => mapping(bytes4 => mapping(bytes32 => bool))) finds;
841
+
842
+ bytes32[] _keys;
843
+ bytes4 _sig;
844
+ uint256 _depth;
845
+ address _target;
846
+ bytes32 _set;
847
+ }
848
+
849
+ library stdStorage {
850
+ event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint slot);
851
+ event WARNING_UninitedSlot(address who, uint slot);
852
+
853
+ uint256 private constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935;
854
+ int256 private constant INT256_MAX = 57896044618658097711785492504343953926634992332820282019728792003956564819967;
855
+
856
+ Vm private constant vm_std_store = Vm(address(uint160(uint256(keccak256('hevm cheat code')))));
857
+
858
+ function sigs(
859
+ string memory sigStr
860
+ )
861
+ internal
862
+ pure
863
+ returns (bytes4)
864
+ {
865
+ return bytes4(keccak256(bytes(sigStr)));
866
+ }
867
+
868
+ /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against
869
+ // slot complexity:
870
+ // if flat, will be bytes32(uint256(uint));
871
+ // if map, will be keccak256(abi.encode(key, uint(slot)));
872
+ // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));
873
+ // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);
874
+ function find(
875
+ StdStorage storage self
876
+ )
877
+ internal
878
+ returns (uint256)
879
+ {
880
+ address who = self._target;
881
+ bytes4 fsig = self._sig;
882
+ uint256 field_depth = self._depth;
883
+ bytes32[] memory ins = self._keys;
884
+
885
+ // calldata to test against
886
+ if (self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {
887
+ return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];
888
+ }
889
+ bytes memory cald = abi.encodePacked(fsig, flatten(ins));
890
+ vm_std_store.record();
891
+ bytes32 fdat;
892
+ {
893
+ (, bytes memory rdat) = who.staticcall(cald);
894
+ fdat = bytesToBytes32(rdat, 32*field_depth);
895
+ }
896
+
897
+ (bytes32[] memory reads, ) = vm_std_store.accesses(address(who));
898
+ if (reads.length == 1) {
899
+ bytes32 curr = vm_std_store.load(who, reads[0]);
900
+ if (curr == bytes32(0)) {
901
+ emit WARNING_UninitedSlot(who, uint256(reads[0]));
902
+ }
903
+ if (fdat != curr) {
904
+ require(false, "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.");
905
+ }
906
+ emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[0]));
907
+ self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[0]);
908
+ self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;
909
+ } else if (reads.length > 1) {
910
+ for (uint256 i = 0; i < reads.length; i++) {
911
+ bytes32 prev = vm_std_store.load(who, reads[i]);
912
+ if (prev == bytes32(0)) {
913
+ emit WARNING_UninitedSlot(who, uint256(reads[i]));
914
+ }
915
+ // store
916
+ vm_std_store.store(who, reads[i], bytes32(hex"1337"));
917
+ bool success;
918
+ bytes memory rdat;
919
+ {
920
+ (success, rdat) = who.staticcall(cald);
921
+ fdat = bytesToBytes32(rdat, 32*field_depth);
922
+ }
923
+
924
+ if (success && fdat == bytes32(hex"1337")) {
925
+ // we found which of the slots is the actual one
926
+ emit SlotFound(who, fsig, keccak256(abi.encodePacked(ins, field_depth)), uint256(reads[i]));
927
+ self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = uint256(reads[i]);
928
+ self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))] = true;
929
+ vm_std_store.store(who, reads[i], prev);
930
+ break;
931
+ }
932
+ vm_std_store.store(who, reads[i], prev);
933
+ }
934
+ } else {
935
+ require(false, "stdStorage find(StdStorage): No storage use detected for target.");
936
+ }
937
+
938
+ require(self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))], "stdStorage find(StdStorage): Slot(s) not found.");
939
+
940
+ delete self._target;
941
+ delete self._sig;
942
+ delete self._keys;
943
+ delete self._depth;
944
+
945
+ return self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))];
946
+ }
947
+
948
+ function target(StdStorage storage self, address _target) internal returns (StdStorage storage) {
949
+ self._target = _target;
950
+ return self;
951
+ }
952
+
953
+ function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) {
954
+ self._sig = _sig;
955
+ return self;
956
+ }
957
+
958
+ function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) {
959
+ self._sig = sigs(_sig);
960
+ return self;
961
+ }
962
+
963
+ function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) {
964
+ self._keys.push(bytes32(uint256(uint160(who))));
965
+ return self;
966
+ }
967
+
968
+ function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) {
969
+ self._keys.push(bytes32(amt));
970
+ return self;
971
+ }
972
+ function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) {
973
+ self._keys.push(key);
974
+ return self;
975
+ }
976
+
977
+ function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) {
978
+ self._depth = _depth;
979
+ return self;
980
+ }
981
+
982
+ function checked_write(StdStorage storage self, address who) internal {
983
+ checked_write(self, bytes32(uint256(uint160(who))));
984
+ }
985
+
986
+ function checked_write(StdStorage storage self, uint256 amt) internal {
987
+ checked_write(self, bytes32(amt));
988
+ }
989
+
990
+ function checked_write(StdStorage storage self, bool write) internal {
991
+ bytes32 t;
992
+ /// @solidity memory-safe-assembly
993
+ assembly {
994
+ t := write
995
+ }
996
+ checked_write(self, t);
997
+ }
998
+
999
+ function checked_write(
1000
+ StdStorage storage self,
1001
+ bytes32 set
1002
+ ) internal {
1003
+ address who = self._target;
1004
+ bytes4 fsig = self._sig;
1005
+ uint256 field_depth = self._depth;
1006
+ bytes32[] memory ins = self._keys;
1007
+
1008
+ bytes memory cald = abi.encodePacked(fsig, flatten(ins));
1009
+ if (!self.finds[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]) {
1010
+ find(self);
1011
+ }
1012
+ bytes32 slot = bytes32(self.slots[who][fsig][keccak256(abi.encodePacked(ins, field_depth))]);
1013
+
1014
+ bytes32 fdat;
1015
+ {
1016
+ (, bytes memory rdat) = who.staticcall(cald);
1017
+ fdat = bytesToBytes32(rdat, 32*field_depth);
1018
+ }
1019
+ bytes32 curr = vm_std_store.load(who, slot);
1020
+
1021
+ if (fdat != curr) {
1022
+ require(false, "stdStorage find(StdStorage): Packed slot. This would cause dangerous overwriting and currently isn't supported.");
1023
+ }
1024
+ vm_std_store.store(who, slot, set);
1025
+ delete self._target;
1026
+ delete self._sig;
1027
+ delete self._keys;
1028
+ delete self._depth;
1029
+ }
1030
+
1031
+ function read(StdStorage storage self) private returns (bytes memory) {
1032
+ address t = self._target;
1033
+ uint256 s = find(self);
1034
+ return abi.encode(vm_std_store.load(t, bytes32(s)));
1035
+ }
1036
+
1037
+ function read_bytes32(StdStorage storage self) internal returns (bytes32) {
1038
+ return abi.decode(read(self), (bytes32));
1039
+ }
1040
+
1041
+
1042
+ function read_bool(StdStorage storage self) internal returns (bool) {
1043
+ int256 v = read_int(self);
1044
+ if (v == 0) return false;
1045
+ if (v == 1) return true;
1046
+ revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool.");
1047
+ }
1048
+
1049
+ function read_address(StdStorage storage self) internal returns (address) {
1050
+ return abi.decode(read(self), (address));
1051
+ }
1052
+
1053
+ function read_uint(StdStorage storage self) internal returns (uint256) {
1054
+ return abi.decode(read(self), (uint256));
1055
+ }
1056
+
1057
+ function read_int(StdStorage storage self) internal returns (int256) {
1058
+ return abi.decode(read(self), (int256));
1059
+ }
1060
+
1061
+ function bytesToBytes32(bytes memory b, uint offset) public pure returns (bytes32) {
1062
+ bytes32 out;
1063
+
1064
+ uint256 max = b.length > 32 ? 32 : b.length;
1065
+ for (uint i = 0; i < max; i++) {
1066
+ out |= bytes32(b[offset + i] & 0xFF) >> (i * 8);
1067
+ }
1068
+ return out;
1069
+ }
1070
+
1071
+ function flatten(bytes32[] memory b) private pure returns (bytes memory)
1072
+ {
1073
+ bytes memory result = new bytes(b.length * 32);
1074
+ for (uint256 i = 0; i < b.length; i++) {
1075
+ bytes32 k = b[i];
1076
+ /// @solidity memory-safe-assembly
1077
+ assembly {
1078
+ mstore(add(result, add(32, mul(32, i))), k)
1079
+ }
1080
+ }
1081
+
1082
+ return result;
1083
+ }
1084
+
1085
+
1086
+
1087
+ }
1088
+
1089
+
1090
+ /*//////////////////////////////////////////////////////////////////////////
1091
+ STD-MATH
1092
+ //////////////////////////////////////////////////////////////////////////*/
1093
+
1094
+ library stdMath {
1095
+ int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;
1096
+
1097
+ function abs(int256 a) internal pure returns (uint256) {
1098
+ // Required or it will fail when `a = type(int256).min`
1099
+ if (a == INT256_MIN)
1100
+ return 57896044618658097711785492504343953926634992332820282019728792003956564819968;
1101
+
1102
+ return uint256(a > 0 ? a : -a);
1103
+ }
1104
+
1105
+ function delta(uint256 a, uint256 b) internal pure returns (uint256) {
1106
+ return a > b
1107
+ ? a - b
1108
+ : b - a;
1109
+ }
1110
+
1111
+ function delta(int256 a, int256 b) internal pure returns (uint256) {
1112
+ // a and b are of the same sign
1113
+ // this works thanks to two's complement, the left-most bit is the sign bit
1114
+ if ((a ^ b) > -1) {
1115
+ return delta(abs(a), abs(b));
1116
+ }
1117
+
1118
+ // a and b are of opposite signs
1119
+ return abs(a) + abs(b);
1120
+ }
1121
+
1122
+ function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {
1123
+ uint256 absDelta = delta(a, b);
1124
+
1125
+ return absDelta * 1e18 / b;
1126
+ }
1127
+
1128
+ function percentDelta(int256 a, int256 b) internal pure returns (uint256) {
1129
+ uint256 absDelta = delta(a, b);
1130
+ uint256 absB = abs(b);
1131
+
1132
+ return absDelta * 1e18 / absB;
1133
+ }
1134
+ }