@zoralabs/coins 2.3.0 → 2.4.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.
- package/.turbo/turbo-build$colon$js.log +119 -101
- package/CHANGELOG.md +31 -1
- package/README.md +1 -0
- package/abis/AddressConstants.json +7 -0
- package/abis/BaseTest.json +65 -3
- package/abis/BuySupplyWithV4SwapHook.json +429 -0
- package/abis/FeeEstimatorHook.json +23 -0
- package/abis/ITrustedMsgSenderProviderLookup.json +21 -0
- package/abis/IUniswapV4Router04.json +484 -0
- package/abis/IZoraV4CoinHook.json +5 -0
- package/abis/MockAirlock.json +39 -0
- package/abis/SimpleERC20.json +326 -0
- package/abis/TrustedMsgSenderProviderLookup.json +215 -0
- package/abis/VmContractHelper242.json +233 -0
- package/abis/ZoraV4CoinHook.json +21 -3
- package/addresses/8453.json +7 -9
- package/audits/report-cantinacode-zora-1021.pdf +0 -0
- package/dist/index.cjs +140 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +139 -18
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +205 -28
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/foundry.toml +5 -1
- package/package/wagmiGenerated.ts +139 -18
- package/package.json +3 -3
- package/script/DeployPostDeploymentHooks.s.sol +1 -3
- package/script/DeployTrustedMsgSenderLookup.s.sol +20 -0
- package/src/deployment/CoinsDeployerBase.sol +31 -9
- package/src/hooks/ZoraV4CoinHook.sol +19 -55
- package/src/hooks/deployment/BuySupplyWithV4SwapHook.sol +310 -0
- package/src/interfaces/ITrustedMsgSenderProviderLookup.sol +18 -0
- package/src/interfaces/IZoraV4CoinHook.sol +3 -0
- package/src/libs/HooksDeployment.sol +9 -8
- package/src/libs/V4Liquidity.sol +50 -6
- package/src/utils/AutoSwapper.sol +1 -1
- package/src/utils/TrustedMsgSenderProviderLookup.sol +73 -0
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/BuySupplyWithV4SwapHook.t.sol +509 -0
- package/test/Coin.t.sol +21 -9
- package/test/CoinUniV4.t.sol +1 -2
- package/test/ContentCoinRewards.t.sol +1 -3
- package/test/CreatorCoin.t.sol +1 -4
- package/test/CreatorCoinRewards.t.sol +5 -3
- package/test/Factory.t.sol +3 -3
- package/test/HooksDeployment.t.sol +58 -6
- package/test/LiquidityMigration.t.sol +6 -2
- package/test/MultiOwnable.t.sol +4 -4
- package/test/TrustedMsgSenderProviderLookup.t.sol +112 -0
- package/test/Upgrades.t.sol +41 -27
- package/test/ZoraHookRegistry.t.sol +19 -9
- package/test/mocks/MockAirlock.sol +22 -0
- package/test/mocks/SimpleERC20.sol +8 -0
- package/test/utils/BaseTest.sol +185 -6
- package/test/utils/FeeEstimatorHook.sol +3 -1
- package/test/utils/TrustedSenderTestHelper.sol +18 -0
- package/test/utils/hookmate/README.md +50 -0
- package/test/utils/hookmate/artifacts/DeployHelper.sol +20 -0
- package/test/utils/hookmate/artifacts/Permit2.sol +16 -0
- package/test/utils/hookmate/artifacts/UniversalRouter.sol +29 -0
- package/test/utils/hookmate/artifacts/V4PoolManager.sol +17 -0
- package/test/utils/hookmate/artifacts/V4PositionManager.sol +23 -0
- package/test/utils/hookmate/artifacts/V4Quoter.sol +17 -0
- package/test/utils/hookmate/artifacts/V4Router.sol +18 -0
- package/test/utils/hookmate/constants/AddressConstants.sol +193 -0
- package/test/utils/hookmate/interfaces/router/IUniswapV4Router04.sol +173 -0
- package/test/utils/hookmate/interfaces/router/PathKey.sol +34 -0
- package/test/utils/hookmate/test/utils/SwapFeeEventAsserter.sol +24 -0
- package/wagmi.config.ts +1 -1
- package/src/utils/uniswap/BytesLib.sol +0 -35
- package/src/utils/uniswap/Path.sol +0 -31
- /package/abis/{VmContractHelper226.json → VmContractHelper235.json} +0 -0
|
@@ -8,27 +8,62 @@ 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";
|
|
11
13
|
|
|
12
14
|
contract HooksDeploymentTest is Test, ContractAddresses {
|
|
13
15
|
address internal hookUpgradeGate;
|
|
16
|
+
ITrustedMsgSenderProviderLookup internal trustedMsgSenderLookup;
|
|
17
|
+
address internal owner;
|
|
18
|
+
address internal nonOwner;
|
|
19
|
+
address internal trustedSender1;
|
|
20
|
+
address internal trustedSender2;
|
|
21
|
+
address internal nonTrustedSender;
|
|
14
22
|
|
|
15
23
|
function setUp() public {
|
|
16
24
|
vm.createSelectFork("base", 31653138);
|
|
17
25
|
|
|
26
|
+
owner = makeAddr("owner");
|
|
27
|
+
nonOwner = makeAddr("nonOwner");
|
|
28
|
+
trustedSender1 = makeAddr("trustedSender1");
|
|
29
|
+
trustedSender2 = makeAddr("trustedSender2");
|
|
30
|
+
nonTrustedSender = makeAddr("nonTrustedSender");
|
|
31
|
+
|
|
18
32
|
hookUpgradeGate = address(new HookUpgradeGate(makeAddr("factoryOwner")));
|
|
33
|
+
|
|
34
|
+
// Initialize with one trusted sender
|
|
35
|
+
address[] memory initialTrustedSenders = new address[](1);
|
|
36
|
+
initialTrustedSenders[0] = trustedSender1;
|
|
37
|
+
|
|
38
|
+
trustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(owner, initialTrustedSenders);
|
|
19
39
|
}
|
|
20
40
|
|
|
21
41
|
function test_canMineAndCacheSalt() public {
|
|
22
42
|
address[] memory trustedMessageSenders = new address[](0);
|
|
23
43
|
|
|
44
|
+
ITrustedMsgSenderProviderLookup localTrustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(
|
|
45
|
+
makeAddr("owner"),
|
|
46
|
+
trustedMessageSenders
|
|
47
|
+
);
|
|
48
|
+
|
|
24
49
|
(bytes32 salt, ) = HooksDeployment.mineAndCacheSalt(
|
|
25
50
|
address(this),
|
|
26
|
-
abi.encode(
|
|
51
|
+
abi.encode(
|
|
52
|
+
V4_POOL_MANAGER,
|
|
53
|
+
0x777777751622c0d3258f214F9DF38E35BF45baF3,
|
|
54
|
+
ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
|
|
55
|
+
address(hookUpgradeGate)
|
|
56
|
+
)
|
|
27
57
|
);
|
|
28
58
|
|
|
29
59
|
(bytes32 salt2, bool wasCached2) = HooksDeployment.mineAndCacheSalt(
|
|
30
60
|
address(this),
|
|
31
|
-
abi.encode(
|
|
61
|
+
abi.encode(
|
|
62
|
+
V4_POOL_MANAGER,
|
|
63
|
+
0x777777751622c0d3258f214F9DF38E35BF45baF3,
|
|
64
|
+
ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
|
|
65
|
+
address(hookUpgradeGate)
|
|
66
|
+
)
|
|
32
67
|
);
|
|
33
68
|
|
|
34
69
|
assertEq(salt, salt2);
|
|
@@ -40,17 +75,23 @@ contract HooksDeploymentTest is Test, ContractAddresses {
|
|
|
40
75
|
vm.createSelectFork("base", 31653138);
|
|
41
76
|
|
|
42
77
|
address[] memory trustedMessageSenders = new address[](0);
|
|
78
|
+
|
|
79
|
+
ITrustedMsgSenderProviderLookup localTrustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(
|
|
80
|
+
makeAddr("owner"),
|
|
81
|
+
trustedMessageSenders
|
|
82
|
+
);
|
|
83
|
+
|
|
43
84
|
(, bytes32 salt) = HooksDeployment.mineForCoinSalt(
|
|
44
85
|
address(this),
|
|
45
86
|
V4_POOL_MANAGER,
|
|
46
87
|
0x777777751622c0d3258f214F9DF38E35BF45baF3,
|
|
47
|
-
|
|
88
|
+
ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
|
|
48
89
|
hookUpgradeGate
|
|
49
90
|
);
|
|
50
91
|
IHooks hook = HooksDeployment.deployZoraV4CoinHook(
|
|
51
92
|
V4_POOL_MANAGER,
|
|
52
93
|
0x777777751622c0d3258f214F9DF38E35BF45baF3,
|
|
53
|
-
|
|
94
|
+
ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
|
|
54
95
|
hookUpgradeGate,
|
|
55
96
|
salt
|
|
56
97
|
);
|
|
@@ -68,16 +109,27 @@ contract HooksDeploymentTest is Test, ContractAddresses {
|
|
|
68
109
|
vm.createSelectFork("base", 31653138);
|
|
69
110
|
|
|
70
111
|
address[] memory trustedMessageSenders = new address[](0);
|
|
112
|
+
|
|
113
|
+
ITrustedMsgSenderProviderLookup localTrustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(
|
|
114
|
+
makeAddr("owner"),
|
|
115
|
+
trustedMessageSenders
|
|
116
|
+
);
|
|
117
|
+
|
|
71
118
|
(, bytes32 salt) = HooksDeployment.mineForCoinSalt(
|
|
72
119
|
address(this),
|
|
73
120
|
V4_POOL_MANAGER,
|
|
74
121
|
0x777777751622c0d3258f214F9DF38E35BF45baF3,
|
|
75
|
-
|
|
122
|
+
ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
|
|
76
123
|
hookUpgradeGate
|
|
77
124
|
);
|
|
78
125
|
|
|
79
126
|
IHooks hook = HooksDeployment.deployHookWithSalt(
|
|
80
|
-
HooksDeployment.makeHookCreationCode(
|
|
127
|
+
HooksDeployment.makeHookCreationCode(
|
|
128
|
+
V4_POOL_MANAGER,
|
|
129
|
+
0x777777751622c0d3258f214F9DF38E35BF45baF3,
|
|
130
|
+
ITrustedMsgSenderProviderLookup(address(localTrustedMsgSenderLookup)),
|
|
131
|
+
hookUpgradeGate
|
|
132
|
+
),
|
|
81
133
|
salt
|
|
82
134
|
);
|
|
83
135
|
|
|
@@ -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";
|
|
@@ -450,7 +452,8 @@ contract LiquidityMigrationTest is BaseTest {
|
|
|
450
452
|
coin.migrateLiquidity(newHook, "");
|
|
451
453
|
|
|
452
454
|
// Now fix the bug by etching fixed hook code onto the old hook address
|
|
453
|
-
|
|
455
|
+
ITrustedMsgSenderProviderLookup trustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
|
|
456
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, trustedMsgSenderLookup, upgradeGate);
|
|
454
457
|
|
|
455
458
|
(IHooks fixedHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
456
459
|
|
|
@@ -477,7 +480,8 @@ contract LiquidityMigrationTest is BaseTest {
|
|
|
477
480
|
assertEq(oldFee, 30000);
|
|
478
481
|
|
|
479
482
|
// Now fix the bug by etching fixed hook code onto the old hook address
|
|
480
|
-
|
|
483
|
+
ITrustedMsgSenderProviderLookup trustedMsgSenderLookup = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
|
|
484
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, trustedMsgSenderLookup, upgradeGate);
|
|
481
485
|
|
|
482
486
|
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
483
487
|
|
package/test/MultiOwnable.t.sol
CHANGED
|
@@ -5,7 +5,7 @@ import "./utils/BaseTest.sol";
|
|
|
5
5
|
|
|
6
6
|
contract MultiOwnableTest is BaseTest {
|
|
7
7
|
function setUp() public override {
|
|
8
|
-
super.
|
|
8
|
+
super.setUpNonForked();
|
|
9
9
|
|
|
10
10
|
_deployV4Coin();
|
|
11
11
|
}
|
|
@@ -135,7 +135,7 @@ contract MultiOwnableTest is BaseTest {
|
|
|
135
135
|
|
|
136
136
|
function test_revert_init_with_zero_owners() public {
|
|
137
137
|
address[] memory emptyOwners = new address[](0);
|
|
138
|
-
bytes memory poolConfig_ = _generatePoolConfig(address(
|
|
138
|
+
bytes memory poolConfig_ = _generatePoolConfig(address(0));
|
|
139
139
|
vm.expectRevert(MultiOwnable.OneOwnerRequired.selector);
|
|
140
140
|
factory.deploy(users.creator, emptyOwners, "https://test.com", "Test Token", "TEST", poolConfig_, users.platformReferrer, 0);
|
|
141
141
|
}
|
|
@@ -143,7 +143,7 @@ contract MultiOwnableTest is BaseTest {
|
|
|
143
143
|
function test_revert_init_with_zero_address() public {
|
|
144
144
|
address[] memory owners = new address[](1);
|
|
145
145
|
owners[0] = address(0);
|
|
146
|
-
bytes memory poolConfig_ = _generatePoolConfig(address(
|
|
146
|
+
bytes memory poolConfig_ = _generatePoolConfig(address(0));
|
|
147
147
|
vm.expectRevert(MultiOwnable.OwnerCannotBeAddressZero.selector);
|
|
148
148
|
factory.deploy(users.creator, owners, "https://test.com", "Test Token", "TEST", poolConfig_, users.platformReferrer, 0);
|
|
149
149
|
}
|
|
@@ -152,7 +152,7 @@ contract MultiOwnableTest is BaseTest {
|
|
|
152
152
|
address[] memory owners = new address[](2);
|
|
153
153
|
owners[0] = users.creator;
|
|
154
154
|
owners[1] = users.creator;
|
|
155
|
-
bytes memory poolConfig_ = _generatePoolConfig(address(
|
|
155
|
+
bytes memory poolConfig_ = _generatePoolConfig(address(0));
|
|
156
156
|
vm.expectRevert(MultiOwnable.AlreadyOwner.selector);
|
|
157
157
|
factory.deploy(users.creator, owners, "https://test.com", "Test Token", "TEST", poolConfig_, users.platformReferrer, 0);
|
|
158
158
|
}
|
|
@@ -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
|
+
}
|
package/test/Upgrades.t.sol
CHANGED
|
@@ -14,6 +14,7 @@ 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
16
|
import {ZoraV4CoinHook} from "../src/hooks/ZoraV4CoinHook.sol";
|
|
17
|
+
import {BuySupplyWithV4SwapHook} from "../src/hooks/deployment/BuySupplyWithV4SwapHook.sol";
|
|
17
18
|
import {console} from "forge-std/console.sol";
|
|
18
19
|
import {IDeployedCoinVersionLookup} from "../src/interfaces/IDeployedCoinVersionLookup.sol";
|
|
19
20
|
import {IHooksUpgradeGate} from "../src/interfaces/IHooksUpgradeGate.sol";
|
|
@@ -27,6 +28,8 @@ import {StateLibrary} from "@uniswap/v4-core/src/libraries/StateLibrary.sol";
|
|
|
27
28
|
import {IZoraV4CoinHook} from "../src/interfaces/IZoraV4CoinHook.sol";
|
|
28
29
|
import {PoolStateReader} from "../src/libs/PoolStateReader.sol";
|
|
29
30
|
import {LpPosition} from "../src/types/LpPosition.sol";
|
|
31
|
+
import {ITrustedMsgSenderProviderLookup} from "../src/interfaces/ITrustedMsgSenderProviderLookup.sol";
|
|
32
|
+
import {TrustedSenderTestHelper} from "./utils/TrustedSenderTestHelper.sol";
|
|
30
33
|
|
|
31
34
|
contract BadImpl {
|
|
32
35
|
function contractName() public pure returns (string memory) {
|
|
@@ -106,26 +109,34 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
106
109
|
|
|
107
110
|
uint128 amountIn = 1 ether;
|
|
108
111
|
|
|
109
|
-
address
|
|
110
|
-
|
|
111
|
-
// build weth to usdc swap
|
|
112
|
-
bytes memory call = abi.encodeWithSelector(
|
|
113
|
-
ISwapRouter.exactInputSingle.selector,
|
|
114
|
-
ISwapRouter.ExactInputSingleParams({
|
|
115
|
-
tokenIn: WETH_ADDRESS,
|
|
116
|
-
tokenOut: ZORA,
|
|
117
|
-
fee: 3000,
|
|
118
|
-
recipient: buySupplyWithSwapRouterHook,
|
|
119
|
-
amountIn: amountIn,
|
|
120
|
-
amountOutMinimum: 0,
|
|
121
|
-
sqrtPriceLimitX96: 0
|
|
122
|
-
})
|
|
123
|
-
);
|
|
112
|
+
address buySupplyWithV4SwapHook = deployment.buySupplyWithSwapRouterHook;
|
|
124
113
|
|
|
125
114
|
address buyRecipient = makeAddr("buyRecipient");
|
|
126
115
|
|
|
127
116
|
address trader = 0xC077e4cC02fa01A5b7fAca1acE9BBe9f5ac5Af9F;
|
|
128
117
|
|
|
118
|
+
// Create V3 path: ETH -> ZORA (using exact path from test)
|
|
119
|
+
bytes memory v3Route = abi.encodePacked(
|
|
120
|
+
WETH_ADDRESS, // WETH
|
|
121
|
+
uint24(3000), // fee
|
|
122
|
+
ZORA // ZORA
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// No V4 route needed since coin is backed by ZORA
|
|
126
|
+
PoolKey[] memory v4Route = new PoolKey[](0);
|
|
127
|
+
|
|
128
|
+
// Encode proper BuySupplyWithV4SwapHook data
|
|
129
|
+
BuySupplyWithV4SwapHook.InitialSupplyParams memory params = BuySupplyWithV4SwapHook.InitialSupplyParams({
|
|
130
|
+
buyRecipient: buyRecipient,
|
|
131
|
+
v3Route: v3Route,
|
|
132
|
+
v4Route: v4Route,
|
|
133
|
+
inputCurrency: address(0), // ETH
|
|
134
|
+
inputAmount: amountIn,
|
|
135
|
+
minAmountOut: 0
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
bytes memory hookData = abi.encode(params);
|
|
139
|
+
|
|
129
140
|
vm.startPrank(trader);
|
|
130
141
|
vm.deal(trader, amountIn);
|
|
131
142
|
|
|
@@ -137,8 +148,8 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
137
148
|
"TEST",
|
|
138
149
|
poolConfig,
|
|
139
150
|
users.platformReferrer,
|
|
140
|
-
|
|
141
|
-
|
|
151
|
+
buySupplyWithV4SwapHook,
|
|
152
|
+
hookData,
|
|
142
153
|
keccak256("test")
|
|
143
154
|
);
|
|
144
155
|
|
|
@@ -186,7 +197,9 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
186
197
|
|
|
187
198
|
uint256 amountIn = 0.000111 ether;
|
|
188
199
|
|
|
189
|
-
|
|
200
|
+
ITrustedMsgSenderProviderLookup trustedMsgSenderLookup2 = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
|
|
201
|
+
|
|
202
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, trustedMsgSenderLookup2, upgradeGate);
|
|
190
203
|
|
|
191
204
|
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
192
205
|
|
|
@@ -238,7 +251,9 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
238
251
|
|
|
239
252
|
address existingHook = address(creatorCoin.hooks());
|
|
240
253
|
|
|
241
|
-
|
|
254
|
+
ITrustedMsgSenderProviderLookup trustedMsgSenderLookup3 = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
|
|
255
|
+
|
|
256
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, trustedMsgSenderLookup3, upgradeGate);
|
|
242
257
|
|
|
243
258
|
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
244
259
|
|
|
@@ -272,19 +287,17 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
272
287
|
uint128[] memory afterLiquidity = getLiquidityForPositions(afterKey, afterPositions);
|
|
273
288
|
|
|
274
289
|
for (uint256 i = 0; i < beforeLiquidity.length; i++) {
|
|
275
|
-
|
|
276
|
-
if (i != beforeLiquidity.length - 1) {
|
|
277
|
-
assertApproxEqAbs(beforeLiquidity[i], afterLiquidity[i], 200);
|
|
278
|
-
}
|
|
290
|
+
assertApproxEqAbs(beforeLiquidity[i], afterLiquidity[i], 200);
|
|
279
291
|
}
|
|
280
292
|
|
|
281
293
|
uint160 afterPrice = PoolStateReader.getSqrtPriceX96(creatorCoin.getPoolKey(), poolManager);
|
|
282
294
|
|
|
283
295
|
assertEq(beforePrice, afterPrice);
|
|
284
296
|
|
|
285
|
-
//
|
|
286
|
-
|
|
287
|
-
assertApproxEqAbs(creatorCoin.getPoolKey().
|
|
297
|
+
// Small amounts of dust from rounding may remain in the hook as burned tokens
|
|
298
|
+
// This is expected and saves on code size by not minting them back into the pool
|
|
299
|
+
assertApproxEqAbs(creatorCoin.getPoolKey().currency0.balanceOf(address(newHook)), 0, 0.1 ether);
|
|
300
|
+
assertApproxEqAbs(creatorCoin.getPoolKey().currency1.balanceOf(address(newHook)), 0, 0.1 ether);
|
|
288
301
|
|
|
289
302
|
// now try to swap some currency for the creator coin - it should succeed
|
|
290
303
|
_swapSomeCurrencyForCoin(creatorCoin, zora, uint128(IERC20(zora).balanceOf(trader) / 2), trader);
|
|
@@ -306,7 +319,8 @@ contract UpgradesTest is BaseTest, CoinsDeployerBase {
|
|
|
306
319
|
// this swap should revert because the content coin is broken
|
|
307
320
|
_swapSomeCurrencyForCoinAndExpectRevert(ICoin(contentCoin), creatorCoin, uint128(amountIn), trader);
|
|
308
321
|
|
|
309
|
-
|
|
322
|
+
ITrustedMsgSenderProviderLookup trustedMsgSenderLookup2 = TrustedSenderTestHelper.deployTrustedMessageSender(makeAddr("owner"), new address[](0));
|
|
323
|
+
bytes memory creationCode = HooksDeployment.makeHookCreationCode(address(poolManager), coinVersionLookup, trustedMsgSenderLookup2, upgradeGate);
|
|
310
324
|
|
|
311
325
|
(IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
312
326
|
|
|
@@ -7,20 +7,28 @@ import {IZoraHookRegistry} from "../src/interfaces/IZoraHookRegistry.sol";
|
|
|
7
7
|
import {ZoraHookRegistry} from "../src/hook-registry/ZoraHookRegistry.sol";
|
|
8
8
|
|
|
9
9
|
contract MockHook {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
string private _version;
|
|
11
|
+
|
|
12
|
+
constructor(string memory version_) {
|
|
13
|
+
_version = version_;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function contractVersion() public view returns (string memory) {
|
|
17
|
+
return _version;
|
|
12
18
|
}
|
|
13
19
|
}
|
|
14
20
|
|
|
21
|
+
contract MockHookNoVersion {
|
|
22
|
+
// No contractVersion function
|
|
23
|
+
}
|
|
24
|
+
|
|
15
25
|
contract ZoraHookRegistryTest is Test {
|
|
16
|
-
uint256 internal forkId;
|
|
17
26
|
address internal owner;
|
|
18
27
|
|
|
19
28
|
ZoraHookRegistry internal zoraHookRegistry;
|
|
20
29
|
MockHook internal mockHook;
|
|
21
30
|
|
|
22
31
|
function setUp() public {
|
|
23
|
-
forkId = vm.createSelectFork("base", 34509280);
|
|
24
32
|
owner = makeAddr("owner");
|
|
25
33
|
|
|
26
34
|
address[] memory initialOwners = new address[](1);
|
|
@@ -29,7 +37,7 @@ contract ZoraHookRegistryTest is Test {
|
|
|
29
37
|
zoraHookRegistry = new ZoraHookRegistry();
|
|
30
38
|
zoraHookRegistry.initialize(initialOwners);
|
|
31
39
|
|
|
32
|
-
mockHook = new MockHook();
|
|
40
|
+
mockHook = new MockHook("0.0.0");
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
function test_register_hooks() public {
|
|
@@ -179,7 +187,8 @@ contract ZoraHookRegistryTest is Test {
|
|
|
179
187
|
address[] memory hooks = new address[](1);
|
|
180
188
|
string[] memory tags = new string[](1);
|
|
181
189
|
|
|
182
|
-
|
|
190
|
+
MockHook hookWithVersion = new MockHook("1.1.1");
|
|
191
|
+
hooks[0] = address(hookWithVersion);
|
|
183
192
|
tags[0] = "CONTENT";
|
|
184
193
|
|
|
185
194
|
vm.prank(owner);
|
|
@@ -192,7 +201,8 @@ contract ZoraHookRegistryTest is Test {
|
|
|
192
201
|
address[] memory hooks = new address[](1);
|
|
193
202
|
string[] memory tags = new string[](1);
|
|
194
203
|
|
|
195
|
-
|
|
204
|
+
MockHookNoVersion hookNoVersion = new MockHookNoVersion();
|
|
205
|
+
hooks[0] = address(hookNoVersion);
|
|
196
206
|
tags[0] = "CONTENT";
|
|
197
207
|
|
|
198
208
|
vm.prank(owner);
|
|
@@ -207,8 +217,8 @@ contract ZoraHookRegistryTest is Test {
|
|
|
207
217
|
|
|
208
218
|
function test_get_hook_addresses_multiple_and_remove_middle() public {
|
|
209
219
|
address a = address(mockHook);
|
|
210
|
-
address b = address(new MockHook());
|
|
211
|
-
address c = address(new MockHook());
|
|
220
|
+
address b = address(new MockHook("0.0.0"));
|
|
221
|
+
address c = address(new MockHook("0.0.0"));
|
|
212
222
|
|
|
213
223
|
address[] memory hooks = new address[](3);
|
|
214
224
|
string[] memory tags = new string[](3);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.13;
|
|
3
|
+
|
|
4
|
+
import {IAirlock} from "../../src/interfaces/IAirlock.sol";
|
|
5
|
+
|
|
6
|
+
/// @title MockAirlock
|
|
7
|
+
/// @notice Mock implementation of IAirlock for testing purposes
|
|
8
|
+
contract MockAirlock is IAirlock {
|
|
9
|
+
address private _owner;
|
|
10
|
+
|
|
11
|
+
constructor(address owner_) {
|
|
12
|
+
_owner = owner_;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function owner() external view override returns (address) {
|
|
16
|
+
return _owner;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function setOwner(address newOwner) external {
|
|
20
|
+
_owner = newOwner;
|
|
21
|
+
}
|
|
22
|
+
}
|