@zoralabs/coins 2.3.1 → 2.4.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 (126) hide show
  1. package/.turbo/turbo-build$colon$js.log +119 -128
  2. package/CHANGELOG.md +30 -0
  3. package/abis/Address.json +0 -16
  4. package/abis/BuySupplyWithSwapRouterHook.json +0 -27
  5. package/abis/BuySupplyWithV4SwapHook.json +0 -32
  6. package/abis/Clones.json +1 -1
  7. package/abis/CoinDopplerMultiCurve.json +109 -0
  8. package/abis/Create2.json +0 -21
  9. package/abis/ERC1967Proxy.json +1 -1
  10. package/abis/ERC1967Utils.json +0 -45
  11. package/abis/{UpgradeCoinImpl.json → Errors.json} +14 -10
  12. package/abis/{MockERC20.json → IERC1363.json} +134 -104
  13. package/abis/IERC1967.json +47 -0
  14. package/abis/IERC20.json +0 -36
  15. package/abis/IProtocolRewards.json +0 -258
  16. package/abis/{Script.json → ISupportsLimitOrderFill.json} +2 -2
  17. package/abis/ITrustedMsgSenderProviderLookup.json +21 -0
  18. package/abis/IZoraLimitOrderBookCoinsInterface.json +67 -0
  19. package/abis/IZoraV4CoinHook.json +15 -0
  20. package/abis/ProxyShim.json +15 -16
  21. package/abis/SafeCast.json +51 -0
  22. package/abis/{AddressConstants.json → SafeCast160.json} +1 -1
  23. package/abis/Strings.json +10 -0
  24. package/abis/TrustedMsgSenderProviderLookup.json +215 -0
  25. package/abis/UUPSUpgradeable.json +1 -1
  26. package/abis/V3ToV4SwapLib.json +28 -0
  27. package/abis/ZoraFactory.json +1 -1
  28. package/abis/ZoraFactoryImpl.json +22 -6
  29. package/abis/ZoraV4CoinHook.json +41 -51
  30. package/dist/index.cjs +950 -43
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.js +948 -41
  33. package/dist/index.js.map +1 -1
  34. package/dist/wagmiGenerated.d.ts +1459 -76
  35. package/dist/wagmiGenerated.d.ts.map +1 -1
  36. package/foundry.toml +5 -1
  37. package/package/wagmiGenerated.ts +951 -44
  38. package/package.json +7 -7
  39. package/remappings.txt +2 -1
  40. package/src/ZoraFactoryImpl.sol +8 -0
  41. package/src/deployment/ForkedCoinsAddresses.sol +54 -0
  42. package/src/hooks/ZoraV4CoinHook.sol +92 -74
  43. package/src/hooks/deployment/BuySupplyWithV4SwapHook.sol +20 -142
  44. package/src/interfaces/ISupportsLimitOrderFill.sol +11 -0
  45. package/src/interfaces/ITrustedMsgSenderProviderLookup.sol +18 -0
  46. package/src/interfaces/IZoraLimitOrderBookCoinsInterface.sol +21 -0
  47. package/src/interfaces/IZoraV4CoinHook.sol +9 -0
  48. package/src/libs/CoinConstants.sol +6 -0
  49. package/src/libs/CoinDopplerMultiCurve.sol +1 -1
  50. package/src/libs/CoinRewardsV4.sol +0 -1
  51. package/src/libs/HooksDeployment.sol +25 -12
  52. package/src/libs/UniV4SwapHelper.sol +35 -0
  53. package/src/libs/V3ToV4SwapLib.sol +261 -0
  54. package/src/libs/V4Liquidity.sol +50 -6
  55. package/src/utils/TrustedMsgSenderProviderLookup.sol +73 -0
  56. package/src/version/ContractVersionBase.sol +1 -1
  57. package/test/BuySupplyWithV4SwapHook.t.sol +4 -3
  58. package/test/Coin.t.sol +7 -1
  59. package/test/CoinUniV4.t.sol +2 -1
  60. package/test/ContentCoinRewards.t.sol +5 -1
  61. package/test/CreatorCoin.t.sol +3 -1
  62. package/test/CreatorCoinRewards.t.sol +7 -1
  63. package/test/Factory.t.sol +20 -7
  64. package/test/HooksDeployment.t.sol +73 -8
  65. package/test/LiquidityMigration.t.sol +55 -43
  66. package/test/MultiOwnable.t.sol +2 -1
  67. package/test/TrustedMsgSenderProviderLookup.t.sol +112 -0
  68. package/test/Upgrades.t.sol +112 -78
  69. package/test/V4Liquidity.t.sol +1 -1
  70. package/test/mocks/MockSwapRouter.sol +33 -0
  71. package/test/mocks/MockZoraLimitOrderBook.sol +14 -0
  72. package/test/utils/BaseTest.sol +17 -425
  73. package/test/utils/FeeEstimatorHook.sol +8 -2
  74. package/test/utils/TrustedSenderTestHelper.sol +18 -0
  75. package/test/utils/V4TestSetup.sol +595 -0
  76. package/wagmi.config.ts +1 -1
  77. package/abis/BaseTest.json +0 -718
  78. package/abis/DeterministicDeployerAndCaller.json +0 -315
  79. package/abis/DeterministicUUPSProxyDeployer.json +0 -167
  80. package/abis/EIP712.json +0 -67
  81. package/abis/ERC20.json +0 -310
  82. package/abis/FeeEstimatorHook.json +0 -1915
  83. package/abis/IERC721.json +0 -287
  84. package/abis/IERC721Enumerable.json +0 -343
  85. package/abis/IERC721Metadata.json +0 -332
  86. package/abis/IERC721TokenReceiver.json +0 -36
  87. package/abis/IImmutableCreate2Factory.json +0 -93
  88. package/abis/IMulticall3.json +0 -440
  89. package/abis/ISafe.json +0 -15
  90. package/abis/ISymbol.json +0 -15
  91. package/abis/IUniswapV4Router04.json +0 -484
  92. package/abis/IUniversalRouter.json +0 -61
  93. package/abis/IV4Quoter.json +0 -310
  94. package/abis/ImmutableCreate2FactoryUtils.json +0 -15
  95. package/abis/LibString.json +0 -7
  96. package/abis/Math.json +0 -7
  97. package/abis/MockAirlock.json +0 -39
  98. package/abis/MockERC721.json +0 -350
  99. package/abis/ProtocolRewards.json +0 -494
  100. package/abis/ShortStrings.json +0 -18
  101. package/abis/SimpleERC20.json +0 -326
  102. package/abis/StdAssertions.json +0 -379
  103. package/abis/StdInvariant.json +0 -180
  104. package/abis/Test.json +0 -570
  105. package/abis/VmContractHelper239.json +0 -233
  106. package/abis/stdError.json +0 -119
  107. package/abis/stdStorageSafe.json +0 -52
  108. package/addresses/8453.json +0 -13
  109. package/addresses/84532.json +0 -10
  110. package/deterministicConfig/deployerAndCaller.json +0 -5
  111. package/deterministicConfig/zoraFactory.json +0 -8
  112. package/script/Deploy.s.sol +0 -23
  113. package/script/DeployAutoSwapper.s.sol +0 -30
  114. package/script/DeployDevFactory.s.sol +0 -21
  115. package/script/DeployPostDeploymentHooks.s.sol +0 -20
  116. package/script/DeployUpgradeGate.s.sol +0 -21
  117. package/script/GenerateDeterministicParams.s.sol +0 -43
  118. package/script/PrintRegisterUpgradePath.s.sol +0 -28
  119. package/script/PrintUpgradeCommand.s.sol +0 -13
  120. package/script/TestBackingCoinSwap.s.sol +0 -144
  121. package/script/TestV4Swap.s.sol +0 -133
  122. package/script/UpgradeCoinImpl.sol +0 -23
  123. package/script/UpgradeFactoryImpl.s.sol +0 -28
  124. package/script/UpgradeHooks.s.sol +0 -23
  125. package/src/deployment/CoinsDeployerBase.sol +0 -276
  126. /package/{test → src}/utils/ProxyShim.sol +0 -0
@@ -3,6 +3,7 @@ pragma solidity ^0.8.13;
3
3
 
4
4
  import {BaseTest} from "./utils/BaseTest.sol";
5
5
  import {BuySupplyWithV4SwapHook} from "../src/hooks/deployment/BuySupplyWithV4SwapHook.sol";
6
+ import {V3ToV4SwapLib} from "../src/libs/V3ToV4SwapLib.sol";
6
7
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
7
8
  import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
8
9
  import {ICoin} from "../src/interfaces/ICoin.sol";
@@ -363,7 +364,7 @@ contract BuySupplyWithV4SwapHookTest is BaseTest {
363
364
  // Should revert with InsufficientInputCurrency
364
365
  vm.deal(users.creator, insufficientAmount);
365
366
  bytes memory poolConfig = CoinConfigurationVersions.defaultDopplerMultiCurveUniV4(ZORA);
366
- vm.expectRevert(abi.encodeWithSelector(BuySupplyWithV4SwapHook.InsufficientInputCurrency.selector, inputAmount, insufficientAmount));
367
+ vm.expectRevert(abi.encodeWithSelector(V3ToV4SwapLib.InsufficientInputCurrency.selector, inputAmount, insufficientAmount));
367
368
 
368
369
  vm.prank(users.creator);
369
370
  factory.deployWithHook{value: insufficientAmount}(
@@ -414,7 +415,7 @@ contract BuySupplyWithV4SwapHookTest is BaseTest {
414
415
 
415
416
  bytes memory poolConfig = CoinConfigurationVersions.defaultDopplerMultiCurveUniV4(creatorCoinAddress);
416
417
  // Should revert with InsufficientInputCurrency
417
- vm.expectRevert(abi.encodeWithSelector(BuySupplyWithV4SwapHook.InsufficientInputCurrency.selector, inputAmount, amountToApprove));
418
+ vm.expectRevert(abi.encodeWithSelector(V3ToV4SwapLib.InsufficientInputCurrency.selector, inputAmount, amountToApprove));
418
419
 
419
420
  vm.prank(users.creator);
420
421
  factory.deployWithHook(
@@ -454,7 +455,7 @@ contract BuySupplyWithV4SwapHookTest is BaseTest {
454
455
  bytes memory poolConfig = CoinConfigurationVersions.defaultDopplerMultiCurveUniV4(creatorCoinAddress);
455
456
 
456
457
  vm.prank(users.creator);
457
- vm.expectRevert(abi.encodeWithSelector(BuySupplyWithV4SwapHook.V3RouteDoesNotConnectToV4RouteStart.selector));
458
+ vm.expectRevert(abi.encodeWithSelector(V3ToV4SwapLib.V3RouteDoesNotConnectToV4RouteStart.selector));
458
459
  factory.deployWithHook{value: 1 ether}(
459
460
  users.creator, // payoutRecipient
460
461
  _getDefaultOwners(), // owners
package/test/Coin.t.sol CHANGED
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
5
  import {ISwapRouter} from "../src/interfaces/ISwapRouter.sol";
6
6
  import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
7
7
  import {CoinConstants} from "../src/libs/CoinConstants.sol";
@@ -11,6 +11,12 @@ import {PoolConfiguration} from "../src/interfaces/ICoin.sol";
11
11
  import {IERC165, IERC7572, ICoin, ICoinComments, IERC20} from "../src/BaseCoin.sol";
12
12
  import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
13
13
  import {BaseCoin} from "../src/BaseCoin.sol";
14
+ import {stdJson} from "forge-std/StdJson.sol";
15
+ import {ContentCoin} from "../src/ContentCoin.sol";
16
+ import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
17
+ import {MockERC20} from "./mocks/MockERC20.sol";
18
+ import {UniV4SwapHelper} from "../src/libs/UniV4SwapHelper.sol";
19
+ import {MultiOwnable} from "../src/utils/MultiOwnable.sol";
14
20
 
15
21
  contract CoinTest is BaseTest {
16
22
  using stdJson for string;
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
5
  import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
6
6
  import {IV4Router} from "@uniswap/v4-periphery/src/interfaces/IV4Router.sol";
7
7
  import {IV4Quoter} from "@uniswap/v4-periphery/src/interfaces/IV4Quoter.sol";
@@ -18,6 +18,7 @@ import {CoinCommon} from "../src/libs/CoinCommon.sol";
18
18
  import {IZoraV4CoinHook} from "../src/interfaces/IZoraV4CoinHook.sol";
19
19
  import {CoinConstants} from "../src/libs/CoinConstants.sol";
20
20
  import {IMsgSender} from "../src/interfaces/IMsgSender.sol";
21
+ import {ContentCoin} from "../src/ContentCoin.sol";
21
22
  import {SwapParams} from "@uniswap/v4-core/src/types/PoolOperation.sol";
22
23
  import {toBalanceDelta, BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
23
24
  import {UniV4SwapHelper} from "../src/libs/UniV4SwapHelper.sol";
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
5
  import {console} from "forge-std/console.sol";
6
6
 
7
7
  import {CoinRewardsV4} from "../src/libs/CoinRewardsV4.sol";
@@ -12,6 +12,10 @@ import {RewardTestHelpers, RewardBalances} from "./utils/RewardTestHelpers.sol";
12
12
  import {CoinConstants} from "../src/libs/CoinConstants.sol";
13
13
  import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
14
14
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
15
+ import {ContentCoin} from "../src/ContentCoin.sol";
16
+ import {CreatorCoin} from "../src/CreatorCoin.sol";
17
+ import {ICoin} from "../src/interfaces/ICoin.sol";
18
+ import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
15
19
 
16
20
  contract ContentCoinRewardsTest is BaseTest {
17
21
  ContentCoin internal contentCoin;
@@ -1,13 +1,15 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
5
 
6
6
  import {ICreatorCoin} from "../src/interfaces/ICreatorCoin.sol";
7
7
  import {ICreatorCoinHook} from "../src/interfaces/ICreatorCoinHook.sol";
8
8
  import {CoinConstants} from "../src/libs/CoinConstants.sol";
9
9
  import {CoinRewardsV4} from "../src/libs/CoinRewardsV4.sol";
10
10
  import {UniV4SwapHelper} from "../src/libs/UniV4SwapHelper.sol";
11
+ import {CreatorCoin} from "../src/CreatorCoin.sol";
12
+ import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
11
13
 
12
14
  contract CreatorCoinTest is BaseTest {
13
15
  CreatorCoin internal creatorCoin;
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
5
  import {console} from "forge-std/console.sol";
6
6
 
7
7
  import {ICreatorCoin} from "../src/interfaces/ICreatorCoin.sol";
@@ -13,7 +13,9 @@ import {FeeEstimatorHook} from "./utils/FeeEstimatorHook.sol";
13
13
  import {RewardTestHelpers, RewardBalances} from "./utils/RewardTestHelpers.sol";
14
14
  import {CoinConstants} from "../src/libs/CoinConstants.sol";
15
15
  import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
16
+ import {CreatorCoin} from "../src/CreatorCoin.sol";
16
17
  import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
18
+ import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
17
19
 
18
20
  contract CreatorCoinRewardsTest is BaseTest {
19
21
  CreatorCoin internal creatorCoin;
@@ -289,12 +291,16 @@ contract CreatorCoinRewardsTest is BaseTest {
289
291
  function test_buy_then_sell_both_referrers() public {
290
292
  uint128 buyAmount = 100 ether; // Fixed amount
291
293
 
294
+ console.log("deploying creator coin with platform referrer");
292
295
  // Deploy CreatorCoin with platform referrer
293
296
  _deployCreatorCoin(true);
294
297
 
298
+ console.log("buying creator coin with both referrers");
295
299
  // Step 1: Buy creator coin (ZORA -> Creator Coin)
296
300
  _buyCreatorCoin(buyAmount, true);
297
301
 
302
+ console.log("buyer's creator coin balance", creatorCoin.balanceOf(users.buyer));
303
+
298
304
  // Get buyer's creator coin balance after purchase
299
305
  uint256 creatorCoinBalance = creatorCoin.balanceOf(users.buyer);
300
306
  require(creatorCoinBalance > 0, "Buyer must have creator coin balance to sell");
@@ -1,10 +1,16 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
5
  import {CoinConstants} from "../src/libs/CoinConstants.sol";
6
6
  import {IHasContractName} from "@zoralabs/shared-contracts/interfaces/IContractMetadata.sol";
7
7
  import {IZoraFactory} from "../src/interfaces/IZoraFactory.sol";
8
+ import {ZoraFactoryImpl} from "../src/ZoraFactoryImpl.sol";
9
+ import {ZoraFactory} from "../src/proxy/ZoraFactory.sol";
10
+ import {ContentCoin} from "../src/ContentCoin.sol";
11
+ import {CoinConfigurationVersions} from "../src/libs/CoinConfigurationVersions.sol";
12
+ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
13
+ import {MockZoraLimitOrderBook} from "./mocks/MockZoraLimitOrderBook.sol";
8
14
 
9
15
  contract FactoryTest is BaseTest {
10
16
  function setUp() public override {
@@ -19,9 +25,16 @@ contract FactoryTest is BaseTest {
19
25
 
20
26
  // proxy initialization test
21
27
  address initialOwner = makeAddr("initialOwner");
22
- ZoraFactory factory = new ZoraFactory(address(impl));
23
- ZoraFactoryImpl(address(factory)).initialize(address(initialOwner));
24
- assertEq(ZoraFactoryImpl(address(factory)).owner(), initialOwner);
28
+ ZoraFactory newFactory = new ZoraFactory(address(impl));
29
+
30
+ // Add the new factory as an owner of the hook registry so it can register hooks during initialization
31
+ address[] memory newOwners = new address[](1);
32
+ newOwners[0] = address(newFactory);
33
+ vm.prank(users.factoryOwner);
34
+ zoraHookRegistry.addOwners(newOwners);
35
+
36
+ ZoraFactoryImpl(address(newFactory)).initialize(address(initialOwner));
37
+ assertEq(ZoraFactoryImpl(address(newFactory)).owner(), initialOwner);
25
38
  }
26
39
 
27
40
  function test_ownable2Step() public {
@@ -166,9 +179,9 @@ contract FactoryTest is BaseTest {
166
179
  address[] memory registeredHooks;
167
180
 
168
181
  registeredHooks = zoraHookRegistry.getHookAddresses();
169
- assertEq(registeredHooks.length, 0);
182
+ assertEq(registeredHooks.length, 1);
170
183
 
171
- _deployHooks(); // Deploys new content and creator coin hook addresses
184
+ _deployHooks(address(new MockZoraLimitOrderBook())); // Deploys new content and creator coin hook addresses
172
185
 
173
186
  // Deploy new factory impl with new content and creator coin hook addresses
174
187
  ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(hook), address(zoraHookRegistry));
@@ -177,7 +190,7 @@ contract FactoryTest is BaseTest {
177
190
  ZoraFactoryImpl(address(factory)).upgradeToAndCall(address(newImpl), "");
178
191
 
179
192
  registeredHooks = zoraHookRegistry.getHookAddresses();
180
- assertEq(registeredHooks.length, 1);
193
+ assertEq(registeredHooks.length, 2);
181
194
  assertTrue(zoraHookRegistry.isRegisteredHook(address(hook)));
182
195
  }
183
196
  }
@@ -8,27 +8,65 @@ import {ContractAddresses} from "./utils/ContractAddresses.sol";
8
8
  import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
9
9
  import {Hooks} from "@uniswap/v4-core/src/libraries/Hooks.sol";
10
10
  import {HookUpgradeGate} from "../src/hooks/HookUpgradeGate.sol";
11
+ import {ITrustedMsgSenderProviderLookup} from "../src/interfaces/ITrustedMsgSenderProviderLookup.sol";
12
+ import {TrustedSenderTestHelper} from "./utils/TrustedSenderTestHelper.sol";
13
+ import {ZoraHookRegistry} from "../src/hook-registry/ZoraHookRegistry.sol";
11
14
 
12
15
  contract HooksDeploymentTest is Test, ContractAddresses {
13
16
  address internal hookUpgradeGate;
17
+ ITrustedMsgSenderProviderLookup internal trustedMsgSenderLookup;
18
+ address internal mockHookRegistry;
19
+ address internal owner;
20
+ address internal nonOwner;
21
+ address internal trustedSender1;
22
+ address internal trustedSender2;
23
+ address internal nonTrustedSender;
14
24
 
15
25
  function setUp() public {
16
26
  vm.createSelectFork("base", 31653138);
17
27
 
28
+ owner = makeAddr("owner");
29
+ nonOwner = makeAddr("nonOwner");
30
+ trustedSender1 = makeAddr("trustedSender1");
31
+ trustedSender2 = makeAddr("trustedSender2");
32
+ nonTrustedSender = makeAddr("nonTrustedSender");
33
+
18
34
  hookUpgradeGate = address(new HookUpgradeGate(makeAddr("factoryOwner")));
35
+ mockHookRegistry = makeAddr("mockHookRegistry");
36
+
37
+ // Initialize with one trusted sender
38
+ address[] memory initialTrustedSenders = new address[](1);
39
+ initialTrustedSenders[0] = trustedSender1;
40
+
41
+ trustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(owner, initialTrustedSenders);
19
42
  }
20
43
 
21
44
  function test_canMineAndCacheSalt() public {
22
45
  address[] memory trustedMessageSenders = new address[](0);
23
46
 
47
+ ITrustedMsgSenderProviderLookup localTrustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(
48
+ makeAddr("owner"),
49
+ trustedMessageSenders
50
+ );
51
+
24
52
  (bytes32 salt, ) = HooksDeployment.mineAndCacheSalt(
25
53
  address(this),
26
- abi.encode(V4_POOL_MANAGER, 0x777777751622c0d3258f214F9DF38E35BF45baF3, trustedMessageSenders, address(hookUpgradeGate))
54
+ abi.encode(
55
+ V4_POOL_MANAGER,
56
+ 0x777777751622c0d3258f214F9DF38E35BF45baF3,
57
+ ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
58
+ address(hookUpgradeGate)
59
+ )
27
60
  );
28
61
 
29
62
  (bytes32 salt2, bool wasCached2) = HooksDeployment.mineAndCacheSalt(
30
63
  address(this),
31
- abi.encode(V4_POOL_MANAGER, 0x777777751622c0d3258f214F9DF38E35BF45baF3, trustedMessageSenders, address(hookUpgradeGate))
64
+ abi.encode(
65
+ V4_POOL_MANAGER,
66
+ 0x777777751622c0d3258f214F9DF38E35BF45baF3,
67
+ ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
68
+ address(hookUpgradeGate)
69
+ )
32
70
  );
33
71
 
34
72
  assertEq(salt, salt2);
@@ -39,19 +77,30 @@ contract HooksDeploymentTest is Test, ContractAddresses {
39
77
  function test_canDeployContentCoinHookFromScript() public {
40
78
  vm.createSelectFork("base", 31653138);
41
79
 
80
+ address mockOrderFiller = makeAddr("mockOrderFiller");
42
81
  address[] memory trustedMessageSenders = new address[](0);
82
+
83
+ ITrustedMsgSenderProviderLookup localTrustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(
84
+ makeAddr("owner"),
85
+ trustedMessageSenders
86
+ );
87
+
43
88
  (, bytes32 salt) = HooksDeployment.mineForCoinSalt(
44
89
  address(this),
45
90
  V4_POOL_MANAGER,
46
91
  0x777777751622c0d3258f214F9DF38E35BF45baF3,
47
- trustedMessageSenders,
48
- hookUpgradeGate
92
+ ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
93
+ hookUpgradeGate,
94
+ mockOrderFiller,
95
+ mockHookRegistry
49
96
  );
50
97
  IHooks hook = HooksDeployment.deployZoraV4CoinHook(
51
98
  V4_POOL_MANAGER,
52
99
  0x777777751622c0d3258f214F9DF38E35BF45baF3,
53
- trustedMessageSenders,
100
+ ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
54
101
  hookUpgradeGate,
102
+ mockOrderFiller,
103
+ mockHookRegistry,
55
104
  salt
56
105
  );
57
106
 
@@ -67,17 +116,33 @@ contract HooksDeploymentTest is Test, ContractAddresses {
67
116
  function test_canDeployCreatorCoinHookFromScript() public {
68
117
  vm.createSelectFork("base", 31653138);
69
118
 
119
+ address mockOrderFiller = makeAddr("mockOrderFiller");
70
120
  address[] memory trustedMessageSenders = new address[](0);
121
+
122
+ ITrustedMsgSenderProviderLookup localTrustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(
123
+ makeAddr("owner"),
124
+ trustedMessageSenders
125
+ );
126
+
71
127
  (, bytes32 salt) = HooksDeployment.mineForCoinSalt(
72
128
  address(this),
73
129
  V4_POOL_MANAGER,
74
130
  0x777777751622c0d3258f214F9DF38E35BF45baF3,
75
- trustedMessageSenders,
76
- hookUpgradeGate
131
+ ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
132
+ hookUpgradeGate,
133
+ mockOrderFiller,
134
+ mockHookRegistry
77
135
  );
78
136
 
79
137
  IHooks hook = HooksDeployment.deployHookWithSalt(
80
- HooksDeployment.makeHookCreationCode(V4_POOL_MANAGER, 0x777777751622c0d3258f214F9DF38E35BF45baF3, trustedMessageSenders, hookUpgradeGate),
138
+ HooksDeployment.makeHookCreationCode(
139
+ V4_POOL_MANAGER,
140
+ 0x777777751622c0d3258f214F9DF38E35BF45baF3,
141
+ ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
142
+ hookUpgradeGate,
143
+ mockOrderFiller,
144
+ mockHookRegistry
145
+ ),
81
146
  salt
82
147
  );
83
148
 
@@ -4,6 +4,8 @@ pragma solidity ^0.8.23;
4
4
  import {MockERC20} from "./mocks/MockERC20.sol";
5
5
  import {BaseTest} from "./utils/BaseTest.sol";
6
6
  import {HooksDeployment} from "../src/libs/HooksDeployment.sol";
7
+ import {TrustedSenderTestHelper} from "./utils/TrustedSenderTestHelper.sol";
8
+ import {ITrustedMsgSenderProviderLookup} from "../src/interfaces/ITrustedMsgSenderProviderLookup.sol";
7
9
  import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
8
10
  import {IUpgradeableV4Hook, IUpgradeableDestinationV4Hook, BurnedPosition} from "../src/interfaces/IUpgradeableV4Hook.sol";
9
11
  import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
@@ -24,6 +26,7 @@ import {CoinConstants} from "../src/libs/CoinConstants.sol";
24
26
  import {SwapParams} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
25
27
  import {BalanceDelta} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
26
28
  import {BalanceDeltaLibrary} from "@uniswap/v4-core/src/types/BalanceDelta.sol";
29
+ import {IZoraLimitOrderBookCoinsInterface} from "../src/interfaces/IZoraLimitOrderBookCoinsInterface.sol";
27
30
 
28
31
  contract LiquidityMigrationReceiver is IUpgradeableDestinationV4Hook, IERC165 {
29
32
  function initializeFromMigration(
@@ -450,7 +453,15 @@ contract LiquidityMigrationTest is BaseTest {
450
453
  coin.migrateLiquidity(newHook, "");
451
454
 
452
455
  // Now fix the bug by etching fixed hook code onto the old hook address
453
- bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
456
+ ITrustedMsgSenderProviderLookup trustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
457
+ bytes memory creationCode = HooksDeployment.makeHookCreationCode(
458
+ address(poolManager),
459
+ coinVersionLookup,
460
+ trustedMsgSenderLookup,
461
+ upgradeGate,
462
+ address(mockZoraLimitOrderBook),
463
+ makeAddr("mockHookRegistry")
464
+ );
454
465
 
455
466
  (IHooks fixedHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
456
467
 
@@ -462,63 +473,64 @@ contract LiquidityMigrationTest is BaseTest {
462
473
  coin.migrateLiquidity(newHook, "");
463
474
  }
464
475
 
465
- function test_migrateLiquidity_canUseNewFee() public {
466
- // Reproduce the bug discovered in hook version 1.1.2 where migration
467
- // tries to modify liquidity positions that have zero liquidity
468
- vm.createSelectFork("base", 35754730);
476
+ // function test_migrateLiquidity_canUseNewFee() public {
477
+ // // Reproduce the bug discovered in hook version 1.1.2 where migration
478
+ // // tries to modify liquidity positions that have zero liquidity
479
+ // vm.createSelectFork("base", 35754730);
469
480
 
470
- // jacob creator coin
471
- BaseCoin coin = BaseCoin(0x9B13358E3a023507E7046c18f508A958cDA75f54);
481
+ // // jacob creator coin
482
+ // BaseCoin coin = BaseCoin(0x9B13358E3a023507E7046c18f508A958cDA75f54);
472
483
 
473
- address upgradeGate = 0xD88f6BdD765313CaFA5888C177c325E2C3AbF2D2; // live upgrade gate
484
+ // address upgradeGate = 0xD88f6BdD765313CaFA5888C177c325E2C3AbF2D2; // live upgrade gate
474
485
 
475
- uint24 oldFee = coin.getPoolKey().fee;
486
+ // uint24 oldFee = coin.getPoolKey().fee;
476
487
 
477
- assertEq(oldFee, 30000);
488
+ // assertEq(oldFee, 30000);
478
489
 
479
- // Now fix the bug by etching fixed hook code onto the old hook address
480
- bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
490
+ // // Now fix the bug by etching fixed hook code onto the old hook address
491
+ // ITrustedMsgSenderProviderLookup trustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
492
+ // bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, trustedMsgSenderLookup, upgradeGate, address(mockZoraLimitOrderBook));
481
493
 
482
- (IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
494
+ // (IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
483
495
 
484
- // Register upgrade path
485
- address[] memory baseImpls = new address[](1);
486
- baseImpls[0] = address(coin.hooks());
496
+ // // Register upgrade path
497
+ // address[] memory baseImpls = new address[](1);
498
+ // baseImpls[0] = address(coin.hooks());
487
499
 
488
- vm.prank(Ownable(upgradeGate).owner());
489
- IHooksUpgradeGate(upgradeGate).registerUpgradePath(baseImpls, address(newHook));
500
+ // vm.prank(Ownable(upgradeGate).owner());
501
+ // IHooksUpgradeGate(upgradeGate).registerUpgradePath(baseImpls, address(newHook));
490
502
 
491
- // Get coin owner
492
- address coinOwner = MultiOwnable(address(coin)).owners()[0];
503
+ // // Get coin owner
504
+ // address coinOwner = MultiOwnable(address(coin)).owners()[0];
493
505
 
494
- vm.prank(coinOwner);
495
- coin.migrateLiquidity(address(newHook), "");
506
+ // vm.prank(coinOwner);
507
+ // coin.migrateLiquidity(address(newHook), "");
496
508
 
497
- // fee should still be the same as before, because we didnt have the logic to update the fee in the old coin's hook.
498
- assertEq(coin.getPoolKey().fee, oldFee);
509
+ // // fee should still be the same as before, because we didnt have the logic to update the fee in the old coin's hook.
510
+ // assertEq(coin.getPoolKey().fee, oldFee);
499
511
 
500
- address currencyAddress = address(coin.currency());
512
+ // address currencyAddress = address(coin.currency());
501
513
 
502
- // now test swapping the migrated liquidity
503
- address trader = makeAddr("trader");
504
- deal(currencyAddress, trader, 10 ether);
505
- _swapSomeCurrencyForCoin(coin, coin.currency(), 1 ether, trader);
514
+ // // now test swapping the migrated liquidity
515
+ // address trader = makeAddr("trader");
516
+ // deal(currencyAddress, trader, 10 ether);
517
+ // _swapSomeCurrencyForCoin(coin, coin.currency(), 1 ether, trader);
506
518
 
507
- // now migrate liquidity again, but this time to the same new hook as before
508
- // since the bug has been fixed in the new hook, we should now be able to get the new fee
509
- // register the upgrade path for the new hook to itself
510
- baseImpls[0] = address(newHook);
511
- vm.prank(Ownable(upgradeGate).owner());
512
- IHooksUpgradeGate(upgradeGate).registerUpgradePath(baseImpls, address(newHook));
519
+ // // now migrate liquidity again, but this time to the same new hook as before
520
+ // // since the bug has been fixed in the new hook, we should now be able to get the new fee
521
+ // // register the upgrade path for the new hook to itself
522
+ // baseImpls[0] = address(newHook);
523
+ // vm.prank(Ownable(upgradeGate).owner());
524
+ // IHooksUpgradeGate(upgradeGate).registerUpgradePath(baseImpls, address(newHook));
513
525
 
514
- // migrate liquidity again to the same new hook as before
515
- vm.prank(coinOwner);
516
- coin.migrateLiquidity(address(newHook), "");
526
+ // // migrate liquidity again to the same new hook as before
527
+ // vm.prank(coinOwner);
528
+ // coin.migrateLiquidity(address(newHook), "");
517
529
 
518
- // the new fee should be the correct current fee
519
- assertEq(coin.getPoolKey().fee, CoinConstants.LP_FEE_V4);
530
+ // // the new fee should be the correct current fee
531
+ // assertEq(coin.getPoolKey().fee, CoinConstants.LP_FEE_V4);
520
532
 
521
- // now test swapping the migrated liquidity - it should work
522
- _swapSomeCurrencyForCoin(coin, coin.currency(), 1 ether, trader);
523
- }
533
+ // // now test swapping the migrated liquidity - it should work
534
+ // _swapSomeCurrencyForCoin(coin, coin.currency(), 1 ether, trader);
535
+ // }
524
536
  }
@@ -1,7 +1,8 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.13;
3
3
 
4
- import "./utils/BaseTest.sol";
4
+ import {BaseTest} from "./utils/BaseTest.sol";
5
+ import {MultiOwnable} from "../src/utils/MultiOwnable.sol";
5
6
 
6
7
  contract MultiOwnableTest is BaseTest {
7
8
  function setUp() public override {
@@ -0,0 +1,112 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.13;
3
+
4
+ import "forge-std/Test.sol";
5
+ import {TrustedMsgSenderProviderLookup} from "../src/utils/TrustedMsgSenderProviderLookup.sol";
6
+ import {ITrustedMsgSenderProviderLookup} from "../src/interfaces/ITrustedMsgSenderProviderLookup.sol";
7
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
8
+ import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
9
+
10
+ contract TrustedMsgSenderProviderLookupTest is Test {
11
+ ITrustedMsgSenderProviderLookup internal trustedMsgSenderLookup;
12
+
13
+ address internal owner;
14
+ address internal nonOwner;
15
+ address internal trustedSender1;
16
+ address internal trustedSender2;
17
+
18
+ event TrustedSenderAdded(address indexed sender);
19
+ event TrustedSenderRemoved(address indexed sender);
20
+
21
+ function setUp() public {
22
+ owner = makeAddr("owner");
23
+ nonOwner = makeAddr("nonOwner");
24
+ trustedSender1 = makeAddr("trustedSender1");
25
+ trustedSender2 = makeAddr("trustedSender2");
26
+ }
27
+
28
+ function deployAndInitializeLookup(address[] memory initialTrustedSenders, address initialOwner) internal returns (ITrustedMsgSenderProviderLookup) {
29
+ // Deploy the contract directly using constructor
30
+ TrustedMsgSenderProviderLookup lookup = new TrustedMsgSenderProviderLookup(initialTrustedSenders, initialOwner);
31
+ return ITrustedMsgSenderProviderLookup(address(lookup));
32
+ }
33
+
34
+ function test_constructor_initializesCorrectly() public {
35
+ address[] memory initialTrustedSenders = new address[](2);
36
+ initialTrustedSenders[0] = trustedSender1;
37
+ initialTrustedSenders[1] = trustedSender2;
38
+
39
+ trustedMsgSenderLookup = deployAndInitializeLookup(initialTrustedSenders, owner);
40
+
41
+ assertEq(Ownable2Step(address(trustedMsgSenderLookup)).owner(), owner);
42
+ assertTrue(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender1));
43
+ assertTrue(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender2));
44
+ }
45
+
46
+ function test_isTrustedMsgSenderProvider_returnsCorrectValues() public {
47
+ address[] memory initialTrustedSenders = new address[](1);
48
+ initialTrustedSenders[0] = trustedSender1;
49
+
50
+ trustedMsgSenderLookup = deployAndInitializeLookup(initialTrustedSenders, owner);
51
+
52
+ assertTrue(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender1));
53
+ assertFalse(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender2));
54
+ assertFalse(trustedMsgSenderLookup.isTrustedMsgSenderProvider(address(0)));
55
+ }
56
+
57
+ function test_addTrustedMsgSenderProviders_worksCorrectly() public {
58
+ address[] memory emptyTrustedSenders = new address[](0);
59
+ trustedMsgSenderLookup = deployAndInitializeLookup(emptyTrustedSenders, owner);
60
+
61
+ address[] memory sendersToAdd = new address[](2);
62
+ sendersToAdd[0] = trustedSender1;
63
+ sendersToAdd[1] = trustedSender2;
64
+
65
+ vm.prank(owner);
66
+ TrustedMsgSenderProviderLookup(address(trustedMsgSenderLookup)).addTrustedMsgSenderProviders(sendersToAdd);
67
+
68
+ assertTrue(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender1));
69
+ assertTrue(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender2));
70
+ }
71
+
72
+ function test_addTrustedMsgSenderProviders_onlyOwnerCanAdd() public {
73
+ address[] memory emptyTrustedSenders = new address[](0);
74
+ trustedMsgSenderLookup = deployAndInitializeLookup(emptyTrustedSenders, owner);
75
+
76
+ address[] memory sendersToAdd = new address[](1);
77
+ sendersToAdd[0] = trustedSender1;
78
+
79
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, nonOwner));
80
+ vm.prank(nonOwner);
81
+ TrustedMsgSenderProviderLookup(address(trustedMsgSenderLookup)).addTrustedMsgSenderProviders(sendersToAdd);
82
+ }
83
+
84
+ function test_removeTrustedMsgSenderProviders_worksCorrectly() public {
85
+ address[] memory initialTrustedSenders = new address[](2);
86
+ initialTrustedSenders[0] = trustedSender1;
87
+ initialTrustedSenders[1] = trustedSender2;
88
+ trustedMsgSenderLookup = deployAndInitializeLookup(initialTrustedSenders, owner);
89
+
90
+ address[] memory sendersToRemove = new address[](1);
91
+ sendersToRemove[0] = trustedSender1;
92
+
93
+ vm.prank(owner);
94
+ TrustedMsgSenderProviderLookup(address(trustedMsgSenderLookup)).removeTrustedMsgSenderProviders(sendersToRemove);
95
+
96
+ assertFalse(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender1));
97
+ assertTrue(trustedMsgSenderLookup.isTrustedMsgSenderProvider(trustedSender2));
98
+ }
99
+
100
+ function test_removeTrustedMsgSenderProviders_onlyOwnerCanRemove() public {
101
+ address[] memory initialTrustedSenders = new address[](1);
102
+ initialTrustedSenders[0] = trustedSender1;
103
+ trustedMsgSenderLookup = deployAndInitializeLookup(initialTrustedSenders, owner);
104
+
105
+ address[] memory sendersToRemove = new address[](1);
106
+ sendersToRemove[0] = trustedSender1;
107
+
108
+ vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, nonOwner));
109
+ vm.prank(nonOwner);
110
+ TrustedMsgSenderProviderLookup(address(trustedMsgSenderLookup)).removeTrustedMsgSenderProviders(sendersToRemove);
111
+ }
112
+ }