@bannynet/core-v6 0.0.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 (48) hide show
  1. package/README.md +53 -0
  2. package/SKILLS.md +94 -0
  3. package/deployments/banny-core-v5/arbitrum/Banny721TokenUriResolver.json +1809 -0
  4. package/deployments/banny-core-v5/arbitrum_sepolia/Banny721TokenUriResolver.json +1795 -0
  5. package/deployments/banny-core-v5/base/Banny721TokenUriResolver.json +1810 -0
  6. package/deployments/banny-core-v5/base_sepolia/Banny721TokenUriResolver.json +1796 -0
  7. package/deployments/banny-core-v5/ethereum/Banny721TokenUriResolver.json +1795 -0
  8. package/deployments/banny-core-v5/optimism/Banny721TokenUriResolver.json +1810 -0
  9. package/deployments/banny-core-v5/optimism_sepolia/Banny721TokenUriResolver.json +1796 -0
  10. package/deployments/banny-core-v5/sepolia/Banny721TokenUriResolver.json +1795 -0
  11. package/foundry.toml +22 -0
  12. package/package.json +53 -0
  13. package/remappings.txt +1 -0
  14. package/script/1.Fix.s.sol +290 -0
  15. package/script/Add.Denver.s.sol +75 -0
  16. package/script/AirdropOutfits.s.sol +2302 -0
  17. package/script/Deploy.s.sol +440 -0
  18. package/script/Drop1.s.sol +979 -0
  19. package/script/MigrationContractArbitrum.sol +494 -0
  20. package/script/MigrationContractArbitrum1.sol +170 -0
  21. package/script/MigrationContractArbitrum2.sol +204 -0
  22. package/script/MigrationContractArbitrum3.sol +174 -0
  23. package/script/MigrationContractArbitrum4.sol +478 -0
  24. package/script/MigrationContractBase1.sol +444 -0
  25. package/script/MigrationContractBase2.sol +175 -0
  26. package/script/MigrationContractBase3.sol +309 -0
  27. package/script/MigrationContractBase4.sol +350 -0
  28. package/script/MigrationContractBase5.sol +259 -0
  29. package/script/MigrationContractEthereum1.sol +468 -0
  30. package/script/MigrationContractEthereum2.sol +306 -0
  31. package/script/MigrationContractEthereum3.sol +349 -0
  32. package/script/MigrationContractEthereum4.sol +352 -0
  33. package/script/MigrationContractEthereum5.sol +354 -0
  34. package/script/MigrationContractEthereum6.sol +270 -0
  35. package/script/MigrationContractEthereum7.sol +439 -0
  36. package/script/MigrationContractEthereum8.sol +385 -0
  37. package/script/MigrationContractOptimism.sol +196 -0
  38. package/script/helpers/BannyverseDeploymentLib.sol +73 -0
  39. package/script/helpers/MigrationHelper.sol +155 -0
  40. package/script/outfit_drop/generate-migration.js +3441 -0
  41. package/script/outfit_drop/raw.json +43276 -0
  42. package/slither-ci.config.json +10 -0
  43. package/sphinx.lock +521 -0
  44. package/src/Banny721TokenUriResolver.sol +1288 -0
  45. package/src/interfaces/IBanny721TokenUriResolver.sol +137 -0
  46. package/test/Banny721TokenUriResolver.t.sol +669 -0
  47. package/test/BannyAttacks.t.sol +322 -0
  48. package/test/DecorateFlow.t.sol +1056 -0
@@ -0,0 +1,352 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.23;
3
+
4
+ import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
5
+ import {JB721TiersHook} from "@bananapus/721-hook-v5/src/JB721TiersHook.sol";
6
+ import {Banny721TokenUriResolver} from "../src/Banny721TokenUriResolver.sol";
7
+ import {MigrationHelper} from "./helpers/MigrationHelper.sol";
8
+
9
+ contract MigrationContractEthereum4 {
10
+ // Define struct to hold all UPC minted tokenIds
11
+ struct MintedIds {
12
+ uint256[20] upc4;
13
+ uint256[1] upc13;
14
+ uint256[1] upc16;
15
+ uint256[1] upc17;
16
+ uint256[2] upc19;
17
+ uint256[4] upc23;
18
+ uint256[2] upc25;
19
+ uint256[1] upc31;
20
+ uint256[1] upc32;
21
+ uint256[1] upc33;
22
+ uint256[4] upc41;
23
+ uint256[1] upc42;
24
+ uint256[1] upc43;
25
+ uint256[2] upc48;
26
+ }
27
+
28
+ address[] private transferOwners;
29
+
30
+ constructor(address[] memory _transferOwners) {
31
+ transferOwners = _transferOwners;
32
+ }
33
+
34
+ function executeMigration(
35
+ address hookAddress,
36
+ address resolverAddress,
37
+ address v4HookAddress,
38
+ address v4ResolverAddress,
39
+ address fallbackV4ResolverAddress
40
+ )
41
+ external
42
+ {
43
+ // Validate addresses
44
+ require(hookAddress != address(0), "Hook address not set");
45
+ require(resolverAddress != address(0), "Resolver address not set");
46
+ require(v4HookAddress != address(0), "V4 Hook address not set");
47
+ require(v4ResolverAddress != address(0), "V4 Resolver address not set");
48
+ require(fallbackV4ResolverAddress != address(0), "V4 fallback resolver address not set");
49
+
50
+ JB721TiersHook hook = JB721TiersHook(hookAddress);
51
+ Banny721TokenUriResolver resolver = Banny721TokenUriResolver(resolverAddress);
52
+ IERC721 v4Hook = IERC721(v4HookAddress);
53
+ Banny721TokenUriResolver v4Resolver = Banny721TokenUriResolver(v4ResolverAddress);
54
+ Banny721TokenUriResolver fallbackV4Resolver = Banny721TokenUriResolver(fallbackV4ResolverAddress);
55
+
56
+ // Ethereum migration chunk 4/6 - 42 items
57
+
58
+ // Step 1: Assets are already minted to this contract by the deployer
59
+
60
+ // Assets are already minted to this contract by the deployer
61
+
62
+ // Create and populate the struct
63
+ // Token IDs follow formula: upc * 1000000000 + unitNumber (unitNumber starts at 1 per UPC)
64
+ MintedIds memory sortedMintedIds;
65
+
66
+ // Populate UPC 4 minted tokenIds (20 items)
67
+ sortedMintedIds.upc4[0] = 4_000_000_028; // Token ID: 4 * 1000000000 + 1
68
+ sortedMintedIds.upc4[1] = 4_000_000_029; // Token ID: 4 * 1000000000 + 2
69
+ sortedMintedIds.upc4[2] = 4_000_000_030; // Token ID: 4 * 1000000000 + 3
70
+ sortedMintedIds.upc4[3] = 4_000_000_031; // Token ID: 4 * 1000000000 + 4
71
+ sortedMintedIds.upc4[4] = 4_000_000_032; // Token ID: 4 * 1000000000 + 5
72
+ sortedMintedIds.upc4[5] = 4_000_000_033; // Token ID: 4 * 1000000000 + 6
73
+ sortedMintedIds.upc4[6] = 4_000_000_034; // Token ID: 4 * 1000000000 + 7
74
+ sortedMintedIds.upc4[7] = 4_000_000_035; // Token ID: 4 * 1000000000 + 8
75
+ sortedMintedIds.upc4[8] = 4_000_000_036; // Token ID: 4 * 1000000000 + 9
76
+ sortedMintedIds.upc4[9] = 4_000_000_037; // Token ID: 4 * 1000000000 + 10
77
+ sortedMintedIds.upc4[10] = 4_000_000_038; // Token ID: 4 * 1000000000 + 11
78
+ sortedMintedIds.upc4[11] = 4_000_000_039; // Token ID: 4 * 1000000000 + 12
79
+ sortedMintedIds.upc4[12] = 4_000_000_040; // Token ID: 4 * 1000000000 + 13
80
+ sortedMintedIds.upc4[13] = 4_000_000_041; // Token ID: 4 * 1000000000 + 14
81
+ sortedMintedIds.upc4[14] = 4_000_000_042; // Token ID: 4 * 1000000000 + 15
82
+ sortedMintedIds.upc4[15] = 4_000_000_043; // Token ID: 4 * 1000000000 + 16
83
+ sortedMintedIds.upc4[16] = 4_000_000_044; // Token ID: 4 * 1000000000 + 17
84
+ sortedMintedIds.upc4[17] = 4_000_000_045; // Token ID: 4 * 1000000000 + 18
85
+ sortedMintedIds.upc4[18] = 4_000_000_046; // Token ID: 4 * 1000000000 + 19
86
+ sortedMintedIds.upc4[19] = 4_000_000_047; // Token ID: 4 * 1000000000 + 20
87
+ // Populate UPC 13 minted tokenIds (1 items)
88
+ sortedMintedIds.upc13[0] = 13_000_000_001; // Token ID: 13 * 1000000000 + 1
89
+ // Populate UPC 16 minted tokenIds (1 items)
90
+ sortedMintedIds.upc16[0] = 16_000_000_001; // Token ID: 16 * 1000000000 + 1
91
+ // Populate UPC 17 minted tokenIds (1 items)
92
+ sortedMintedIds.upc17[0] = 17_000_000_002; // Token ID: 17 * 1000000000 + 1
93
+ // Populate UPC 19 minted tokenIds (2 items)
94
+ sortedMintedIds.upc19[0] = 19_000_000_008; // Token ID: 19 * 1000000000 + 1
95
+ sortedMintedIds.upc19[1] = 19_000_000_009; // Token ID: 19 * 1000000000 + 2
96
+ // Populate UPC 23 minted tokenIds (4 items)
97
+ sortedMintedIds.upc23[0] = 23_000_000_002; // Token ID: 23 * 1000000000 + 1
98
+ sortedMintedIds.upc23[1] = 23_000_000_003; // Token ID: 23 * 1000000000 + 2
99
+ sortedMintedIds.upc23[2] = 23_000_000_004; // Token ID: 23 * 1000000000 + 3
100
+ sortedMintedIds.upc23[3] = 23_000_000_005; // Token ID: 23 * 1000000000 + 4
101
+ // Populate UPC 25 minted tokenIds (2 items)
102
+ sortedMintedIds.upc25[0] = 25_000_000_006; // Token ID: 25 * 1000000000 + 1
103
+ sortedMintedIds.upc25[1] = 25_000_000_007; // Token ID: 25 * 1000000000 + 2
104
+ // Populate UPC 31 minted tokenIds (1 items)
105
+ sortedMintedIds.upc31[0] = 31_000_000_005; // Token ID: 31 * 1000000000 + 1
106
+ // Populate UPC 32 minted tokenIds (1 items)
107
+ sortedMintedIds.upc32[0] = 32_000_000_003; // Token ID: 32 * 1000000000 + 1
108
+ // Populate UPC 33 minted tokenIds (1 items)
109
+ sortedMintedIds.upc33[0] = 33_000_000_001; // Token ID: 33 * 1000000000 + 1
110
+ // Populate UPC 41 minted tokenIds (4 items)
111
+ sortedMintedIds.upc41[0] = 41_000_000_001; // Token ID: 41 * 1000000000 + 1
112
+ sortedMintedIds.upc41[1] = 41_000_000_002; // Token ID: 41 * 1000000000 + 2
113
+ sortedMintedIds.upc41[2] = 41_000_000_003; // Token ID: 41 * 1000000000 + 3
114
+ sortedMintedIds.upc41[3] = 41_000_000_004; // Token ID: 41 * 1000000000 + 4
115
+ // Populate UPC 42 minted tokenIds (1 items)
116
+ sortedMintedIds.upc42[0] = 42_000_000_003; // Token ID: 42 * 1000000000 + 1
117
+ // Populate UPC 43 minted tokenIds (1 items)
118
+ sortedMintedIds.upc43[0] = 43_000_000_005; // Token ID: 43 * 1000000000 + 1
119
+ // Populate UPC 48 minted tokenIds (2 items)
120
+ sortedMintedIds.upc48[0] = 48_000_000_003; // Token ID: 48 * 1000000000 + 1
121
+ sortedMintedIds.upc48[1] = 48_000_000_004; // Token ID: 48 * 1000000000 + 2
122
+ // Step 1.5: Approve resolver to transfer all tokens owned by this contract
123
+ // The resolver needs approval to transfer outfits and backgrounds to itself during decoration
124
+ IERC721(address(hook)).setApprovalForAll(address(resolver), true);
125
+
126
+ // Step 2: Process each Banny body and dress them
127
+
128
+ // Dress Banny 4000000033 (Original)
129
+ {
130
+ uint256[] memory outfitIds = new uint256[](2);
131
+ outfitIds[0] = 19_000_000_008; // V4: 19000000009 -> V5: 19000000008
132
+ outfitIds[1] = 43_000_000_005; // V4: 43000000008 -> V5: 43000000005
133
+
134
+ resolver.decorateBannyWith(address(hook), 4_000_000_033, 0, outfitIds);
135
+
136
+ MigrationHelper.verifyV4AssetMatch(
137
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_033
138
+ );
139
+ }
140
+
141
+ // Dress Banny 4000000039 (Original)
142
+ {
143
+ uint256[] memory outfitIds = new uint256[](4);
144
+ outfitIds[0] = 13_000_000_001; // V4: 13000000001 -> V5: 13000000001
145
+ outfitIds[1] = 19_000_000_009; // V4: 19000000011 -> V5: 19000000009
146
+ outfitIds[2] = 25_000_000_006; // V4: 25000000006 -> V5: 25000000006
147
+ outfitIds[3] = 42_000_000_003; // V4: 42000000004 -> V5: 42000000003
148
+
149
+ resolver.decorateBannyWith(address(hook), 4_000_000_039, 0, outfitIds);
150
+
151
+ MigrationHelper.verifyV4AssetMatch(
152
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_039
153
+ );
154
+ }
155
+
156
+ // Dress Banny 4000000040 (Original)
157
+ {
158
+ uint256[] memory outfitIds = new uint256[](1);
159
+ outfitIds[0] = 25_000_000_007; // V4: 25000000007 -> V5: 25000000007
160
+
161
+ resolver.decorateBannyWith(address(hook), 4_000_000_040, 0, outfitIds);
162
+
163
+ MigrationHelper.verifyV4AssetMatch(
164
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_040
165
+ );
166
+ }
167
+
168
+ // Dress Banny 4000000041 (Original)
169
+ {
170
+ uint256[] memory outfitIds = new uint256[](5);
171
+ outfitIds[0] = 16_000_000_001; // V4: 16000000001 -> V5: 16000000001
172
+ outfitIds[1] = 17_000_000_002; // V4: 17000000002 -> V5: 17000000002
173
+ outfitIds[2] = 31_000_000_005; // V4: 31000000009 -> V5: 31000000005
174
+ outfitIds[3] = 33_000_000_001; // V4: 33000000001 -> V5: 33000000001
175
+ outfitIds[4] = 48_000_000_003; // V4: 48000000002 -> V5: 48000000003
176
+
177
+ resolver.decorateBannyWith(address(hook), 4_000_000_041, 0, outfitIds);
178
+
179
+ MigrationHelper.verifyV4AssetMatch(
180
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_041
181
+ );
182
+ }
183
+
184
+ // Dress Banny 4000000043 (Original)
185
+ {
186
+ uint256[] memory outfitIds = new uint256[](2);
187
+ outfitIds[0] = 32_000_000_003; // V4: 32000000003 -> V5: 32000000003
188
+ outfitIds[1] = 48_000_000_004; // V4: 48000000003 -> V5: 48000000004
189
+
190
+ resolver.decorateBannyWith(address(hook), 4_000_000_043, 0, outfitIds);
191
+
192
+ MigrationHelper.verifyV4AssetMatch(
193
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_043
194
+ );
195
+ }
196
+
197
+ // Dress Banny 4000000044 (Original)
198
+ {
199
+ uint256[] memory outfitIds = new uint256[](2);
200
+ outfitIds[0] = 23_000_000_002; // V4: 23000000002 -> V5: 23000000002
201
+ outfitIds[1] = 41_000_000_001; // V4: 41000000001 -> V5: 41000000001
202
+
203
+ resolver.decorateBannyWith(address(hook), 4_000_000_044, 0, outfitIds);
204
+
205
+ MigrationHelper.verifyV4AssetMatch(
206
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_044
207
+ );
208
+ }
209
+
210
+ // Dress Banny 4000000045 (Original)
211
+ {
212
+ uint256[] memory outfitIds = new uint256[](2);
213
+ outfitIds[0] = 23_000_000_004; // V4: 23000000004 -> V5: 23000000004
214
+ outfitIds[1] = 41_000_000_003; // V4: 41000000003 -> V5: 41000000003
215
+
216
+ resolver.decorateBannyWith(address(hook), 4_000_000_045, 0, outfitIds);
217
+
218
+ MigrationHelper.verifyV4AssetMatch(
219
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_045
220
+ );
221
+ }
222
+
223
+ // Dress Banny 4000000046 (Original)
224
+ {
225
+ uint256[] memory outfitIds = new uint256[](2);
226
+ outfitIds[0] = 23_000_000_005; // V4: 23000000005 -> V5: 23000000005
227
+ outfitIds[1] = 41_000_000_004; // V4: 41000000004 -> V5: 41000000004
228
+
229
+ resolver.decorateBannyWith(address(hook), 4_000_000_046, 0, outfitIds);
230
+
231
+ MigrationHelper.verifyV4AssetMatch(
232
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_046
233
+ );
234
+ }
235
+
236
+ // Dress Banny 4000000047 (Original)
237
+ {
238
+ uint256[] memory outfitIds = new uint256[](2);
239
+ outfitIds[0] = 23_000_000_003; // V4: 23000000003 -> V5: 23000000003
240
+ outfitIds[1] = 41_000_000_002; // V4: 41000000002 -> V5: 41000000002
241
+
242
+ resolver.decorateBannyWith(address(hook), 4_000_000_047, 0, outfitIds);
243
+
244
+ MigrationHelper.verifyV4AssetMatch(
245
+ resolver, v4Resolver, fallbackV4Resolver, address(hook), v4HookAddress, 4_000_000_047
246
+ );
247
+ }
248
+
249
+ // Step 3: Transfer all assets to rightful owners using constructor data
250
+ // Generate token IDs in the same order as items appear (matching mint order)
251
+ // Token ID format: UPC * 1000000000 + unitNumber
252
+ // Note: Only banny body token IDs are guaranteed to match between V4 and V5.
253
+ // Outfits/backgrounds being worn by bannys may have different IDs, but that's OK
254
+ // since they're not transferred (only used in decorateBannyWith calls).
255
+ uint256[] memory generatedTokenIds = new uint256[](transferOwners.length);
256
+
257
+ generatedTokenIds[0] = 4_000_000_028; // Token ID (V4: 4000000028)
258
+ generatedTokenIds[1] = 4_000_000_029; // Token ID (V4: 4000000029)
259
+ generatedTokenIds[2] = 4_000_000_030; // Token ID (V4: 4000000030)
260
+ generatedTokenIds[3] = 4_000_000_031; // Token ID (V4: 4000000031)
261
+ generatedTokenIds[4] = 4_000_000_032; // Token ID (V4: 4000000032)
262
+ generatedTokenIds[5] = 4_000_000_033; // Token ID (V4: 4000000033)
263
+ generatedTokenIds[6] = 4_000_000_034; // Token ID (V4: 4000000034)
264
+ generatedTokenIds[7] = 4_000_000_035; // Token ID (V4: 4000000035)
265
+ generatedTokenIds[8] = 4_000_000_036; // Token ID (V4: 4000000036)
266
+ generatedTokenIds[9] = 4_000_000_037; // Token ID (V4: 4000000037)
267
+ generatedTokenIds[10] = 4_000_000_038; // Token ID (V4: 4000000038)
268
+ generatedTokenIds[11] = 4_000_000_039; // Token ID (V4: 4000000039)
269
+ generatedTokenIds[12] = 4_000_000_040; // Token ID (V4: 4000000040)
270
+ generatedTokenIds[13] = 4_000_000_041; // Token ID (V4: 4000000041)
271
+ generatedTokenIds[14] = 4_000_000_042; // Token ID (V4: 4000000042)
272
+ generatedTokenIds[15] = 4_000_000_043; // Token ID (V4: 4000000043)
273
+ generatedTokenIds[16] = 4_000_000_044; // Token ID (V4: 4000000044)
274
+ generatedTokenIds[17] = 4_000_000_045; // Token ID (V4: 4000000045)
275
+ generatedTokenIds[18] = 4_000_000_046; // Token ID (V4: 4000000046)
276
+ generatedTokenIds[19] = 4_000_000_047; // Token ID (V4: 4000000047)
277
+
278
+ uint256 successfulTransfers = 0;
279
+ uint256 skippedResolverOwned = 0;
280
+
281
+ for (uint256 i = 0; i < transferOwners.length; i++) {
282
+ uint256 tokenId = generatedTokenIds[i];
283
+ // Verify V4 ownership before transferring V5
284
+ address v4Owner = v4Hook.ownerOf(tokenId);
285
+ require(
286
+ v4Owner == transferOwners[i] || v4Owner == address(fallbackV4ResolverAddress),
287
+ "V4/V5 ownership mismatch for token"
288
+ );
289
+
290
+ // Skip transfer if V4 owner is the resolver (resolver holds these tokens, we shouldn't transfer to
291
+ // resolver)
292
+ if (v4Owner == address(v4ResolverAddress) || v4Owner == address(fallbackV4ResolverAddress)) {
293
+ // Token is held by resolver, skip transfer
294
+ skippedResolverOwned++;
295
+ continue;
296
+ }
297
+
298
+ IERC721(address(hook)).safeTransferFrom(address(this), transferOwners[i], tokenId);
299
+ successfulTransfers++;
300
+ }
301
+
302
+ // Verify all expected items were processed (transferred or skipped as expected)
303
+ require(successfulTransfers + skippedResolverOwned == transferOwners.length, "Not all items were processed");
304
+
305
+ // Final verification: Ensure this contract no longer owns any tokens
306
+ // This ensures all transfers completed successfully and no tokens were left behind
307
+ require(hook.balanceOf(address(this)) == 0, "Contract still owns tokens after migration");
308
+
309
+ // Verify tier balances: V5 should never exceed V4 (except for tiers owned by fallback resolver in V4)
310
+
311
+ // // Collect unique owners
312
+ // address[] memory uniqueOwners = new address[](10);
313
+
314
+ // uniqueOwners[0] = 0x7bE8c264c9DCebA3A35990c78d5C4220D8724B6e;
315
+ // uniqueOwners[1] = 0x5A00e8683f37e8B08C744054a0EF606a18b1aEF7;
316
+ // uniqueOwners[2] = 0x59E98040E53d7dC1900B4daf36D9Fbbd4a8f1dA2;
317
+ // uniqueOwners[3] = 0x46f3cC6a1c00A5cD8864d2B92f128196CAE07D15;
318
+ // uniqueOwners[4] = 0x08cF1208e638a5A3623be58d600e35c6199baa9C;
319
+ // uniqueOwners[5] = 0x381CC779761212344f8400373a994d29E17522c6;
320
+ // uniqueOwners[6] = 0x849151d7D0bF1F34b70d5caD5149D28CC2308bf1;
321
+ // uniqueOwners[7] = 0x823b92d6a4b2AED4b15675c7917c9f922ea8ADAD;
322
+ // uniqueOwners[8] = 0x63A2368F4B509438ca90186cb1C15156713D5834;
323
+ // uniqueOwners[9] = 0x95E9A0c113AA9931a4230f91AdE08A491D3f8d54;
324
+
325
+ // // Collect unique tier IDs
326
+ // uint256[] memory uniqueTierIds = new uint256[](14);
327
+
328
+ // uniqueTierIds[0] = 4;
329
+ // uniqueTierIds[1] = 13;
330
+ // uniqueTierIds[2] = 16;
331
+ // uniqueTierIds[3] = 17;
332
+ // uniqueTierIds[4] = 19;
333
+ // uniqueTierIds[5] = 23;
334
+ // uniqueTierIds[6] = 25;
335
+ // uniqueTierIds[7] = 31;
336
+ // uniqueTierIds[8] = 32;
337
+ // uniqueTierIds[9] = 33;
338
+ // uniqueTierIds[10] = 41;
339
+ // uniqueTierIds[11] = 42;
340
+ // uniqueTierIds[12] = 43;
341
+ // uniqueTierIds[13] = 48;
342
+
343
+ // // Verify tier balances: V5 should never exceed V4 (except for tiers owned by fallback resolver in V4)
344
+ // MigrationHelper.verifyTierBalances(
345
+ // hookAddress,
346
+ // v4HookAddress,
347
+ // fallbackV4ResolverAddress,
348
+ // uniqueOwners,
349
+ // uniqueTierIds
350
+ // );
351
+ }
352
+ }