@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.
- package/.turbo/turbo-build$colon$js.log +119 -128
- package/CHANGELOG.md +30 -0
- package/abis/Address.json +0 -16
- package/abis/BuySupplyWithSwapRouterHook.json +0 -27
- package/abis/BuySupplyWithV4SwapHook.json +0 -32
- package/abis/Clones.json +1 -1
- package/abis/CoinDopplerMultiCurve.json +109 -0
- package/abis/Create2.json +0 -21
- package/abis/ERC1967Proxy.json +1 -1
- package/abis/ERC1967Utils.json +0 -45
- package/abis/{UpgradeCoinImpl.json → Errors.json} +14 -10
- package/abis/{MockERC20.json → IERC1363.json} +134 -104
- package/abis/IERC1967.json +47 -0
- package/abis/IERC20.json +0 -36
- package/abis/IProtocolRewards.json +0 -258
- package/abis/{Script.json → ISupportsLimitOrderFill.json} +2 -2
- package/abis/ITrustedMsgSenderProviderLookup.json +21 -0
- package/abis/IZoraLimitOrderBookCoinsInterface.json +67 -0
- package/abis/IZoraV4CoinHook.json +15 -0
- package/abis/ProxyShim.json +15 -16
- package/abis/SafeCast.json +51 -0
- package/abis/{AddressConstants.json → SafeCast160.json} +1 -1
- package/abis/Strings.json +10 -0
- package/abis/TrustedMsgSenderProviderLookup.json +215 -0
- package/abis/UUPSUpgradeable.json +1 -1
- package/abis/V3ToV4SwapLib.json +28 -0
- package/abis/ZoraFactory.json +1 -1
- package/abis/ZoraFactoryImpl.json +22 -6
- package/abis/ZoraV4CoinHook.json +41 -51
- package/dist/index.cjs +950 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +948 -41
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +1459 -76
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/foundry.toml +5 -1
- package/package/wagmiGenerated.ts +951 -44
- package/package.json +7 -7
- package/remappings.txt +2 -1
- package/src/ZoraFactoryImpl.sol +8 -0
- package/src/deployment/ForkedCoinsAddresses.sol +54 -0
- package/src/hooks/ZoraV4CoinHook.sol +92 -74
- package/src/hooks/deployment/BuySupplyWithV4SwapHook.sol +20 -142
- package/src/interfaces/ISupportsLimitOrderFill.sol +11 -0
- package/src/interfaces/ITrustedMsgSenderProviderLookup.sol +18 -0
- package/src/interfaces/IZoraLimitOrderBookCoinsInterface.sol +21 -0
- package/src/interfaces/IZoraV4CoinHook.sol +9 -0
- package/src/libs/CoinConstants.sol +6 -0
- package/src/libs/CoinDopplerMultiCurve.sol +1 -1
- package/src/libs/CoinRewardsV4.sol +0 -1
- package/src/libs/HooksDeployment.sol +25 -12
- package/src/libs/UniV4SwapHelper.sol +35 -0
- package/src/libs/V3ToV4SwapLib.sol +261 -0
- package/src/libs/V4Liquidity.sol +50 -6
- package/src/utils/TrustedMsgSenderProviderLookup.sol +73 -0
- package/src/version/ContractVersionBase.sol +1 -1
- package/test/BuySupplyWithV4SwapHook.t.sol +4 -3
- package/test/Coin.t.sol +7 -1
- package/test/CoinUniV4.t.sol +2 -1
- package/test/ContentCoinRewards.t.sol +5 -1
- package/test/CreatorCoin.t.sol +3 -1
- package/test/CreatorCoinRewards.t.sol +7 -1
- package/test/Factory.t.sol +20 -7
- package/test/HooksDeployment.t.sol +73 -8
- package/test/LiquidityMigration.t.sol +55 -43
- package/test/MultiOwnable.t.sol +2 -1
- package/test/TrustedMsgSenderProviderLookup.t.sol +112 -0
- package/test/Upgrades.t.sol +112 -78
- package/test/V4Liquidity.t.sol +1 -1
- package/test/mocks/MockSwapRouter.sol +33 -0
- package/test/mocks/MockZoraLimitOrderBook.sol +14 -0
- package/test/utils/BaseTest.sol +17 -425
- package/test/utils/FeeEstimatorHook.sol +8 -2
- package/test/utils/TrustedSenderTestHelper.sol +18 -0
- package/test/utils/V4TestSetup.sol +595 -0
- package/wagmi.config.ts +1 -1
- package/abis/BaseTest.json +0 -718
- package/abis/DeterministicDeployerAndCaller.json +0 -315
- package/abis/DeterministicUUPSProxyDeployer.json +0 -167
- package/abis/EIP712.json +0 -67
- package/abis/ERC20.json +0 -310
- package/abis/FeeEstimatorHook.json +0 -1915
- package/abis/IERC721.json +0 -287
- package/abis/IERC721Enumerable.json +0 -343
- package/abis/IERC721Metadata.json +0 -332
- package/abis/IERC721TokenReceiver.json +0 -36
- package/abis/IImmutableCreate2Factory.json +0 -93
- package/abis/IMulticall3.json +0 -440
- package/abis/ISafe.json +0 -15
- package/abis/ISymbol.json +0 -15
- package/abis/IUniswapV4Router04.json +0 -484
- package/abis/IUniversalRouter.json +0 -61
- package/abis/IV4Quoter.json +0 -310
- package/abis/ImmutableCreate2FactoryUtils.json +0 -15
- package/abis/LibString.json +0 -7
- package/abis/Math.json +0 -7
- package/abis/MockAirlock.json +0 -39
- package/abis/MockERC721.json +0 -350
- package/abis/ProtocolRewards.json +0 -494
- package/abis/ShortStrings.json +0 -18
- package/abis/SimpleERC20.json +0 -326
- package/abis/StdAssertions.json +0 -379
- package/abis/StdInvariant.json +0 -180
- package/abis/Test.json +0 -570
- package/abis/VmContractHelper239.json +0 -233
- package/abis/stdError.json +0 -119
- package/abis/stdStorageSafe.json +0 -52
- package/addresses/8453.json +0 -13
- package/addresses/84532.json +0 -10
- package/deterministicConfig/deployerAndCaller.json +0 -5
- package/deterministicConfig/zoraFactory.json +0 -8
- package/script/Deploy.s.sol +0 -23
- package/script/DeployAutoSwapper.s.sol +0 -30
- package/script/DeployDevFactory.s.sol +0 -21
- package/script/DeployPostDeploymentHooks.s.sol +0 -20
- package/script/DeployUpgradeGate.s.sol +0 -21
- package/script/GenerateDeterministicParams.s.sol +0 -43
- package/script/PrintRegisterUpgradePath.s.sol +0 -28
- package/script/PrintUpgradeCommand.s.sol +0 -13
- package/script/TestBackingCoinSwap.s.sol +0 -144
- package/script/TestV4Swap.s.sol +0 -133
- package/script/UpgradeCoinImpl.sol +0 -23
- package/script/UpgradeFactoryImpl.s.sol +0 -28
- package/script/UpgradeHooks.s.sol +0 -23
- package/src/deployment/CoinsDeployerBase.sol +0 -276
- /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(
|
|
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(
|
|
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(
|
|
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;
|
package/test/CoinUniV4.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 {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;
|
package/test/CreatorCoin.t.sol
CHANGED
|
@@ -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");
|
package/test/Factory.t.sol
CHANGED
|
@@ -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
|
|
23
|
-
|
|
24
|
-
|
|
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,
|
|
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,
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
-
|
|
471
|
-
|
|
481
|
+
// // jacob creator coin
|
|
482
|
+
// BaseCoin coin = BaseCoin(0x9B13358E3a023507E7046c18f508A958cDA75f54);
|
|
472
483
|
|
|
473
|
-
|
|
484
|
+
// address upgradeGate = 0xD88f6BdD765313CaFA5888C177c325E2C3AbF2D2; // live upgrade gate
|
|
474
485
|
|
|
475
|
-
|
|
486
|
+
// uint24 oldFee = coin.getPoolKey().fee;
|
|
476
487
|
|
|
477
|
-
|
|
488
|
+
// assertEq(oldFee, 30000);
|
|
478
489
|
|
|
479
|
-
|
|
480
|
-
|
|
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
|
-
|
|
494
|
+
// (IHooks newHook, ) = HooksDeployment.deployHookWithExistingOrNewSalt(address(this), creationCode, bytes32(0));
|
|
483
495
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
496
|
+
// // Register upgrade path
|
|
497
|
+
// address[] memory baseImpls = new address[](1);
|
|
498
|
+
// baseImpls[0] = address(coin.hooks());
|
|
487
499
|
|
|
488
|
-
|
|
489
|
-
|
|
500
|
+
// vm.prank(Ownable(upgradeGate).owner());
|
|
501
|
+
// IHooksUpgradeGate(upgradeGate).registerUpgradePath(baseImpls, address(newHook));
|
|
490
502
|
|
|
491
|
-
|
|
492
|
-
|
|
503
|
+
// // Get coin owner
|
|
504
|
+
// address coinOwner = MultiOwnable(address(coin)).owners()[0];
|
|
493
505
|
|
|
494
|
-
|
|
495
|
-
|
|
506
|
+
// vm.prank(coinOwner);
|
|
507
|
+
// coin.migrateLiquidity(address(newHook), "");
|
|
496
508
|
|
|
497
|
-
|
|
498
|
-
|
|
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
|
-
|
|
512
|
+
// address currencyAddress = address(coin.currency());
|
|
501
513
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
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
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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
|
-
|
|
515
|
-
|
|
516
|
-
|
|
526
|
+
// // migrate liquidity again to the same new hook as before
|
|
527
|
+
// vm.prank(coinOwner);
|
|
528
|
+
// coin.migrateLiquidity(address(newHook), "");
|
|
517
529
|
|
|
518
|
-
|
|
519
|
-
|
|
530
|
+
// // the new fee should be the correct current fee
|
|
531
|
+
// assertEq(coin.getPoolKey().fee, CoinConstants.LP_FEE_V4);
|
|
520
532
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
}
|
|
533
|
+
// // now test swapping the migrated liquidity - it should work
|
|
534
|
+
// _swapSomeCurrencyForCoin(coin, coin.currency(), 1 ether, trader);
|
|
535
|
+
// }
|
|
524
536
|
}
|
package/test/MultiOwnable.t.sol
CHANGED
|
@@ -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
|
+
}
|