@zoralabs/coins 2.1.2 → 2.2.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.
- package/.turbo/turbo-build$colon$js.log +152 -0
- package/CHANGELOG.md +54 -0
- package/abis/BaseCoin.json +26 -0
- package/abis/BaseTest.json +2 -7
- package/abis/CoinConstants.json +0 -104
- package/abis/ContentCoin.json +26 -0
- package/abis/CreatorCoin.json +30 -4
- package/abis/FeeEstimatorHook.json +0 -5
- package/abis/ICoin.json +26 -0
- package/abis/ICoinV3.json +26 -0
- package/abis/ICreatorCoin.json +39 -0
- package/abis/IERC721.json +36 -36
- package/abis/IHasCoinType.json +15 -0
- package/abis/IHasTotalSupplyForPositions.json +15 -0
- package/abis/IZoraFactory.json +52 -0
- package/abis/IZoraHookRegistry.json +188 -0
- package/abis/VmContractHelper227.json +233 -0
- package/abis/ZoraFactoryImpl.json +32 -6
- package/abis/ZoraHookRegistry.json +375 -0
- package/abis/{CreatorCoinHook.json → ZoraV4CoinHook.json} +1 -1
- package/addresses/8453.json +2 -1
- package/dist/index.cjs +72 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -10
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +90 -10
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/foundry.toml +4 -1
- package/package/wagmiGenerated.ts +72 -10
- package/package.json +6 -4
- package/script/PrintRegisterUpgradePath.s.sol +0 -7
- package/script/TestBackingCoinSwap.s.sol +0 -1
- package/script/TestV4Swap.s.sol +0 -1
- package/script/UpgradeFactoryImpl.s.sol +1 -1
- package/src/BaseCoin.sol +15 -12
- package/src/ContentCoin.sol +10 -0
- package/src/CreatorCoin.sol +28 -7
- package/src/ZoraFactoryImpl.sol +62 -23
- package/src/deployment/CoinsDeployerBase.sol +24 -58
- package/src/hook-registry/ZoraHookRegistry.sol +93 -0
- package/src/hooks/{BaseZoraV4CoinHook.sol → ZoraV4CoinHook.sol} +13 -8
- package/src/interfaces/ICoin.sol +19 -1
- package/src/interfaces/ICreatorCoin.sol +4 -0
- package/src/interfaces/IZoraFactory.sol +32 -10
- package/src/interfaces/IZoraHookRegistry.sol +47 -0
- package/src/libs/CoinConstants.sol +0 -32
- package/src/libs/CoinRewardsV4.sol +53 -15
- package/src/libs/CreatorCoinConstants.sol +0 -1
- package/src/libs/HooksDeployment.sol +13 -65
- package/src/libs/MarketConstants.sol +11 -3
- package/src/libs/V4Liquidity.sol +30 -0
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/CoinUniV4.t.sol +33 -30
- package/test/ContentCoinRewards.t.sol +320 -0
- package/test/CreatorCoin.t.sol +1 -1
- package/test/CreatorCoinRewards.t.sol +375 -0
- package/test/DeploymentHooks.t.sol +10 -10
- package/test/Factory.t.sol +24 -7
- package/test/HooksDeployment.t.sol +4 -4
- package/test/LiquidityMigration.t.sol +4 -9
- package/test/Upgrades.t.sol +44 -48
- package/test/ZoraHookRegistry.t.sol +266 -0
- package/test/utils/BaseTest.sol +25 -42
- package/test/utils/FeeEstimatorHook.sol +4 -6
- package/test/utils/RewardTestHelpers.sol +106 -0
- package/.turbo/turbo-build.log +0 -199
- package/abis/AutoSwapperTest.json +0 -618
- package/abis/BadImpl.json +0 -15
- package/abis/BaseZoraV4CoinHook.json +0 -1664
- package/abis/CoinTest.json +0 -819
- package/abis/CoinUniV4Test.json +0 -1128
- package/abis/ContentCoinHook.json +0 -1733
- package/abis/CreatorCoinTest.json +0 -887
- package/abis/Deploy.json +0 -9
- package/abis/DeployHooks.json +0 -9
- package/abis/DeployScript.json +0 -35
- package/abis/DeployedCoinVersionLookupTest.json +0 -740
- package/abis/DifferentNamespaceVersionLookup.json +0 -39
- package/abis/FactoryTest.json +0 -748
- package/abis/FakeHookNoInterface.json +0 -21
- package/abis/GenerateDeterministicParams.json +0 -9
- package/abis/HooksDeploymentTest.json +0 -645
- package/abis/HooksTest.json +0 -709
- package/abis/InvalidLiquidityMigrationReceiver.json +0 -21
- package/abis/LiquidityMigrationReceiver.json +0 -103
- package/abis/LiquidityMigrationTest.json +0 -889
- package/abis/MockBadFactory.json +0 -15
- package/abis/MultiOwnableTest.json +0 -766
- package/abis/PrintUpgradeCommand.json +0 -9
- package/abis/TestDeployedCoinVersionLookupImplementation.json +0 -39
- package/abis/TestV4Swap.json +0 -9
- package/abis/UpgradeFactoryImpl.json +0 -9
- package/abis/UpgradeHooks.json +0 -35
- package/abis/UpgradesTest.json +0 -723
- package/src/hooks/ContentCoinHook.sol +0 -27
- package/src/hooks/CreatorCoinHook.sol +0 -27
- package/src/libs/CreatorCoinRewards.sol +0 -34
package/test/Upgrades.t.sol
CHANGED
|
@@ -13,7 +13,7 @@ import {IWETH} from "../src/interfaces/IWETH.sol";
|
|
|
13
13
|
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
14
14
|
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
|
|
15
15
|
import {BuySupplyWithSwapRouterHook} from "../src/hooks/deployment/BuySupplyWithSwapRouterHook.sol";
|
|
16
|
-
import {
|
|
16
|
+
import {ZoraV4CoinHook} from "../src/hooks/ZoraV4CoinHook.sol";
|
|
17
17
|
import {console} from "forge-std/console.sol";
|
|
18
18
|
import {IDeployedCoinVersionLookup} from "../src/interfaces/IDeployedCoinVersionLookup.sol";
|
|
19
19
|
import {IHooksUpgradeGate} from "../src/interfaces/IHooksUpgradeGate.sol";
|
|
@@ -43,7 +43,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
43
43
|
|
|
44
44
|
factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
|
|
45
45
|
|
|
46
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(
|
|
46
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(hook), address(zoraHookRegistry));
|
|
47
47
|
|
|
48
48
|
vm.prank(factoryProxy.owner());
|
|
49
49
|
factoryProxy.upgradeToAndCall(address(newImpl), "");
|
|
@@ -58,7 +58,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
58
58
|
|
|
59
59
|
factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
|
|
60
60
|
|
|
61
|
-
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(
|
|
61
|
+
ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(hook), address(zoraHookRegistry));
|
|
62
62
|
|
|
63
63
|
vm.prank(factoryProxy.owner());
|
|
64
64
|
factoryProxy.upgradeToAndCall(address(newImpl), "");
|
|
@@ -70,29 +70,25 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
70
70
|
factoryProxy.upgradeToAndCall(address(badImpl), "");
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
// This fork test needs to be updated after hook registry + new factory is deployed
|
|
74
|
+
// function test_canUpgradeToSameContractName() public {
|
|
75
|
+
// // this test that we can upgrade to the same contract name, when we have already upgraded to a version that has a contract name
|
|
76
|
+
// vm.createSelectFork("base", 29675508);
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
// factoryProxy = ZoraFactoryImpl(0x777777751622c0d3258f214F9DF38E35BF45baF3);
|
|
78
79
|
|
|
79
|
-
|
|
80
|
+
// ZoraFactoryImpl newImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(hook), address(zoraHookRegistry));
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
// vm.prank(factoryProxy.owner());
|
|
83
|
+
// factoryProxy.upgradeToAndCall(address(newImpl), "");
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
factoryProxy.coinV4Impl(),
|
|
86
|
-
factoryProxy.creatorCoinImpl(),
|
|
87
|
-
address(contentCoinHook),
|
|
88
|
-
address(creatorCoinHook)
|
|
89
|
-
);
|
|
85
|
+
// ZoraFactoryImpl newImpl2 = new ZoraFactoryImpl(factoryProxy.coinV4Impl(), factoryProxy.creatorCoinImpl(), address(hook), address(zoraHookRegistry));
|
|
90
86
|
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
// vm.prank(factoryProxy.owner());
|
|
88
|
+
// factoryProxy.upgradeToAndCall(address(newImpl2), "");
|
|
93
89
|
|
|
94
|
-
|
|
95
|
-
}
|
|
90
|
+
// assertEq(factoryProxy.implementation(), address(newImpl2));
|
|
91
|
+
// }
|
|
96
92
|
|
|
97
93
|
function test_canUpgradeAndSwap() public {
|
|
98
94
|
vm.createSelectFork("base");
|
|
@@ -179,32 +175,6 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
179
175
|
vm.stopPrank();
|
|
180
176
|
}
|
|
181
177
|
|
|
182
|
-
function test_canCanFixBrokenContentCoinAndSwap() public {
|
|
183
|
-
vm.createSelectFork("base", 31835069);
|
|
184
|
-
|
|
185
|
-
address trader = 0xf69fEc6d858c77e969509843852178bd24CAd2B6;
|
|
186
|
-
|
|
187
|
-
address contentCoin = 0x4E93A01c90f812284F71291a8d1415a904957156;
|
|
188
|
-
|
|
189
|
-
address creatorCoin = ICoin(contentCoin).currency();
|
|
190
|
-
|
|
191
|
-
uint256 amountIn = IERC20(creatorCoin).balanceOf(trader);
|
|
192
|
-
|
|
193
|
-
require(amountIn > 0, "no balance");
|
|
194
|
-
|
|
195
|
-
// this swap should revert because the content coin is broken
|
|
196
|
-
_swapSomeCurrencyForCoinAndExpectRevert(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
|
|
197
|
-
|
|
198
|
-
bytes memory creationCode = HooksDeployment.contentCoinCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
|
|
199
|
-
|
|
200
|
-
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
201
|
-
|
|
202
|
-
// etch new hook into the content coin, it shouldn't revert anymore when swapping
|
|
203
|
-
vm.etch(address(ICoin(contentCoin).hooks()), address(newHook).code);
|
|
204
|
-
|
|
205
|
-
_swapSomeCurrencyForCoin(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
178
|
function test_canUpgradeBrokenContentCoinAndSwap() public {
|
|
209
179
|
vm.createSelectFork("base", 32613149);
|
|
210
180
|
|
|
@@ -216,7 +186,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
216
186
|
|
|
217
187
|
uint256 amountIn = 0.000111 ether;
|
|
218
188
|
|
|
219
|
-
bytes memory creationCode = HooksDeployment.
|
|
189
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
|
|
220
190
|
|
|
221
191
|
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
222
192
|
|
|
@@ -268,7 +238,7 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
268
238
|
|
|
269
239
|
address existingHook = address(creatorCoin.hooks());
|
|
270
240
|
|
|
271
|
-
bytes memory creationCode = HooksDeployment.
|
|
241
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
|
|
272
242
|
|
|
273
243
|
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
274
244
|
|
|
@@ -319,4 +289,30 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
319
289
|
// now try to swap some currency for the creator coin - it should succeed
|
|
320
290
|
_swapSomeCurrencyForCoin(creatorCoin, zora, uint128(IERC20(zora).balanceOf(trader) / 2), trader);
|
|
321
291
|
}
|
|
292
|
+
|
|
293
|
+
function test_canFixBrokenContentCoinAndSwap() public {
|
|
294
|
+
vm.createSelectFork("base", 31835069);
|
|
295
|
+
|
|
296
|
+
address trader = 0xf69fEc6d858c77e969509843852178bd24CAd2B6;
|
|
297
|
+
|
|
298
|
+
address contentCoin = 0x4E93A01c90f812284F71291a8d1415a904957156;
|
|
299
|
+
|
|
300
|
+
address creatorCoin = ICoin(contentCoin).currency();
|
|
301
|
+
|
|
302
|
+
uint256 amountIn = IERC20(creatorCoin).balanceOf(trader);
|
|
303
|
+
|
|
304
|
+
require(amountIn > 0, "no balance");
|
|
305
|
+
|
|
306
|
+
// this swap should revert because the content coin is broken
|
|
307
|
+
_swapSomeCurrencyForCoinAndExpectRevert(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
|
|
308
|
+
|
|
309
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, new address[](0), upgradeGate);
|
|
310
|
+
|
|
311
|
+
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
312
|
+
|
|
313
|
+
// etch new hook into the content coin, it shouldn't revert anymore when swapping
|
|
314
|
+
vm.etch(address(ICoin(contentCoin).hooks()), address(newHook).code);
|
|
315
|
+
|
|
316
|
+
_swapSomeCurrencyForCoin(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
|
|
317
|
+
}
|
|
322
318
|
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// SPDX-License-Identifier: UNLICENSED
|
|
2
|
+
pragma solidity ^0.8.28;
|
|
3
|
+
|
|
4
|
+
import "forge-std/Test.sol";
|
|
5
|
+
|
|
6
|
+
import {IZoraHookRegistry} from "../src/interfaces/IZoraHookRegistry.sol";
|
|
7
|
+
import {ZoraHookRegistry} from "../src/hook-registry/ZoraHookRegistry.sol";
|
|
8
|
+
|
|
9
|
+
contract MockHook {
|
|
10
|
+
function contractVersion() public pure returns (string memory) {
|
|
11
|
+
return "0.0.0";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
contract ZoraHookRegistryTest is Test {
|
|
16
|
+
uint256 internal forkId;
|
|
17
|
+
address internal owner;
|
|
18
|
+
|
|
19
|
+
ZoraHookRegistry internal zoraHookRegistry;
|
|
20
|
+
MockHook internal mockHook;
|
|
21
|
+
|
|
22
|
+
function setUp() public {
|
|
23
|
+
forkId = vm.createSelectFork("base", 34509280);
|
|
24
|
+
owner = makeAddr("owner");
|
|
25
|
+
|
|
26
|
+
address[] memory initialOwners = new address[](1);
|
|
27
|
+
initialOwners[0] = owner;
|
|
28
|
+
|
|
29
|
+
zoraHookRegistry = new ZoraHookRegistry();
|
|
30
|
+
zoraHookRegistry.initialize(initialOwners);
|
|
31
|
+
|
|
32
|
+
mockHook = new MockHook();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function test_register_hooks() public {
|
|
36
|
+
address[] memory hooks = new address[](1);
|
|
37
|
+
string[] memory tags = new string[](1);
|
|
38
|
+
|
|
39
|
+
hooks[0] = address(mockHook);
|
|
40
|
+
tags[0] = "ZoraHook";
|
|
41
|
+
|
|
42
|
+
vm.prank(owner);
|
|
43
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
44
|
+
|
|
45
|
+
assertEq(zoraHookRegistry.isRegisteredHook(hooks[0]), true);
|
|
46
|
+
|
|
47
|
+
address[] memory addrs = zoraHookRegistry.getHookAddresses();
|
|
48
|
+
assertEq(addrs.length, 1);
|
|
49
|
+
assertEq(addrs[0], hooks[0]);
|
|
50
|
+
|
|
51
|
+
assertEq(zoraHookRegistry.getHookTag(hooks[0]), tags[0]);
|
|
52
|
+
|
|
53
|
+
IZoraHookRegistry.ZoraHook[] memory zoraHooks = zoraHookRegistry.getHooks();
|
|
54
|
+
assertEq(zoraHooks.length, 1);
|
|
55
|
+
assertEq(zoraHooks[0].hook, hooks[0]);
|
|
56
|
+
assertEq(zoraHooks[0].tag, "ZoraHook");
|
|
57
|
+
assertEq(zoraHooks[0].version, "0.0.0");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function test_revert_register_hooks_only_owner() public {
|
|
61
|
+
address[] memory hooks = new address[](1);
|
|
62
|
+
string[] memory tags = new string[](1);
|
|
63
|
+
|
|
64
|
+
hooks[0] = address(mockHook);
|
|
65
|
+
tags[0] = "ZoraHook";
|
|
66
|
+
|
|
67
|
+
vm.expectRevert(abi.encodeWithSignature("OnlyOwner()"));
|
|
68
|
+
vm.prank(makeAddr("notOwner"));
|
|
69
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function test_revert_register_hooks_array_length_mismatch() public {
|
|
73
|
+
address[] memory hooks = new address[](2);
|
|
74
|
+
string[] memory tags = new string[](1);
|
|
75
|
+
|
|
76
|
+
hooks[0] = address(mockHook);
|
|
77
|
+
hooks[1] = makeAddr("anotherHook");
|
|
78
|
+
tags[0] = "Tag0";
|
|
79
|
+
|
|
80
|
+
vm.prank(owner);
|
|
81
|
+
vm.expectRevert(abi.encodeWithSignature("ArrayLengthMismatch()"));
|
|
82
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function test_register_duplicate_is_idempotent() public {
|
|
86
|
+
address[] memory hooks = new address[](1);
|
|
87
|
+
string[] memory tags = new string[](1);
|
|
88
|
+
|
|
89
|
+
hooks[0] = address(mockHook);
|
|
90
|
+
tags[0] = "ZoraHook";
|
|
91
|
+
|
|
92
|
+
vm.startPrank(owner);
|
|
93
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
94
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
95
|
+
vm.stopPrank();
|
|
96
|
+
|
|
97
|
+
assertEq(zoraHookRegistry.getHookAddresses().length, 1);
|
|
98
|
+
assertEq(zoraHookRegistry.isRegisteredHook(hooks[0]), true);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function test_remove_hooks() public {
|
|
102
|
+
address[] memory hooks = new address[](1);
|
|
103
|
+
string[] memory tags = new string[](1);
|
|
104
|
+
|
|
105
|
+
hooks[0] = address(mockHook);
|
|
106
|
+
tags[0] = "ZoraHook";
|
|
107
|
+
|
|
108
|
+
vm.prank(owner);
|
|
109
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
110
|
+
|
|
111
|
+
vm.prank(owner);
|
|
112
|
+
zoraHookRegistry.removeHooks(hooks);
|
|
113
|
+
|
|
114
|
+
assertEq(zoraHookRegistry.isRegisteredHook(hooks[0]), false);
|
|
115
|
+
assertEq(zoraHookRegistry.getHookAddresses().length, 0);
|
|
116
|
+
assertEq(zoraHookRegistry.getHookTag(hooks[0]), "");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function test_revert_remove_hooks_only_owner() public {
|
|
120
|
+
address[] memory hooks = new address[](1);
|
|
121
|
+
string[] memory tags = new string[](1);
|
|
122
|
+
|
|
123
|
+
hooks[0] = address(mockHook);
|
|
124
|
+
tags[0] = "ZoraHook";
|
|
125
|
+
|
|
126
|
+
vm.prank(owner);
|
|
127
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
128
|
+
|
|
129
|
+
vm.expectRevert(abi.encodeWithSignature("OnlyOwner()"));
|
|
130
|
+
vm.prank(makeAddr("notOwner"));
|
|
131
|
+
zoraHookRegistry.removeHooks(hooks);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function test_remove_unregistered_noop() public {
|
|
135
|
+
address[] memory hooks = new address[](1);
|
|
136
|
+
hooks[0] = makeAddr("unregistered");
|
|
137
|
+
|
|
138
|
+
uint256 beforeLen = zoraHookRegistry.getHookAddresses().length;
|
|
139
|
+
|
|
140
|
+
vm.prank(owner);
|
|
141
|
+
zoraHookRegistry.removeHooks(hooks);
|
|
142
|
+
|
|
143
|
+
assertEq(zoraHookRegistry.getHookAddresses().length, beforeLen);
|
|
144
|
+
assertEq(zoraHookRegistry.isRegisteredHook(hooks[0]), false);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function test_emit_register_hooks_event() public {
|
|
148
|
+
address[] memory hooks = new address[](1);
|
|
149
|
+
string[] memory tags = new string[](1);
|
|
150
|
+
|
|
151
|
+
hooks[0] = address(mockHook);
|
|
152
|
+
tags[0] = "ZoraHook";
|
|
153
|
+
|
|
154
|
+
vm.expectEmit(true, true, true, false, address(zoraHookRegistry));
|
|
155
|
+
emit IZoraHookRegistry.ZoraHookRegistered(hooks[0], tags[0], "0.0.0");
|
|
156
|
+
|
|
157
|
+
vm.prank(owner);
|
|
158
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function test_emit_remove_hooks_event() public {
|
|
162
|
+
address[] memory hooks = new address[](1);
|
|
163
|
+
string[] memory tags = new string[](1);
|
|
164
|
+
|
|
165
|
+
hooks[0] = address(mockHook);
|
|
166
|
+
tags[0] = "ZoraHook";
|
|
167
|
+
|
|
168
|
+
vm.prank(owner);
|
|
169
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
170
|
+
|
|
171
|
+
vm.expectEmit(true, true, true, false, address(zoraHookRegistry));
|
|
172
|
+
emit IZoraHookRegistry.ZoraHookRemoved(hooks[0], tags[0], "0.0.0");
|
|
173
|
+
|
|
174
|
+
vm.prank(owner);
|
|
175
|
+
zoraHookRegistry.removeHooks(hooks);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function test_hook_version() public {
|
|
179
|
+
address[] memory hooks = new address[](1);
|
|
180
|
+
string[] memory tags = new string[](1);
|
|
181
|
+
|
|
182
|
+
hooks[0] = 0x81542dC43Aff247eff4a0eceFC286A2973aE1040;
|
|
183
|
+
tags[0] = "CONTENT";
|
|
184
|
+
|
|
185
|
+
vm.prank(owner);
|
|
186
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
187
|
+
|
|
188
|
+
assertEq(zoraHookRegistry.getHookVersion(hooks[0]), "1.1.1");
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function test_hook_version_not_found() public {
|
|
192
|
+
address[] memory hooks = new address[](1);
|
|
193
|
+
string[] memory tags = new string[](1);
|
|
194
|
+
|
|
195
|
+
hooks[0] = 0xA1eBdD5cA6470Bbd67114331387f2dDa7bfad040;
|
|
196
|
+
tags[0] = "CONTENT";
|
|
197
|
+
|
|
198
|
+
vm.prank(owner);
|
|
199
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
200
|
+
|
|
201
|
+
assertEq(zoraHookRegistry.getHookVersion(hooks[0]), "");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function test_is_registered_hook_false_when_never_registered() public view {
|
|
205
|
+
assertEq(zoraHookRegistry.isRegisteredHook(address(this)), false);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function test_get_hook_addresses_multiple_and_remove_middle() public {
|
|
209
|
+
address a = address(mockHook);
|
|
210
|
+
address b = address(new MockHook());
|
|
211
|
+
address c = address(new MockHook());
|
|
212
|
+
|
|
213
|
+
address[] memory hooks = new address[](3);
|
|
214
|
+
string[] memory tags = new string[](3);
|
|
215
|
+
hooks[0] = a;
|
|
216
|
+
tags[0] = "A";
|
|
217
|
+
hooks[1] = b;
|
|
218
|
+
tags[1] = "B";
|
|
219
|
+
hooks[2] = c;
|
|
220
|
+
tags[2] = "C";
|
|
221
|
+
|
|
222
|
+
vm.prank(owner);
|
|
223
|
+
zoraHookRegistry.registerHooks(hooks, tags);
|
|
224
|
+
|
|
225
|
+
address[] memory removeB = new address[](1);
|
|
226
|
+
removeB[0] = b;
|
|
227
|
+
|
|
228
|
+
vm.prank(owner);
|
|
229
|
+
zoraHookRegistry.removeHooks(removeB);
|
|
230
|
+
|
|
231
|
+
address[] memory addrs = zoraHookRegistry.getHookAddresses();
|
|
232
|
+
assertEq(addrs.length, 2);
|
|
233
|
+
|
|
234
|
+
bool hasA;
|
|
235
|
+
bool hasC;
|
|
236
|
+
for (uint256 i = 0; i < addrs.length; i++) {
|
|
237
|
+
if (addrs[i] == a) hasA = true;
|
|
238
|
+
if (addrs[i] == c) hasC = true;
|
|
239
|
+
assertTrue(addrs[i] != b);
|
|
240
|
+
}
|
|
241
|
+
assertTrue(hasA);
|
|
242
|
+
assertTrue(hasC);
|
|
243
|
+
|
|
244
|
+
assertEq(zoraHookRegistry.getHookTag(a), "A");
|
|
245
|
+
assertEq(zoraHookRegistry.getHookTag(b), "");
|
|
246
|
+
assertEq(zoraHookRegistry.getHookTag(c), "C");
|
|
247
|
+
|
|
248
|
+
IZoraHookRegistry.ZoraHook[] memory full = zoraHookRegistry.getHooks();
|
|
249
|
+
assertEq(full.length, 2);
|
|
250
|
+
|
|
251
|
+
bool okA;
|
|
252
|
+
bool okC;
|
|
253
|
+
for (uint256 i = 0; i < full.length; i++) {
|
|
254
|
+
if (full[i].hook == a) {
|
|
255
|
+
assertEq(full[i].tag, "A");
|
|
256
|
+
assertEq(full[i].version, "0.0.0");
|
|
257
|
+
okA = true;
|
|
258
|
+
} else if (full[i].hook == c) {
|
|
259
|
+
assertEq(full[i].tag, "C");
|
|
260
|
+
assertEq(full[i].version, "0.0.0");
|
|
261
|
+
okC = true;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
assertTrue(okA && okC);
|
|
265
|
+
}
|
|
266
|
+
}
|
package/test/utils/BaseTest.sol
CHANGED
|
@@ -27,7 +27,7 @@ import {ProtocolRewards} from "../utils/ProtocolRewards.sol";
|
|
|
27
27
|
import {MarketConstants} from "../../src/libs/MarketConstants.sol";
|
|
28
28
|
import {CoinConfigurationVersions} from "../../src/libs/CoinConfigurationVersions.sol";
|
|
29
29
|
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
30
|
-
import {
|
|
30
|
+
import {ZoraV4CoinHook} from "../../src/hooks/ZoraV4CoinHook.sol";
|
|
31
31
|
import {HooksDeployment} from "../../src/libs/HooksDeployment.sol";
|
|
32
32
|
import {CoinConstants} from "../../src/libs/CoinConstants.sol";
|
|
33
33
|
import {ProxyShim} from "./ProxyShim.sol";
|
|
@@ -41,15 +41,19 @@ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
|
41
41
|
import {Actions} from "@uniswap/v4-periphery/src/libraries/Actions.sol";
|
|
42
42
|
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
43
43
|
import {CreatorCoin} from "../../src/CreatorCoin.sol";
|
|
44
|
-
import {CreatorCoinHook} from "../../src/hooks/CreatorCoinHook.sol";
|
|
45
44
|
import {ContractAddresses} from "./ContractAddresses.sol";
|
|
46
45
|
import {IHooks} from "@uniswap/v4-core/src/interfaces/IHooks.sol";
|
|
47
46
|
import {HookUpgradeGate} from "../../src/hooks/HookUpgradeGate.sol";
|
|
47
|
+
import {ZoraHookRegistry} from "../../src/hook-registry/ZoraHookRegistry.sol";
|
|
48
48
|
|
|
49
49
|
contract BaseTest is Test, ContractAddresses {
|
|
50
50
|
using stdStorage for StdStorage;
|
|
51
51
|
|
|
52
52
|
int24 internal constant USDC_TICK_LOWER = 57200;
|
|
53
|
+
int24 internal constant DEFAULT_DISCOVERY_TICK_LOWER = CoinConstants.DEFAULT_DISCOVERY_TICK_LOWER;
|
|
54
|
+
int24 internal constant DEFAULT_DISCOVERY_TICK_UPPER = CoinConstants.DEFAULT_DISCOVERY_TICK_UPPER;
|
|
55
|
+
uint16 internal constant DEFAULT_NUM_DISCOVERY_POSITIONS = CoinConstants.DEFAULT_NUM_DISCOVERY_POSITIONS;
|
|
56
|
+
uint256 internal constant DEFAULT_DISCOVERY_SUPPLY_SHARE = CoinConstants.DEFAULT_DISCOVERY_SUPPLY_SHARE;
|
|
53
57
|
|
|
54
58
|
struct Users {
|
|
55
59
|
address factoryOwner;
|
|
@@ -85,13 +89,9 @@ contract BaseTest is Test, ContractAddresses {
|
|
|
85
89
|
CreatorCoin internal creatorCoinImpl;
|
|
86
90
|
ZoraFactoryImpl internal factoryImpl;
|
|
87
91
|
IZoraFactory internal factory;
|
|
88
|
-
|
|
89
|
-
CreatorCoinHook internal creatorCoinHook;
|
|
92
|
+
ZoraV4CoinHook internal hook;
|
|
90
93
|
HookUpgradeGate internal hookUpgradeGate;
|
|
91
|
-
|
|
92
|
-
int24 internal constant DEFAULT_DISCOVERY_TICK_UPPER = CoinConstants.DEFAULT_DISCOVERY_TICK_UPPER;
|
|
93
|
-
uint16 internal constant DEFAULT_NUM_DISCOVERY_POSITIONS = CoinConstants.DEFAULT_NUM_DISCOVERY_POSITIONS;
|
|
94
|
-
uint256 internal constant DEFAULT_DISCOVERY_SUPPLY_SHARE = CoinConstants.DEFAULT_DISCOVERY_SUPPLY_SHARE;
|
|
94
|
+
ZoraHookRegistry internal zoraHookRegistry;
|
|
95
95
|
|
|
96
96
|
function _defaultPoolConfig(address currency) internal pure returns (bytes memory) {
|
|
97
97
|
return CoinConfigurationVersions.defaultDopplerMultiCurveUniV4(currency);
|
|
@@ -203,28 +203,14 @@ contract BaseTest is Test, ContractAddresses {
|
|
|
203
203
|
vm.stopPrank();
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
function _deployFeeEstimatorHook(
|
|
207
|
-
deployCodeTo("FeeEstimatorHook.sol", abi.encode(V4_POOL_MANAGER, address(factory), hookUpgradeGate
|
|
206
|
+
function _deployFeeEstimatorHook(address hooks) internal {
|
|
207
|
+
deployCodeTo("FeeEstimatorHook.sol", abi.encode(V4_POOL_MANAGER, address(factory), hookUpgradeGate), hooks);
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
function
|
|
210
|
+
function getSalt(address[] memory trustedMessageSenders) public returns (bytes32 hookSalt) {
|
|
211
211
|
address deployer = address(this);
|
|
212
212
|
|
|
213
|
-
(,
|
|
214
|
-
deployer,
|
|
215
|
-
V4_POOL_MANAGER,
|
|
216
|
-
address(factory),
|
|
217
|
-
trustedMessageSenders,
|
|
218
|
-
address(hookUpgradeGate)
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
(, creatorCoinSalt) = HooksDeployment.mineForCreatorCoinSalt(
|
|
222
|
-
deployer,
|
|
223
|
-
V4_POOL_MANAGER,
|
|
224
|
-
address(factory),
|
|
225
|
-
trustedMessageSenders,
|
|
226
|
-
address(hookUpgradeGate)
|
|
227
|
-
);
|
|
213
|
+
(, hookSalt) = HooksDeployment.mineForCoinSalt(deployer, V4_POOL_MANAGER, address(factory), trustedMessageSenders, address(hookUpgradeGate));
|
|
228
214
|
}
|
|
229
215
|
|
|
230
216
|
function _deployHooks() internal {
|
|
@@ -232,24 +218,14 @@ contract BaseTest is Test, ContractAddresses {
|
|
|
232
218
|
trustedMessageSenders[0] = UNIVERSAL_ROUTER;
|
|
233
219
|
trustedMessageSenders[1] = V4_POSITION_MANAGER;
|
|
234
220
|
|
|
235
|
-
|
|
221
|
+
bytes32 hookSalt = getSalt(trustedMessageSenders);
|
|
236
222
|
|
|
237
|
-
|
|
238
|
-
payable(
|
|
239
|
-
address(
|
|
240
|
-
HooksDeployment.deployHookWithSalt(
|
|
241
|
-
HooksDeployment.contentCoinCreationCode(V4_POOL_MANAGER, address(factory), trustedMessageSenders, address(hookUpgradeGate)),
|
|
242
|
-
contentCoinSalt
|
|
243
|
-
)
|
|
244
|
-
)
|
|
245
|
-
)
|
|
246
|
-
);
|
|
247
|
-
creatorCoinHook = CreatorCoinHook(
|
|
223
|
+
hook = ZoraV4CoinHook(
|
|
248
224
|
payable(
|
|
249
225
|
address(
|
|
250
226
|
HooksDeployment.deployHookWithSalt(
|
|
251
|
-
HooksDeployment.
|
|
252
|
-
|
|
227
|
+
HooksDeployment.makeHookCreationCode(V4_POOL_MANAGER, address(factory), trustedMessageSenders, address(hookUpgradeGate)),
|
|
228
|
+
hookSalt
|
|
253
229
|
)
|
|
254
230
|
)
|
|
255
231
|
)
|
|
@@ -291,13 +267,20 @@ contract BaseTest is Test, ContractAddresses {
|
|
|
291
267
|
|
|
292
268
|
hookUpgradeGate = new HookUpgradeGate(users.factoryOwner);
|
|
293
269
|
|
|
270
|
+
zoraHookRegistry = new ZoraHookRegistry();
|
|
271
|
+
|
|
272
|
+
address[] memory initialOwners = new address[](2);
|
|
273
|
+
initialOwners[0] = users.factoryOwner;
|
|
274
|
+
initialOwners[1] = address(factory);
|
|
275
|
+
zoraHookRegistry.initialize(initialOwners);
|
|
276
|
+
|
|
294
277
|
_deployHooks();
|
|
295
278
|
|
|
296
279
|
coinV4Impl = new ContentCoin(users.feeRecipient, address(protocolRewards), IPoolManager(V4_POOL_MANAGER), DOPPLER_AIRLOCK);
|
|
297
280
|
|
|
298
281
|
creatorCoinImpl = new CreatorCoin(users.feeRecipient, address(protocolRewards), IPoolManager(V4_POOL_MANAGER), DOPPLER_AIRLOCK);
|
|
299
282
|
|
|
300
|
-
factoryImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(
|
|
283
|
+
factoryImpl = new ZoraFactoryImpl(address(coinV4Impl), address(creatorCoinImpl), address(hook), address(zoraHookRegistry));
|
|
301
284
|
UUPSUpgradeable(address(factory)).upgradeToAndCall(address(factoryImpl), "");
|
|
302
285
|
factory = IZoraFactory(address(factory));
|
|
303
286
|
|
|
@@ -317,7 +300,7 @@ contract BaseTest is Test, ContractAddresses {
|
|
|
317
300
|
vm.label(address(V4_QUOTER), "V4_QUOTER");
|
|
318
301
|
vm.label(address(V4_PERMIT2), "V4_PERMIT2");
|
|
319
302
|
vm.label(address(UNIVERSAL_ROUTER), "UNIVERSAL_ROUTER");
|
|
320
|
-
vm.label(address(
|
|
303
|
+
vm.label(address(hook), "HOOK");
|
|
321
304
|
}
|
|
322
305
|
|
|
323
306
|
struct TradeRewards {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
pragma solidity ^0.8.13;
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {ZoraV4CoinHook} from "../../src/hooks/ZoraV4CoinHook.sol";
|
|
5
5
|
import {IPoolManager, PoolKey} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
6
6
|
import {IDeployedCoinVersionLookup} from "../../src/interfaces/IDeployedCoinVersionLookup.sol";
|
|
7
7
|
import {IHasRewardsRecipients} from "../../src/interfaces/IHasRewardsRecipients.sol";
|
|
@@ -15,11 +15,10 @@ import {ICoin, IHasSwapPath} from "../../src/interfaces/ICoin.sol";
|
|
|
15
15
|
import {UniV4SwapToCurrency} from "../../src/libs/UniV4SwapToCurrency.sol";
|
|
16
16
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
17
17
|
import {CoinRewardsV4} from "../../src/libs/CoinRewardsV4.sol";
|
|
18
|
-
import {BaseZoraV4CoinHook} from "../../src/hooks/BaseZoraV4CoinHook.sol";
|
|
19
18
|
import {IHooksUpgradeGate} from "../../src/interfaces/IHooksUpgradeGate.sol";
|
|
20
19
|
|
|
21
20
|
/// @dev Test util - meant to be able to etched where a normal zora hook is, to gather the fees from swaps but not distribute them
|
|
22
|
-
contract FeeEstimatorHook is
|
|
21
|
+
contract FeeEstimatorHook is ZoraV4CoinHook {
|
|
23
22
|
struct FeeEstimatorState {
|
|
24
23
|
uint128 fees0;
|
|
25
24
|
uint128 fees1;
|
|
@@ -34,9 +33,8 @@ contract FeeEstimatorHook is BaseZoraV4CoinHook {
|
|
|
34
33
|
constructor(
|
|
35
34
|
IPoolManager _poolManager,
|
|
36
35
|
IDeployedCoinVersionLookup _coinVersionLookup,
|
|
37
|
-
IHooksUpgradeGate upgradeGate
|
|
38
|
-
|
|
39
|
-
) BaseZoraV4CoinHook(_poolManager, _coinVersionLookup, new address[](0), upgradeGate, initialSupplyForPositions) {}
|
|
36
|
+
IHooksUpgradeGate upgradeGate
|
|
37
|
+
) ZoraV4CoinHook(_poolManager, _coinVersionLookup, new address[](0), upgradeGate) {}
|
|
40
38
|
|
|
41
39
|
FeeEstimatorState public feeState;
|
|
42
40
|
|