@zoralabs/coins 1.1.2 → 2.1.0

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 (78) hide show
  1. package/.turbo/turbo-build.log +107 -110
  2. package/CHANGELOG.md +50 -0
  3. package/README.md +48 -1
  4. package/abis/BaseCoin.json +442 -0
  5. package/abis/BaseZoraV4CoinHook.json +6 -2
  6. package/abis/CoinTest.json +3 -246
  7. package/abis/CoinUniV4Test.json +20 -0
  8. package/abis/ContentCoinHook.json +6 -2
  9. package/abis/CreatorCoinHook.json +6 -2
  10. package/abis/FactoryTest.json +8 -133
  11. package/abis/FeeEstimatorHook.json +6 -2
  12. package/abis/HooksTest.json +0 -26
  13. package/abis/ICoin.json +378 -0
  14. package/abis/ICoinV3.json +378 -0
  15. package/abis/IZoraFactory.json +0 -18
  16. package/abis/IZoraV4CoinHook.json +2 -2
  17. package/abis/LiquidityMigrationTest.json +101 -0
  18. package/abis/MockBadFactory.json +15 -0
  19. package/abis/Ownable2StepUpgradeable.json +138 -0
  20. package/abis/ZoraFactoryImpl.json +38 -65
  21. package/addresses/8453.json +5 -5
  22. package/dist/index.cjs +272 -268
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.js +270 -266
  25. package/dist/index.js.map +1 -1
  26. package/dist/wagmiGenerated.d.ts +397 -470
  27. package/dist/wagmiGenerated.d.ts.map +1 -1
  28. package/package/wagmiGenerated.ts +275 -271
  29. package/package.json +3 -3
  30. package/script/DeployPostDeploymentHooks.s.sol +2 -2
  31. package/script/TestBackingCoinSwap.s.sol +9 -9
  32. package/script/TestV4Swap.s.sol +9 -9
  33. package/script/UpgradeFactoryImpl.s.sol +0 -1
  34. package/src/BaseCoin.sol +109 -6
  35. package/src/ContentCoin.sol +45 -0
  36. package/src/CreatorCoin.sol +7 -5
  37. package/src/ZoraFactoryImpl.sol +12 -95
  38. package/src/deployment/CoinsDeployerBase.sol +13 -30
  39. package/src/hooks/BaseZoraV4CoinHook.sol +8 -6
  40. package/src/hooks/deployment/BuySupplyWithSwapRouterHook.sol +4 -5
  41. package/src/interfaces/ICoin.sol +67 -1
  42. package/src/interfaces/ICreatorCoin.sol +2 -2
  43. package/src/interfaces/IZoraFactory.sol +0 -5
  44. package/src/interfaces/IZoraV4CoinHook.sol +1 -1
  45. package/src/libs/CoinConfigurationVersions.sol +1 -39
  46. package/src/libs/CoinRewardsV4.sol +2 -2
  47. package/src/libs/CoinSetup.sol +1 -4
  48. package/src/libs/UniV4SwapHelper.sol +1 -1
  49. package/src/libs/UniV4SwapToCurrency.sol +2 -2
  50. package/src/libs/V4Liquidity.sol +1 -1
  51. package/src/version/ContractVersionBase.sol +1 -1
  52. package/test/Coin.t.sol +112 -535
  53. package/test/CoinUniV4.t.sol +66 -10
  54. package/test/DeploymentHooks.t.sol +5 -102
  55. package/test/Factory.t.sol +49 -291
  56. package/test/LiquidityMigration.t.sol +160 -2
  57. package/test/MultiOwnable.t.sol +36 -36
  58. package/test/Upgrades.t.sol +23 -42
  59. package/test/utils/BaseTest.sol +39 -84
  60. package/test/utils/FeeEstimatorHook.sol +3 -3
  61. package/wagmi.config.ts +2 -2
  62. package/abis/Coin.json +0 -1912
  63. package/abis/DopplerUniswapV3Test.json +0 -800
  64. package/abis/ICoinV4.json +0 -1048
  65. package/abis/Simulate.json +0 -29
  66. package/abis/UniV3BuySell.json +0 -12
  67. package/abis/UniV3Errors.json +0 -32
  68. package/script/Simulate.s.sol +0 -59
  69. package/src/Coin.sol +0 -236
  70. package/src/CoinV4.sol +0 -151
  71. package/src/interfaces/ICoinV4.sol +0 -74
  72. package/src/libs/CoinDopplerUniV3.sol +0 -50
  73. package/src/libs/CoinRewards.sol +0 -201
  74. package/src/libs/CoinSetupV3.sol +0 -50
  75. package/src/libs/UniV3BuySell.sol +0 -231
  76. package/src/libs/UniV3Errors.sol +0 -11
  77. package/test/CoinDopplerUniV3.t.sol +0 -310
  78. /package/abis/{CoinV4.json → ContentCoin.json} +0 -0
@@ -13,9 +13,11 @@ import {LpPosition} from "../src/types/LpPosition.sol";
13
13
  import {V4Liquidity} from "../src/libs/V4Liquidity.sol";
14
14
  import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
15
15
  import {IZoraV4CoinHook} from "../src/interfaces/IZoraV4CoinHook.sol";
16
- import {ICoinV4} from "../src/interfaces/ICoinV4.sol";
16
+ import {ICoin} from "../src/interfaces/ICoin.sol";
17
17
  import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
18
18
  import {CoinCommon} from "../src/libs/CoinCommon.sol";
19
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
20
+ import {IHooksUpgradeGate} from "../src/interfaces/IHooksUpgradeGate.sol";
19
21
 
20
22
  contract LiquidityMigrationReceiver is IUpgradeableDestinationV4Hook, IERC165 {
21
23
  function initializeFromMigration(
@@ -175,7 +177,7 @@ contract LiquidityMigrationTest is BaseTest {
175
177
  // migrate the liquidity
176
178
  vm.prank(users.creator);
177
179
  vm.expectEmit(true, true, true, true);
178
- emit ICoinV4.LiquidityMigrated(poolKey, fromPoolKeyHash, newPoolKey, toPoolKeyHash);
180
+ emit ICoin.LiquidityMigrated(poolKey, fromPoolKeyHash, newPoolKey, toPoolKeyHash);
179
181
  coinV4.migrateLiquidity(address(newHook), "");
180
182
  }
181
183
 
@@ -230,4 +232,160 @@ contract LiquidityMigrationTest is BaseTest {
230
232
  vm.expectRevert(abi.encodeWithSelector(IZoraV4CoinHook.OnlyCoin.selector, users.creator, address(coinV4)));
231
233
  IUpgradeableV4Hook(originalHook).migrateLiquidity(address(newHook), poolKey, "");
232
234
  }
235
+
236
+ // Hook Upgrade Gate Tests
237
+ function test_hookUpgradeGate_removeUpgradePath() public {
238
+ address baseImpl = makeAddr("baseImpl");
239
+ address upgradeImpl = makeAddr("upgradeImpl");
240
+
241
+ // First register the upgrade path
242
+ address[] memory baseImpls = new address[](1);
243
+ baseImpls[0] = baseImpl;
244
+
245
+ vm.prank(hookUpgradeGate.owner());
246
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
247
+
248
+ // Verify it's registered
249
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(baseImpl, upgradeImpl));
250
+
251
+ // Remove the upgrade path
252
+ vm.prank(hookUpgradeGate.owner());
253
+ vm.expectEmit(true, true, false, false);
254
+ emit IHooksUpgradeGate.UpgradeRemoved(baseImpl, upgradeImpl);
255
+ hookUpgradeGate.removeUpgradePath(baseImpl, upgradeImpl);
256
+
257
+ // Verify it's removed
258
+ assertFalse(hookUpgradeGate.isRegisteredUpgradePath(baseImpl, upgradeImpl));
259
+ }
260
+
261
+ function test_hookUpgradeGate_removeUpgradePath_onlyOwner() public {
262
+ address baseImpl = makeAddr("baseImpl");
263
+ address upgradeImpl = makeAddr("upgradeImpl");
264
+ address nonOwner = makeAddr("nonOwner");
265
+
266
+ // Try to remove upgrade path as non-owner
267
+ vm.prank(nonOwner);
268
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, nonOwner));
269
+ hookUpgradeGate.removeUpgradePath(baseImpl, upgradeImpl);
270
+ }
271
+
272
+ function test_hookUpgradeGate_registerUpgradePath_onlyOwner() public {
273
+ address baseImpl = makeAddr("baseImpl");
274
+ address upgradeImpl = makeAddr("upgradeImpl");
275
+ address nonOwner = makeAddr("nonOwner");
276
+
277
+ address[] memory baseImpls = new address[](1);
278
+ baseImpls[0] = baseImpl;
279
+
280
+ // Try to register upgrade path as non-owner
281
+ vm.prank(nonOwner);
282
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, nonOwner));
283
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
284
+ }
285
+
286
+ function test_hookUpgradeGate_registerMultipleUpgradePaths() public {
287
+ address baseImpl1 = makeAddr("baseImpl1");
288
+ address baseImpl2 = makeAddr("baseImpl2");
289
+ address baseImpl3 = makeAddr("baseImpl3");
290
+ address upgradeImpl = makeAddr("upgradeImpl");
291
+
292
+ address[] memory baseImpls = new address[](3);
293
+ baseImpls[0] = baseImpl1;
294
+ baseImpls[1] = baseImpl2;
295
+ baseImpls[2] = baseImpl3;
296
+
297
+ // Register multiple upgrade paths at once
298
+ vm.prank(hookUpgradeGate.owner());
299
+ vm.expectEmit(true, true, false, false);
300
+ emit IHooksUpgradeGate.UpgradeRegistered(baseImpl1, upgradeImpl);
301
+ vm.expectEmit(true, true, false, false);
302
+ emit IHooksUpgradeGate.UpgradeRegistered(baseImpl2, upgradeImpl);
303
+ vm.expectEmit(true, true, false, false);
304
+ emit IHooksUpgradeGate.UpgradeRegistered(baseImpl3, upgradeImpl);
305
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
306
+
307
+ // Verify all paths are registered
308
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(baseImpl1, upgradeImpl));
309
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(baseImpl2, upgradeImpl));
310
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(baseImpl3, upgradeImpl));
311
+ }
312
+
313
+ function test_hookUpgradeGate_registerEmptyArray() public {
314
+ address upgradeImpl = makeAddr("upgradeImpl");
315
+ address[] memory baseImpls = new address[](0);
316
+
317
+ // Register with empty array - should succeed but do nothing
318
+ vm.prank(hookUpgradeGate.owner());
319
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
320
+
321
+ // No events should be emitted, no state changes
322
+ }
323
+
324
+ function test_hookUpgradeGate_removeNonexistentUpgradePath() public {
325
+ address baseImpl = makeAddr("baseImpl");
326
+ address upgradeImpl = makeAddr("upgradeImpl");
327
+
328
+ // Try to remove a path that was never registered
329
+ vm.prank(hookUpgradeGate.owner());
330
+ vm.expectEmit(true, true, false, false);
331
+ emit IHooksUpgradeGate.UpgradeRemoved(baseImpl, upgradeImpl);
332
+ hookUpgradeGate.removeUpgradePath(baseImpl, upgradeImpl);
333
+
334
+ // Should still be false (was already false)
335
+ assertFalse(hookUpgradeGate.isRegisteredUpgradePath(baseImpl, upgradeImpl));
336
+ }
337
+
338
+ function test_hookUpgradeGate_registerSamePathTwice() public {
339
+ address baseImpl = makeAddr("baseImpl");
340
+ address upgradeImpl = makeAddr("upgradeImpl");
341
+
342
+ address[] memory baseImpls = new address[](1);
343
+ baseImpls[0] = baseImpl;
344
+
345
+ // Register once
346
+ vm.prank(hookUpgradeGate.owner());
347
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
348
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(baseImpl, upgradeImpl));
349
+
350
+ // Register again - should succeed and overwrite (true -> true)
351
+ vm.prank(hookUpgradeGate.owner());
352
+ vm.expectEmit(true, true, false, false);
353
+ emit IHooksUpgradeGate.UpgradeRegistered(baseImpl, upgradeImpl);
354
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
355
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(baseImpl, upgradeImpl));
356
+ }
357
+
358
+ function test_hookUpgradeGate_zeroAddressHandling() public {
359
+ address[] memory baseImpls = new address[](2);
360
+ baseImpls[0] = address(0);
361
+ baseImpls[1] = makeAddr("baseImpl");
362
+ address upgradeImpl = address(0);
363
+
364
+ // Should allow zero addresses (no validation in contract)
365
+ vm.prank(hookUpgradeGate.owner());
366
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
367
+
368
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(address(0), address(0)));
369
+ assertTrue(hookUpgradeGate.isRegisteredUpgradePath(makeAddr("baseImpl"), address(0)));
370
+ }
371
+
372
+ function test_hookUpgradeGate_isAllowedHookUpgradeMapping() public {
373
+ address baseImpl = makeAddr("baseImpl");
374
+ address upgradeImpl = makeAddr("upgradeImpl");
375
+
376
+ // Test direct mapping access
377
+ assertFalse(hookUpgradeGate.isAllowedHookUpgrade(baseImpl, upgradeImpl));
378
+
379
+ // Register upgrade path
380
+ address[] memory baseImpls = new address[](1);
381
+ baseImpls[0] = baseImpl;
382
+ vm.prank(hookUpgradeGate.owner());
383
+ hookUpgradeGate.registerUpgradePath(baseImpls, upgradeImpl);
384
+
385
+ // Test direct mapping access
386
+ assertTrue(hookUpgradeGate.isAllowedHookUpgrade(baseImpl, upgradeImpl));
387
+
388
+ // Should match isRegisteredUpgradePath
389
+ assertEq(hookUpgradeGate.isAllowedHookUpgrade(baseImpl, upgradeImpl), hookUpgradeGate.isRegisteredUpgradePath(baseImpl, upgradeImpl));
390
+ }
233
391
  }
@@ -7,13 +7,13 @@ contract MultiOwnableTest is BaseTest {
7
7
  function setUp() public override {
8
8
  super.setUp();
9
9
 
10
- _deployCoin();
10
+ _deployV4Coin();
11
11
  }
12
12
 
13
13
  function test_initial_owners() public view {
14
- assertEq(coin.owners().length, 1);
15
- assertEq(coin.owners()[0], users.creator);
16
- assertEq(coin.isOwner(users.creator), true);
14
+ assertEq(coinV4.owners().length, 1);
15
+ assertEq(coinV4.owners()[0], users.creator);
16
+ assertEq(coinV4.isOwner(users.creator), true);
17
17
  }
18
18
 
19
19
  function test_add_owners() public {
@@ -22,21 +22,21 @@ contract MultiOwnableTest is BaseTest {
22
22
  newOwners[1] = makeAddr("NewOwner2");
23
23
 
24
24
  vm.prank(users.creator);
25
- coin.addOwners(newOwners);
25
+ coinV4.addOwners(newOwners);
26
26
 
27
- assertEq(coin.owners().length, 3);
28
- assertEq(coin.isOwner(users.creator), true);
29
- assertEq(coin.isOwner(newOwners[0]), true);
30
- assertEq(coin.isOwner(newOwners[1]), true);
27
+ assertEq(coinV4.owners().length, 3);
28
+ assertEq(coinV4.isOwner(users.creator), true);
29
+ assertEq(coinV4.isOwner(newOwners[0]), true);
30
+ assertEq(coinV4.isOwner(newOwners[1]), true);
31
31
  }
32
32
 
33
33
  function test_add_owner() public {
34
34
  vm.prank(users.creator);
35
- coin.addOwner(address(this));
35
+ coinV4.addOwner(address(this));
36
36
 
37
- assertEq(coin.owners().length, 2);
38
- assertEq(coin.isOwner(users.creator), true);
39
- assertEq(coin.isOwner(address(this)), true);
37
+ assertEq(coinV4.owners().length, 2);
38
+ assertEq(coinV4.isOwner(users.creator), true);
39
+ assertEq(coinV4.isOwner(address(this)), true);
40
40
  }
41
41
 
42
42
  function test_remove_owners() public {
@@ -45,67 +45,67 @@ contract MultiOwnableTest is BaseTest {
45
45
  newOwners[1] = makeAddr("NewOwner2");
46
46
 
47
47
  vm.prank(users.creator);
48
- coin.addOwners(newOwners);
48
+ coinV4.addOwners(newOwners);
49
49
 
50
50
  vm.prank(users.creator);
51
- coin.removeOwners(newOwners);
51
+ coinV4.removeOwners(newOwners);
52
52
 
53
- assertEq(coin.owners().length, 1);
54
- assertEq(coin.isOwner(users.creator), true);
55
- assertEq(coin.isOwner(newOwners[0]), false);
56
- assertEq(coin.isOwner(newOwners[1]), false);
53
+ assertEq(coinV4.owners().length, 1);
54
+ assertEq(coinV4.isOwner(users.creator), true);
55
+ assertEq(coinV4.isOwner(newOwners[0]), false);
56
+ assertEq(coinV4.isOwner(newOwners[1]), false);
57
57
  }
58
58
 
59
59
  function test_remove_owner() public {
60
60
  vm.prank(users.creator);
61
- coin.addOwner(address(this));
61
+ coinV4.addOwner(address(this));
62
62
 
63
63
  vm.prank(address(this));
64
- coin.removeOwner(users.creator);
64
+ coinV4.removeOwner(users.creator);
65
65
 
66
- assertEq(coin.owners().length, 1);
67
- assertEq(coin.isOwner(users.creator), false);
68
- assertEq(coin.isOwner(address(this)), true);
66
+ assertEq(coinV4.owners().length, 1);
67
+ assertEq(coinV4.isOwner(users.creator), false);
68
+ assertEq(coinV4.isOwner(address(this)), true);
69
69
  }
70
70
 
71
71
  function test_revert_only_owner_can_add() public {
72
72
  vm.expectRevert(abi.encodeWithSelector(MultiOwnable.OnlyOwner.selector));
73
- coin.addOwner(address(this));
73
+ coinV4.addOwner(address(this));
74
74
  }
75
75
 
76
76
  function test_revert_only_owner_can_remove() public {
77
77
  vm.expectRevert(abi.encodeWithSelector(MultiOwnable.OnlyOwner.selector));
78
78
 
79
79
  vm.prank(address(this));
80
- coin.removeOwner(users.creator);
80
+ coinV4.removeOwner(users.creator);
81
81
  }
82
82
 
83
83
  function test_revert_cannot_remove_not_owner() public {
84
84
  vm.expectRevert(abi.encodeWithSelector(MultiOwnable.NotOwner.selector));
85
85
  vm.prank(users.creator);
86
- coin.removeOwner(address(this));
86
+ coinV4.removeOwner(address(this));
87
87
  }
88
88
 
89
89
  function test_revert_last_owner_must_revoke() public {
90
90
  address newOwner = makeAddr("NewOwner1");
91
91
 
92
92
  vm.prank(users.creator);
93
- coin.addOwner(newOwner);
93
+ coinV4.addOwner(newOwner);
94
94
 
95
95
  vm.prank(newOwner);
96
- coin.removeOwner(users.creator);
96
+ coinV4.removeOwner(users.creator);
97
97
 
98
98
  vm.prank(newOwner);
99
99
  vm.expectRevert(abi.encodeWithSelector(MultiOwnable.UseRevokeOwnershipToRemoveSelf.selector));
100
- coin.removeOwner(newOwner);
100
+ coinV4.removeOwner(newOwner);
101
101
  }
102
102
 
103
103
  function test_revoke_ownership() public {
104
104
  vm.prank(users.creator);
105
- coin.revokeOwnership();
105
+ coinV4.revokeOwnership();
106
106
 
107
- assertEq(coin.owners().length, 0);
108
- assertEq(coin.isOwner(users.creator), false);
107
+ assertEq(coinV4.owners().length, 0);
108
+ assertEq(coinV4.isOwner(users.creator), false);
109
109
  }
110
110
 
111
111
  function test_revert_add_owners_with_zero_address() public {
@@ -116,7 +116,7 @@ contract MultiOwnableTest is BaseTest {
116
116
 
117
117
  vm.prank(users.creator);
118
118
  vm.expectRevert(MultiOwnable.OwnerCannotBeAddressZero.selector);
119
- coin.addOwners(newOwners);
119
+ coinV4.addOwners(newOwners);
120
120
  }
121
121
 
122
122
  function test_revert_add_owners_with_duplicate() public {
@@ -126,11 +126,11 @@ contract MultiOwnableTest is BaseTest {
126
126
  newOwners[1] = newOwner;
127
127
 
128
128
  vm.prank(users.creator);
129
- coin.addOwner(newOwner);
129
+ coinV4.addOwner(newOwner);
130
130
 
131
131
  vm.expectRevert(MultiOwnable.AlreadyOwner.selector);
132
132
  vm.prank(users.creator);
133
- coin.addOwners(newOwners);
133
+ coinV4.addOwners(newOwners);
134
134
  }
135
135
 
136
136
  function test_revert_init_with_zero_owners() public {
@@ -6,7 +6,7 @@ import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
6
6
  import {BaseTest} from "./utils/BaseTest.sol";
7
7
  import {CoinsDeployerBase} from "../src/deployment/CoinsDeployerBase.sol";
8
8
  import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
9
- import {ICoinV4} from "../src/interfaces/ICoinV4.sol";
9
+ import {ICoin} from "../src/interfaces/ICoin.sol";
10
10
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
11
11
  import {ISwapRouter} from "../src/interfaces/ISwapRouter.sol";
12
12
  import {IWETH} from "../src/interfaces/IWETH.sol";
@@ -21,7 +21,7 @@ import {HooksDeployment} from "../src/libs/HooksDeployment.sol";
21
21
  import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
22
22
  import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
23
23
  import {MultiOwnable} from "../src/utils/MultiOwnable.sol";
24
- import {CoinV4} from "../src/CoinV4.sol";
24
+ import {ContentCoin} from "../src/ContentCoin.sol";
25
25
  import {UniV4SwapHelper} from "../src/libs/UniV4SwapHelper.sol";
26
26
  import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol";
27
27
  import {IZoraV4CoinHook} from "../src/interfaces/IZoraV4CoinHook.sol";
@@ -43,13 +43,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
43
43
 
44
44
  factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
45
45
 
46
- ZoraFactoryImpl newImpl = new ZoraFactoryImpl(
47
- factoryProxy.coinImpl(),
48
- address(coinV4Impl),
49
- address(creatorCoinImpl),
50
- address(contentCoinHook),
51
- address(creatorCoinHook)
52
- );
46
+ ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(contentCoinHook), address(creatorCoinHook));
53
47
 
54
48
  vm.prank(factoryProxy.owner());
55
49
  factoryProxy.upgradeToAndCall(address(newImpl), "");
@@ -64,13 +58,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
64
58
 
65
59
  factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
66
60
 
67
- ZoraFactoryImpl newImpl = new ZoraFactoryImpl(
68
- factoryProxy.coinImpl(),
69
- address(coinV4Impl),
70
- address(creatorCoinImpl),
71
- address(contentCoinHook),
72
- address(creatorCoinHook)
73
- );
61
+ ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(contentCoinHook), address(creatorCoinHook));
74
62
 
75
63
  vm.prank(factoryProxy.owner());
76
64
  factoryProxy.upgradeToAndCall(address(newImpl), "");
@@ -88,19 +76,12 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
88
76
 
89
77
  factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
90
78
 
91
- ZoraFactoryImpl newImpl = new ZoraFactoryImpl(
92
- factoryProxy.coinImpl(),
93
- address(coinV4Impl),
94
- address(creatorCoinImpl),
95
- address(contentCoinHook),
96
- address(creatorCoinHook)
97
- );
79
+ ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(contentCoinHook), address(creatorCoinHook));
98
80
 
99
81
  vm.prank(factoryProxy.owner());
100
82
  factoryProxy.upgradeToAndCall(address(newImpl), "");
101
83
 
102
84
  ZoraFactoryImpl newImpl2 = new ZoraFactoryImpl(
103
- factoryProxy.coinImpl(),
104
85
  factoryProxy.coinV4Impl(),
105
86
  factoryProxy.creatorCoinImpl(),
106
87
  address(contentCoinHook),
@@ -166,16 +147,16 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
166
147
  );
167
148
 
168
149
  // do some swaps to test out
169
- _swapSomeCurrencyForCoin(ICoinV4(coinAddress), ZORA, uint128(IERC20(ZORA).balanceOf(trader)), trader);
150
+ _swapSomeCurrencyForCoin(ICoin(coinAddress), ZORA, uint128(IERC20(ZORA).balanceOf(trader)), trader);
170
151
 
171
152
  // do some swaps to test out
172
- _swapSomeCoinForCurrency(ICoinV4(coinAddress), ZORA, uint128(IERC20(coinAddress).balanceOf(trader)), trader);
153
+ _swapSomeCoinForCurrency(ICoin(coinAddress), ZORA, uint128(IERC20(coinAddress).balanceOf(trader)), trader);
173
154
  }
174
155
 
175
156
  address coinVersionLookup = 0x777777751622c0d3258f214F9DF38E35BF45baF3;
176
157
  address upgradeGate = 0xD88f6BdD765313CaFA5888C177c325E2C3AbF2D2;
177
158
 
178
- function _swapSomeCurrencyForCoinAndExpectRevert(ICoinV4 _coin, address currency, uint128 amountIn, address trader) internal {
159
+ function _swapSomeCurrencyForCoinAndExpectRevert(ICoin _coin, address currency, uint128 amountIn, address trader) internal {
179
160
  uint128 minAmountOut = uint128(0);
180
161
 
181
162
  (bytes memory commands, bytes[] memory inputs) = UniV4SwapHelper.buildExactInputSingleSwapCommand(
@@ -205,42 +186,42 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
205
186
 
206
187
  address contentCoin = 0x4E93A01c90f812284F71291a8d1415a904957156;
207
188
 
208
- address creatorCoin = ICoinV4(contentCoin).currency();
189
+ address creatorCoin = ICoin(contentCoin).currency();
209
190
 
210
191
  uint256 amountIn = IERC20(creatorCoin).balanceOf(trader);
211
192
 
212
193
  require(amountIn > 0, "no balance");
213
194
 
214
195
  // this swap should revert because the content coin is broken
215
- _swapSomeCurrencyForCoinAndExpectRevert(ICoinV4(contentCoin), creatorCoin, uint128(amountIn), trader);
196
+ _swapSomeCurrencyForCoinAndExpectRevert(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
216
197
 
217
198
  bytes memory creationCode = HooksDeployment.contentCoinCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
218
199
 
219
200
  (IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
220
201
 
221
202
  // etch new hook into the content coin, it shouldn't revert anymore when swapping
222
- vm.etch(address(ICoinV4(contentCoin).hooks()), address(newHook).code);
203
+ vm.etch(address(ICoin(contentCoin).hooks()), address(newHook).code);
223
204
 
224
- _swapSomeCurrencyForCoin(ICoinV4(contentCoin), creatorCoin, uint128(amountIn), trader);
205
+ _swapSomeCurrencyForCoin(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
225
206
  }
226
207
 
227
208
  function test_canUpgradeBrokenContentCoinAndSwap() public {
228
- vm.createSelectFork("base", 31835069);
209
+ vm.createSelectFork("base", 32613149);
229
210
 
230
211
  address trader = 0xf69fEc6d858c77e969509843852178bd24CAd2B6;
231
212
 
232
- address contentCoin = 0x4E93A01c90f812284F71291a8d1415a904957156;
213
+ address contentCoin = 0xB9799C839818bF50240CE683363D00c43a2E23b8;
233
214
 
234
- address creatorCoin = ICoinV4(contentCoin).currency();
215
+ address creatorCoin = ICoin(contentCoin).currency();
235
216
 
236
- address existingHook = 0xd3D133469ADC85e01A4887404D8AC12d630e9040;
237
-
238
- uint256 amountIn = IERC20(creatorCoin).balanceOf(trader);
217
+ uint256 amountIn = 0.000111 ether;
239
218
 
240
219
  bytes memory creationCode = HooksDeployment.contentCoinCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
241
220
 
242
221
  (IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
243
222
 
223
+ address existingHook = address(ICoin(contentCoin).hooks());
224
+
244
225
  address[] memory baseImpls = new address[](1);
245
226
  baseImpls[0] = existingHook;
246
227
 
@@ -248,10 +229,10 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
248
229
  IHooksUpgradeGate(upgradeGate).registerUpgradePath(baseImpls, address(newHook));
249
230
 
250
231
  vm.prank(MultiOwnable(contentCoin).owners()[0]);
251
- CoinV4(contentCoin).migrateLiquidity(address(newHook), "");
232
+ ContentCoin(contentCoin).migrateLiquidity(address(newHook), "");
252
233
 
253
234
  // do some swaps to test out
254
- _swapSomeCurrencyForCoin(ICoinV4(contentCoin), creatorCoin, uint128(amountIn), trader);
235
+ _swapSomeCurrencyForCoin(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
255
236
  }
256
237
 
257
238
  function getPositionInfo(
@@ -272,7 +253,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
272
253
  }
273
254
  }
274
255
 
275
- function getLiquidityForPoolCoin(ICoinV4 coin) internal view returns (uint128[] memory liquidityForPositions) {
256
+ function getLiquidityForPoolCoin(ICoin coin) internal view returns (uint128[] memory liquidityForPositions) {
276
257
  return getLiquidityForPositions(coin.getPoolKey(), IZoraV4CoinHook(address(coin.hooks())).getPoolCoin(coin.getPoolKey()).positions);
277
258
  }
278
259
 
@@ -281,7 +262,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
281
262
 
282
263
  address trader = 0xf69fEc6d858c77e969509843852178bd24CAd2B6;
283
264
 
284
- ICoinV4 creatorCoin = ICoinV4(0x2F03aB8fD97F5874bc3274C296Bb954Ae92EdA34);
265
+ ICoin creatorCoin = ICoin(0x2F03aB8fD97F5874bc3274C296Bb954Ae92EdA34);
285
266
 
286
267
  address zora = creatorCoin.currency();
287
268
 
@@ -305,7 +286,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
305
286
  uint160 beforePrice = PoolStateReader.getSqrtPriceX96(creatorCoin.getPoolKey(), poolManager);
306
287
 
307
288
  vm.prank(MultiOwnable(address(creatorCoin)).owners()[0]);
308
- CoinV4(address(creatorCoin)).migrateLiquidity(address(newHook), "");
289
+ ContentCoin(address(creatorCoin)).migrateLiquidity(address(newHook), "");
309
290
 
310
291
  // get liquidity of original positions after migration
311
292
  uint128[] memory liquidityOfPositionsAfterMigration = getLiquidityForPositions(beforeKey, beforePositions);