@zoralabs/limit-orders 0.2.1 → 0.2.4
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/.abi-stability +70 -0
- package/.turbo/turbo-build$colon$js.log +50 -51
- package/CHANGELOG.md +35 -0
- package/abis/ISetLimitOrderConfig.json +27 -0
- package/abis/{SimpleAccessManaged.json → Ownable.json} +29 -10
- package/abis/Ownable2Step.json +115 -0
- package/abis/PermittedCallers.json +181 -0
- package/abis/SwapWithLimitOrders.json +116 -3
- package/abis/ZoraLimitOrderBook.json +159 -35
- package/cache/solidity-files-cache.json +1 -1
- package/dist/index.cjs +191 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +191 -27
- package/dist/index.js.map +1 -1
- package/dist/wagmiGenerated.d.ts +217 -32
- package/dist/wagmiGenerated.d.ts.map +1 -1
- package/out/BalanceDelta.sol/BalanceDeltaLibrary.json +1 -1
- package/out/BeforeSwapDelta.sol/BeforeSwapDeltaLibrary.json +1 -1
- package/out/BitMath.sol/BitMath.json +1 -1
- package/out/BytesLib.sol/BytesLib.json +1 -1
- package/out/CoinCommon.sol/CoinCommon.json +1 -1
- package/out/CoinConfigurationVersions.sol/CoinConfigurationVersions.json +1 -1
- package/out/CoinConstants.sol/CoinConstants.json +1 -1
- package/out/Context.sol/Context.json +1 -1
- package/out/Currency.sol/CurrencyLibrary.json +1 -1
- package/out/CurrencyReserves.sol/CurrencyReserves.json +1 -1
- package/out/CustomRevert.sol/CustomRevert.json +1 -1
- package/out/DopplerMath.sol/DopplerMath.json +1 -1
- package/out/FixedPoint128.sol/FixedPoint128.json +1 -1
- package/out/FixedPoint96.sol/FixedPoint96.json +1 -1
- package/out/FullMath.sol/FullMath.json +1 -1
- package/out/IAllowanceTransfer.sol/IAllowanceTransfer.json +1 -1
- package/out/ICoin.sol/ICoin.json +1 -1
- package/out/ICoin.sol/IHasCoinType.json +1 -1
- package/out/ICoin.sol/IHasPoolKey.json +1 -1
- package/out/ICoin.sol/IHasSwapPath.json +1 -1
- package/out/ICoin.sol/IHasTotalSupplyForPositions.json +1 -1
- package/out/IDeployedCoinVersionLookup.sol/IDeployedCoinVersionLookup.json +1 -1
- package/out/IDopplerErrors.sol/IDopplerErrors.json +1 -1
- package/out/IEIP712.sol/IEIP712.json +1 -1
- package/out/IERC1363.sol/IERC1363.json +1 -1
- package/out/IERC165.sol/IERC165.json +1 -1
- package/out/IERC20.sol/IERC20.json +1 -1
- package/out/IERC20Minimal.sol/IERC20Minimal.json +1 -1
- package/out/IERC6909Claims.sol/IERC6909Claims.json +1 -1
- package/out/IERC7572.sol/IERC7572.json +1 -1
- package/out/IExtsload.sol/IExtsload.json +1 -1
- package/out/IExttload.sol/IExttload.json +1 -1
- package/out/IHasRewardsRecipients.sol/IHasRewardsRecipients.json +1 -1
- package/out/IHooks.sol/IHooks.json +1 -1
- package/out/IMsgSender.sol/IMsgSender.json +1 -1
- package/out/IPoolManager.sol/IPoolManager.json +1 -1
- package/out/IProtocolFees.sol/IProtocolFees.json +1 -1
- package/out/ISetLimitOrderConfig.sol/ISetLimitOrderConfig.json +1 -0
- package/out/ISupportsLimitOrderFill.sol/ISupportsLimitOrderFill.json +1 -1
- package/out/ISwapPathRouter.sol/ISwapPathRouter.json +1 -1
- package/out/ISwapRouter.sol/ISwapRouter.json +1 -1
- package/out/IUniswapV3SwapCallback.sol/IUniswapV3SwapCallback.json +1 -1
- package/out/IUpgradeableV4Hook.sol/IUpgradeableDestinationV4Hook.json +1 -1
- package/out/IUpgradeableV4Hook.sol/IUpgradeableDestinationV4HookWithUpdateableFee.json +1 -1
- package/out/IUpgradeableV4Hook.sol/IUpgradeableV4Hook.json +1 -1
- package/out/IWETH.sol/IWETH.json +1 -1
- package/out/IZoraHookRegistry.sol/IZoraHookRegistry.json +1 -1
- package/out/IZoraLimitOrderBook.sol/IZoraLimitOrderBook.json +1 -1
- package/out/IZoraLimitOrderBookCoinsInterface.sol/IZoraLimitOrderBookCoinsInterface.json +1 -1
- package/out/IZoraV4CoinHook.sol/IZoraV4CoinHook.json +1 -1
- package/out/LimitOrderBitmap.sol/LimitOrderBitmap.json +1 -1
- package/out/LimitOrderCommon.sol/LimitOrderCommon.json +1 -1
- package/out/LimitOrderCreate.sol/LimitOrderCreate.json +1 -1
- package/out/LimitOrderFill.sol/LimitOrderFill.json +1 -1
- package/out/LimitOrderLiquidity.sol/LimitOrderLiquidity.json +1 -1
- package/out/LimitOrderViews.sol/LimitOrderViews.json +1 -1
- package/out/LimitOrderWithdraw.sol/LimitOrderWithdraw.json +1 -1
- package/out/LiquidityAmounts.sol/LiquidityAmounts.json +1 -1
- package/out/LiquidityMath.sol/LiquidityMath.json +1 -1
- package/out/Lock.sol/Lock.json +1 -1
- package/out/NonzeroDeltaCount.sol/NonzeroDeltaCount.json +1 -1
- package/out/Ownable.sol/Ownable.json +1 -0
- package/out/Ownable2Step.sol/Ownable2Step.json +1 -0
- package/out/Path.sol/Path.json +1 -1
- package/out/PathKey.sol/PathKeyLibrary.json +1 -1
- package/out/PermittedCallers.sol/PermittedCallers.json +1 -0
- package/out/PoolId.sol/PoolIdLibrary.json +1 -1
- package/out/Position.sol/Position.json +1 -1
- package/out/SafeCast.sol/SafeCast.json +1 -1
- package/out/SafeCast160.sol/SafeCast160.json +1 -1
- package/out/SafeERC20.sol/SafeERC20.json +1 -1
- package/out/SqrtPriceMath.sol/SqrtPriceMath.json +1 -1
- package/out/StateLibrary.sol/StateLibrary.json +1 -1
- package/out/SwapLimitOrders.sol/SwapLimitOrders.json +1 -1
- package/out/SwapWithLimitOrders.sol/SwapWithLimitOrders.json +1 -1
- package/out/TickBitmap.sol/TickBitmap.json +1 -1
- package/out/TickMath.sol/TickMath.json +1 -1
- package/out/TransientSlot.sol/TransientSlot.json +1 -1
- package/out/TransientStateLibrary.sol/TransientStateLibrary.json +1 -1
- package/out/UniV4SwapToCurrency.sol/UniV4SwapToCurrency.json +1 -1
- package/out/UnsafeMath.sol/UnsafeMath.json +1 -1
- package/out/V3ToV4SwapLib.sol/V3ToV4SwapLib.json +1 -1
- package/out/ZoraLimitOrderBook.sol/ZoraLimitOrderBook.json +1 -1
- package/out/build-info/68b2e124c4a02a45.json +1 -0
- package/out/uniswap/BitMath.sol/BitMath.json +1 -1
- package/out/uniswap/CustomRevert.sol/CustomRevert.json +1 -1
- package/out/uniswap/FullMath.sol/FullMath.json +1 -1
- package/out/uniswap/SafeCast.sol/SafeCast.json +1 -1
- package/out/uniswap/TickMath.sol/TickMath.json +1 -1
- package/package/wagmiGenerated.ts +190 -26
- package/package.json +4 -2
- package/src/IZoraLimitOrderBook.sol +3 -5
- package/src/ZoraLimitOrderBook.sol +14 -45
- package/src/access/PermittedCallers.sol +45 -0
- package/src/libs/LimitOrderBitmap.sol +0 -1
- package/src/libs/LimitOrderCommon.sol +14 -0
- package/src/libs/LimitOrderCreate.sol +6 -0
- package/src/libs/LimitOrderFill.sol +3 -20
- package/src/libs/LimitOrderLiquidity.sol +61 -38
- package/src/libs/LimitOrderWithdraw.sol +2 -6
- package/src/libs/SwapLimitOrders.sol +13 -7
- package/src/router/ISetLimitOrderConfig.sol +12 -0
- package/src/router/SwapWithLimitOrders.sol +9 -9
- package/test/LimitOrderAccessControl.t.sol +173 -156
- package/test/LimitOrderFill.t.sol +0 -5
- package/test/LimitOrderLiquidityPayouts.t.sol +14 -14
- package/test/SwapWithLimitOrders.t.sol +0 -2
- package/test/SwapWithLimitOrdersRouter.t.sol +4 -2
- package/test/gas/LimitOrderFillGas.t.sol +0 -7
- package/test/gas/LimitOrderSwapGas.t.sol +0 -6
- package/test/unit/LimitOrderCreateUnit.t.sol +17 -17
- package/test/unit/SwapLimitOrdersUnit.t.sol +49 -88
- package/test/unit/SwapLimitOrdersValidation.t.sol +11 -19
- package/test/utils/BaseTest.sol +8 -17
- package/test/utils/TestableZoraLimitOrderBook.sol +2 -2
- package/abis/IAuthority.json +0 -31
- package/abis/SimpleAccessManager.json +0 -351
- package/out/IAuthority.sol/IAuthority.json +0 -1
- package/out/SimpleAccessManaged.sol/SimpleAccessManaged.json +0 -1
- package/out/SimpleAccessManager.sol/SimpleAccessManager.json +0 -1
- package/out/build-info/876cc09bc44cc8a7.json +0 -1
- package/src/access/SimpleAccessManaged.sol +0 -76
- package/src/access/SimpleAccessManager.sol +0 -268
- package/test/SimpleAccessManager.t.sol +0 -420
|
@@ -2,25 +2,28 @@
|
|
|
2
2
|
pragma solidity ^0.8.28;
|
|
3
3
|
|
|
4
4
|
import {BaseTest} from "./utils/BaseTest.sol";
|
|
5
|
-
import {
|
|
6
|
-
import {SimpleAccessManaged} from "../src/access/SimpleAccessManaged.sol";
|
|
5
|
+
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
7
6
|
import {IZoraLimitOrderBook} from "../src/IZoraLimitOrderBook.sol";
|
|
7
|
+
import {PermittedCallers} from "../src/access/PermittedCallers.sol";
|
|
8
8
|
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
|
|
9
9
|
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
|
|
10
10
|
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
11
11
|
import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
|
|
12
|
+
import {SwapWithLimitOrders} from "../src/router/SwapWithLimitOrders.sol";
|
|
13
|
+
import {LimitOrderConfig} from "../src/libs/SwapLimitOrders.sol";
|
|
12
14
|
|
|
13
15
|
contract LimitOrderAccessControlTest is BaseTest {
|
|
14
|
-
uint64 public constant CREATOR_ROLE = 1;
|
|
15
16
|
address public unauthorizedUser;
|
|
16
|
-
address public
|
|
17
|
+
address public authorizedCaller;
|
|
18
|
+
address public newOwner;
|
|
17
19
|
|
|
18
20
|
function setUp() public override {
|
|
19
21
|
super.setUpNonForked();
|
|
20
22
|
|
|
21
23
|
// Set up test users
|
|
22
24
|
unauthorizedUser = makeAddr("unauthorizedUser");
|
|
23
|
-
|
|
25
|
+
authorizedCaller = makeAddr("authorizedCaller");
|
|
26
|
+
newOwner = makeAddr("newOwner");
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
function _prepareOrder(
|
|
@@ -69,120 +72,146 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
69
72
|
zoraHookRegistry.registerHooks(hooks, tags);
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
function
|
|
75
|
+
function _setPublicAccess(bool isPublic) internal {
|
|
76
|
+
address[] memory callers = new address[](1);
|
|
77
|
+
callers[0] = address(0); // PUBLIC_ACCESS sentinel
|
|
78
|
+
bool[] memory permitted = new bool[](1);
|
|
79
|
+
permitted[0] = isPublic;
|
|
80
|
+
limitOrderBook.setPermittedCallers(callers, permitted);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Test: create() works in public mode (default)
|
|
84
|
+
function test_create_publicMode() public {
|
|
73
85
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
74
86
|
|
|
87
|
+
// Verify any address is permitted by default (public mode)
|
|
88
|
+
assertTrue(limitOrderBook.isPermittedCaller(unauthorizedUser), "any address should be permitted in public mode");
|
|
89
|
+
|
|
90
|
+
// Anyone can create orders in public mode
|
|
75
91
|
(bool isCurrency0, address orderCoin, uint256[] memory orderSizes, int24[] memory orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
76
92
|
_createOrder(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser, orderCoin);
|
|
77
93
|
}
|
|
78
94
|
|
|
79
|
-
|
|
95
|
+
// Test: setPermittedCallers can toggle public access control via address(0)
|
|
96
|
+
function test_setPermittedCallers_togglesPublicAccessControl() public {
|
|
80
97
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
81
98
|
|
|
82
|
-
// Initially anyone can create
|
|
99
|
+
// Initially public - anyone can create
|
|
100
|
+
assertTrue(limitOrderBook.isPermittedCaller(unauthorizedUser));
|
|
83
101
|
(bool isCurrency0, address orderCoin, uint256[] memory orderSizes, int24[] memory orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
84
102
|
_createOrder(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser, orderCoin);
|
|
85
103
|
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// Grant role to authorized router
|
|
90
|
-
accessManager.grantRole(CREATOR_ROLE, authorizedRouter, 0);
|
|
91
|
-
|
|
92
|
-
// Switch function to require CREATOR_ROLE
|
|
93
|
-
bytes4[] memory selectors = new bytes4[](1);
|
|
94
|
-
selectors[0] = IZoraLimitOrderBook.create.selector;
|
|
95
|
-
accessManager.setTargetFunctionRole(address(limitOrderBook), selectors, CREATOR_ROLE);
|
|
104
|
+
// Owner sets to permissioned mode by disabling address(0)
|
|
105
|
+
_setPublicAccess(false);
|
|
106
|
+
assertFalse(limitOrderBook.isPermittedCaller(unauthorizedUser));
|
|
96
107
|
|
|
97
108
|
// Now unauthorized user should fail
|
|
98
109
|
(isCurrency0, orderCoin, orderSizes, orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
99
|
-
vm.expectRevert(
|
|
110
|
+
vm.expectRevert(PermittedCallers.CallerNotPermitted.selector);
|
|
100
111
|
limitOrderBook.create{value: orderCoin == address(0) ? 1 ether : 0}(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser);
|
|
101
112
|
vm.stopPrank();
|
|
102
113
|
|
|
103
|
-
//
|
|
104
|
-
(
|
|
105
|
-
|
|
114
|
+
// Owner sets back to public mode
|
|
115
|
+
_setPublicAccess(true);
|
|
116
|
+
assertTrue(limitOrderBook.isPermittedCaller(unauthorizedUser));
|
|
106
117
|
|
|
107
|
-
//
|
|
118
|
+
// Now anyone can create again
|
|
119
|
+
(isCurrency0, orderCoin, orderSizes, orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
120
|
+
_createOrder(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser, orderCoin);
|
|
108
121
|
}
|
|
109
122
|
|
|
110
|
-
|
|
123
|
+
// Test: unauthorized user cannot create in permissioned mode
|
|
124
|
+
function test_create_permissionedMode_unauthorizedFails() public {
|
|
111
125
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
112
126
|
|
|
113
|
-
// Set
|
|
114
|
-
|
|
115
|
-
accessManager.grantRole(CREATOR_ROLE, authorizedRouter, 0);
|
|
116
|
-
|
|
117
|
-
bytes4[] memory selectors = new bytes4[](1);
|
|
118
|
-
selectors[0] = IZoraLimitOrderBook.create.selector;
|
|
119
|
-
accessManager.setTargetFunctionRole(address(limitOrderBook), selectors, CREATOR_ROLE);
|
|
127
|
+
// Set to permissioned mode
|
|
128
|
+
_setPublicAccess(false);
|
|
120
129
|
|
|
121
130
|
// Unauthorized user tries to create
|
|
122
131
|
(bool isCurrency0, address orderCoin, uint256[] memory orderSizes, int24[] memory orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
123
|
-
vm.expectRevert(
|
|
132
|
+
vm.expectRevert(PermittedCallers.CallerNotPermitted.selector);
|
|
124
133
|
limitOrderBook.create{value: orderCoin == address(0) ? 1 ether : 0}(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser);
|
|
125
134
|
vm.stopPrank();
|
|
126
135
|
}
|
|
127
136
|
|
|
128
|
-
|
|
137
|
+
// Test: setPermittedCallers grants and revokes access
|
|
138
|
+
function test_setPermittedCallers_grantsAndRevokesAccess() public {
|
|
129
139
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
130
140
|
|
|
131
|
-
// Set
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
bytes4[] memory selectors = new bytes4[](1);
|
|
135
|
-
selectors[0] = IZoraLimitOrderBook.create.selector;
|
|
136
|
-
accessManager.setTargetFunctionRole(address(limitOrderBook), selectors, CREATOR_ROLE);
|
|
141
|
+
// Set to permissioned mode
|
|
142
|
+
_setPublicAccess(false);
|
|
137
143
|
|
|
138
144
|
// Initially unauthorized user cannot create
|
|
139
145
|
(bool isCurrency0, address orderCoin, uint256[] memory orderSizes, int24[] memory orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
140
|
-
vm.expectRevert(
|
|
146
|
+
vm.expectRevert(PermittedCallers.CallerNotPermitted.selector);
|
|
141
147
|
limitOrderBook.create{value: orderCoin == address(0) ? 1 ether : 0}(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser);
|
|
142
148
|
vm.stopPrank();
|
|
143
149
|
|
|
144
|
-
// Grant
|
|
145
|
-
|
|
150
|
+
// Grant access to user
|
|
151
|
+
address[] memory callers = new address[](1);
|
|
152
|
+
callers[0] = unauthorizedUser;
|
|
153
|
+
bool[] memory permitted = new bool[](1);
|
|
154
|
+
permitted[0] = true;
|
|
155
|
+
limitOrderBook.setPermittedCallers(callers, permitted);
|
|
156
|
+
|
|
157
|
+
assertTrue(limitOrderBook.isPermittedCaller(unauthorizedUser), "user should be permitted");
|
|
146
158
|
|
|
147
159
|
// Now user can create
|
|
148
160
|
(isCurrency0, orderCoin, orderSizes, orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
149
161
|
_createOrder(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser, orderCoin);
|
|
150
162
|
|
|
151
|
-
// Revoke
|
|
152
|
-
|
|
163
|
+
// Revoke access
|
|
164
|
+
permitted[0] = false;
|
|
165
|
+
limitOrderBook.setPermittedCallers(callers, permitted);
|
|
166
|
+
|
|
167
|
+
assertFalse(limitOrderBook.isPermittedCaller(unauthorizedUser), "user should not be permitted");
|
|
153
168
|
|
|
154
169
|
// Now user cannot create again
|
|
155
170
|
(isCurrency0, orderCoin, orderSizes, orderTicks) = _prepareOrder(unauthorizedUser, key);
|
|
156
|
-
vm.expectRevert(
|
|
171
|
+
vm.expectRevert(PermittedCallers.CallerNotPermitted.selector);
|
|
157
172
|
limitOrderBook.create{value: orderCoin == address(0) ? 1 ether : 0}(key, isCurrency0, orderSizes, orderTicks, unauthorizedUser);
|
|
158
173
|
vm.stopPrank();
|
|
159
174
|
}
|
|
160
175
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
(
|
|
183
|
-
|
|
176
|
+
// Test: setPermittedCallers works with multiple addresses
|
|
177
|
+
function test_setPermittedCallers_batchUpdate() public {
|
|
178
|
+
address caller1 = makeAddr("caller1");
|
|
179
|
+
address caller2 = makeAddr("caller2");
|
|
180
|
+
address caller3 = makeAddr("caller3");
|
|
181
|
+
|
|
182
|
+
_setPublicAccess(false);
|
|
183
|
+
|
|
184
|
+
// Grant access to multiple callers
|
|
185
|
+
address[] memory callers = new address[](3);
|
|
186
|
+
callers[0] = caller1;
|
|
187
|
+
callers[1] = caller2;
|
|
188
|
+
callers[2] = caller3;
|
|
189
|
+
// set public to false
|
|
190
|
+
bool[] memory permitted = new bool[](3);
|
|
191
|
+
permitted[0] = true;
|
|
192
|
+
permitted[1] = true;
|
|
193
|
+
permitted[2] = true;
|
|
194
|
+
|
|
195
|
+
limitOrderBook.setPermittedCallers(callers, permitted);
|
|
196
|
+
|
|
197
|
+
assertTrue(limitOrderBook.isPermittedCaller(caller1));
|
|
198
|
+
assertTrue(limitOrderBook.isPermittedCaller(caller2));
|
|
199
|
+
assertTrue(limitOrderBook.isPermittedCaller(caller3));
|
|
200
|
+
|
|
201
|
+
// Revoke access from caller2
|
|
202
|
+
address[] memory revokeList = new address[](1);
|
|
203
|
+
revokeList[0] = caller2;
|
|
204
|
+
bool[] memory revokePermitted = new bool[](1);
|
|
205
|
+
revokePermitted[0] = false;
|
|
206
|
+
|
|
207
|
+
limitOrderBook.setPermittedCallers(revokeList, revokePermitted);
|
|
208
|
+
|
|
209
|
+
assertTrue(limitOrderBook.isPermittedCaller(caller1));
|
|
210
|
+
assertFalse(limitOrderBook.isPermittedCaller(caller2));
|
|
211
|
+
assertTrue(limitOrderBook.isPermittedCaller(caller3));
|
|
184
212
|
}
|
|
185
213
|
|
|
214
|
+
// Test: non-hook cannot fill while unlocked
|
|
186
215
|
function test_nonHookCannotFillWhileUnlocked() public {
|
|
187
216
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
188
217
|
|
|
@@ -194,6 +223,7 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
194
223
|
caller.attemptUnlockedFill(key, false, -type(int24).max, type(int24).max, 1, address(0));
|
|
195
224
|
}
|
|
196
225
|
|
|
226
|
+
// Test: registered hook can fill while unlocked
|
|
197
227
|
function test_fillRegisteredHookCanFillWhileUnlocked() public {
|
|
198
228
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
199
229
|
|
|
@@ -217,6 +247,7 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
217
247
|
assertEq(_makerBalance(users.seller, created[0].coin), 0, "maker balance should be zero");
|
|
218
248
|
}
|
|
219
249
|
|
|
250
|
+
// Test: unregistered hook cannot fill while unlocked
|
|
220
251
|
function test_fillUnregisteredHookCannotFillWhileUnlocked() public {
|
|
221
252
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
222
253
|
UnlockedFillCaller caller = new UnlockedFillCaller(address(limitOrderBook), address(poolManager));
|
|
@@ -225,6 +256,7 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
225
256
|
caller.attemptUnlockedFill(key, true, -type(int24).max, type(int24).max, 5, address(0));
|
|
226
257
|
}
|
|
227
258
|
|
|
259
|
+
// Test: fill maxFillCount defaults to storage
|
|
228
260
|
function test_fill_MaxFillCountDefaultsToStorage() public {
|
|
229
261
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
230
262
|
|
|
@@ -237,7 +269,6 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
237
269
|
_movePriceBeyondTicksWithAutoFillDisabled(created);
|
|
238
270
|
|
|
239
271
|
uint256 previousMax = limitOrderBook.getMaxFillCount();
|
|
240
|
-
vm.prank(users.factoryOwner);
|
|
241
272
|
limitOrderBook.setMaxFillCount(2);
|
|
242
273
|
(int24 startTick, int24 endTick) = _tickWindow(created, key);
|
|
243
274
|
|
|
@@ -246,10 +277,10 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
246
277
|
FilledOrderLog[] memory fills = _decodeFilledLogs(vm.getRecordedLogs());
|
|
247
278
|
assertEq(fills.length, 2, "should use stored maxFillCount when input is zero");
|
|
248
279
|
|
|
249
|
-
vm.prank(users.factoryOwner);
|
|
250
280
|
limitOrderBook.setMaxFillCount(previousMax);
|
|
251
281
|
}
|
|
252
282
|
|
|
283
|
+
// Test: fillBatch ignores empty order arrays
|
|
253
284
|
function test_fillBatchIgnoresEmptyOrderArrays() public {
|
|
254
285
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
255
286
|
|
|
@@ -288,138 +319,128 @@ contract LimitOrderAccessControlTest is BaseTest {
|
|
|
288
319
|
assertApproxEqAbs(makerBalanceBefore - makerBalanceAfter, expectedDelta, 3, "unexpected maker balance delta");
|
|
289
320
|
}
|
|
290
321
|
|
|
322
|
+
// Test: unlockCallback reverts for non-poolManager
|
|
291
323
|
function test_unlockCallbackRevertsForNonPoolManager() public {
|
|
292
324
|
vm.expectRevert(IZoraLimitOrderBook.NotPoolManager.selector);
|
|
293
325
|
limitOrderBook.unlockCallback(bytes(""));
|
|
294
326
|
}
|
|
295
327
|
|
|
328
|
+
// Test: receive reverts for non-poolManager
|
|
296
329
|
function test_receiveRevertsForNonPoolManager() public {
|
|
297
330
|
vm.deal(address(this), 1 ether);
|
|
298
331
|
vm.expectRevert(IZoraLimitOrderBook.NotPoolManager.selector);
|
|
299
332
|
payable(address(limitOrderBook)).transfer(1 wei);
|
|
300
333
|
}
|
|
301
334
|
|
|
302
|
-
|
|
335
|
+
// Test: setMaxFillCount - owner can set
|
|
336
|
+
function test_setMaxFillCount_ownerCanSet() public {
|
|
303
337
|
// Initially max fill count should be 50 (set in BaseTest)
|
|
304
338
|
assertEq(limitOrderBook.getMaxFillCount(), 50);
|
|
305
339
|
|
|
306
|
-
//
|
|
307
|
-
// Any user should be able to set it
|
|
308
|
-
vm.prank(unauthorizedUser);
|
|
340
|
+
// Owner (this contract) should be able to set it
|
|
309
341
|
limitOrderBook.setMaxFillCount(20);
|
|
310
342
|
|
|
311
343
|
assertEq(limitOrderBook.getMaxFillCount(), 20);
|
|
312
344
|
}
|
|
313
345
|
|
|
346
|
+
// Test: setMaxFillCount - unauthorized user cannot set
|
|
314
347
|
function test_setMaxFillCount_unauthorizedUserCannotSet() public {
|
|
315
|
-
uint64 MAX_FILL_COUNT_ROLE = 2;
|
|
316
|
-
|
|
317
|
-
// Set up permissioned mode for setMaxFillCount
|
|
318
|
-
accessManager.labelRole(MAX_FILL_COUNT_ROLE, "MAX_FILL_COUNT_SETTER");
|
|
319
|
-
accessManager.grantRole(MAX_FILL_COUNT_ROLE, authorizedRouter, 0);
|
|
320
|
-
|
|
321
|
-
bytes4[] memory selectors = new bytes4[](1);
|
|
322
|
-
selectors[0] = IZoraLimitOrderBook.setMaxFillCount.selector;
|
|
323
|
-
accessManager.setTargetFunctionRole(address(limitOrderBook), selectors, MAX_FILL_COUNT_ROLE);
|
|
324
|
-
|
|
325
348
|
// Unauthorized user tries to set max fill count
|
|
326
349
|
vm.prank(unauthorizedUser);
|
|
327
|
-
vm.expectRevert(
|
|
350
|
+
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorizedUser));
|
|
328
351
|
limitOrderBook.setMaxFillCount(20);
|
|
329
352
|
|
|
330
353
|
// Verify value hasn't changed (still 50 from BaseTest)
|
|
331
354
|
assertEq(limitOrderBook.getMaxFillCount(), 50);
|
|
332
355
|
}
|
|
333
356
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
bytes4[] memory selectors = new bytes4[](1);
|
|
342
|
-
selectors[0] = IZoraLimitOrderBook.setMaxFillCount.selector;
|
|
343
|
-
accessManager.setTargetFunctionRole(address(limitOrderBook), selectors, MAX_FILL_COUNT_ROLE);
|
|
357
|
+
// Test: setPermittedCallers - owner can set
|
|
358
|
+
function test_setPermittedCallers_ownerCanSet() public {
|
|
359
|
+
address[] memory callers = new address[](1);
|
|
360
|
+
callers[0] = authorizedCaller;
|
|
361
|
+
bool[] memory permitted = new bool[](1);
|
|
362
|
+
permitted[0] = true;
|
|
344
363
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
limitOrderBook.setMaxFillCount(25);
|
|
348
|
-
|
|
349
|
-
assertEq(limitOrderBook.getMaxFillCount(), 25);
|
|
364
|
+
limitOrderBook.setPermittedCallers(callers, permitted);
|
|
365
|
+
assertTrue(limitOrderBook.isPermittedCaller(authorizedCaller));
|
|
350
366
|
}
|
|
351
367
|
|
|
352
|
-
|
|
353
|
-
|
|
368
|
+
// Test: setPermittedCallers - unauthorized user cannot set
|
|
369
|
+
function test_setPermittedCallers_unauthorizedUserCannotSet() public {
|
|
370
|
+
address[] memory callers = new address[](0);
|
|
371
|
+
bool[] memory permitted = new bool[](0);
|
|
354
372
|
|
|
355
|
-
|
|
356
|
-
|
|
373
|
+
vm.prank(unauthorizedUser);
|
|
374
|
+
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorizedUser));
|
|
375
|
+
limitOrderBook.setPermittedCallers(callers, permitted);
|
|
376
|
+
}
|
|
357
377
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
378
|
+
// Test: setLimitOrderConfig - owner can set
|
|
379
|
+
function test_setLimitOrderConfig_ownerCanSet() public {
|
|
380
|
+
// Owner (this contract) should be able to set limit order config
|
|
381
|
+
uint256[] memory multiples = new uint256[](2);
|
|
382
|
+
multiples[0] = 2e18; // 2x
|
|
383
|
+
multiples[1] = 3e18; // 3x
|
|
361
384
|
|
|
362
|
-
|
|
363
|
-
|
|
385
|
+
uint256[] memory percentages = new uint256[](2);
|
|
386
|
+
percentages[0] = 5000; // 50%
|
|
387
|
+
percentages[1] = 5000; // 50%
|
|
364
388
|
|
|
365
|
-
|
|
366
|
-
limitOrderBook.setMaxFillCount(30);
|
|
389
|
+
LimitOrderConfig memory config = LimitOrderConfig({multiples: multiples, percentages: percentages});
|
|
367
390
|
|
|
368
|
-
|
|
391
|
+
swapWithLimitOrders.setLimitOrderConfig(config);
|
|
369
392
|
}
|
|
370
393
|
|
|
371
|
-
|
|
372
|
-
|
|
394
|
+
// Test: setLimitOrderConfig - unauthorized user cannot set
|
|
395
|
+
function test_setLimitOrderConfig_unauthorizedUserCannotSet() public {
|
|
396
|
+
uint256[] memory multiples = new uint256[](2);
|
|
397
|
+
multiples[0] = 2e18;
|
|
398
|
+
multiples[1] = 3e18;
|
|
373
399
|
|
|
374
|
-
|
|
375
|
-
|
|
400
|
+
uint256[] memory percentages = new uint256[](2);
|
|
401
|
+
percentages[0] = 5000;
|
|
402
|
+
percentages[1] = 5000;
|
|
376
403
|
|
|
377
|
-
|
|
378
|
-
selectors[0] = IZoraLimitOrderBook.setMaxFillCount.selector;
|
|
379
|
-
accessManager.setTargetFunctionRole(address(limitOrderBook), selectors, MAX_FILL_COUNT_ROLE);
|
|
404
|
+
LimitOrderConfig memory config = LimitOrderConfig({multiples: multiples, percentages: percentages});
|
|
380
405
|
|
|
381
|
-
//
|
|
406
|
+
// Unauthorized user tries to set config
|
|
382
407
|
vm.prank(unauthorizedUser);
|
|
383
|
-
vm.expectRevert(
|
|
384
|
-
|
|
408
|
+
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, unauthorizedUser));
|
|
409
|
+
swapWithLimitOrders.setLimitOrderConfig(config);
|
|
410
|
+
}
|
|
385
411
|
|
|
386
|
-
|
|
387
|
-
|
|
412
|
+
// Test: ownership transfer (two-step process)
|
|
413
|
+
function test_ownershipTransfer() public {
|
|
414
|
+
// Initial owner is this contract
|
|
415
|
+
assertEq(limitOrderBook.owner(), address(this));
|
|
388
416
|
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
limitOrderBook.setMaxFillCount(15);
|
|
392
|
-
assertEq(limitOrderBook.getMaxFillCount(), 15);
|
|
417
|
+
// Step 1: Current owner proposes transfer
|
|
418
|
+
limitOrderBook.transferOwnership(newOwner);
|
|
393
419
|
|
|
394
|
-
//
|
|
395
|
-
|
|
420
|
+
// Ownership hasn't changed yet
|
|
421
|
+
assertEq(limitOrderBook.owner(), address(this));
|
|
422
|
+
assertEq(limitOrderBook.pendingOwner(), newOwner);
|
|
396
423
|
|
|
397
|
-
//
|
|
398
|
-
vm.prank(
|
|
399
|
-
vm.expectRevert(
|
|
400
|
-
limitOrderBook.setMaxFillCount(
|
|
424
|
+
// New owner cannot perform owner actions yet
|
|
425
|
+
vm.prank(newOwner);
|
|
426
|
+
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, newOwner));
|
|
427
|
+
limitOrderBook.setMaxFillCount(100);
|
|
401
428
|
|
|
402
|
-
//
|
|
403
|
-
|
|
404
|
-
|
|
429
|
+
// Step 2: New owner accepts transfer
|
|
430
|
+
vm.prank(newOwner);
|
|
431
|
+
limitOrderBook.acceptOwnership();
|
|
405
432
|
|
|
406
|
-
|
|
407
|
-
|
|
433
|
+
// Now ownership has transferred
|
|
434
|
+
assertEq(limitOrderBook.owner(), newOwner);
|
|
408
435
|
|
|
409
|
-
|
|
410
|
-
vm.
|
|
411
|
-
limitOrderBook.
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
function test_setAuthority_revertsForNonContractAddress() public {
|
|
415
|
-
// Deploy a simple test contract with test contract as authority
|
|
416
|
-
AuthorityTester tester = new AuthorityTester(address(this));
|
|
417
|
-
|
|
418
|
-
address eoaAddress = makeAddr("eoa");
|
|
436
|
+
// New owner can perform owner actions
|
|
437
|
+
vm.prank(newOwner);
|
|
438
|
+
limitOrderBook.setMaxFillCount(100);
|
|
439
|
+
assertEq(limitOrderBook.getMaxFillCount(), 100);
|
|
419
440
|
|
|
420
|
-
//
|
|
421
|
-
vm.expectRevert(abi.encodeWithSelector(
|
|
422
|
-
|
|
441
|
+
// Old owner cannot perform owner actions
|
|
442
|
+
vm.expectRevert(abi.encodeWithSelector(Ownable.OwnableUnauthorizedAccount.selector, address(this)));
|
|
443
|
+
limitOrderBook.setMaxFillCount(50);
|
|
423
444
|
}
|
|
424
445
|
}
|
|
425
446
|
|
|
@@ -455,7 +476,3 @@ contract UnlockedFillCaller {
|
|
|
455
476
|
return bytes("");
|
|
456
477
|
}
|
|
457
478
|
}
|
|
458
|
-
|
|
459
|
-
contract AuthorityTester is SimpleAccessManaged {
|
|
460
|
-
constructor(address initialAuthority) SimpleAccessManaged(initialAuthority) {}
|
|
461
|
-
}
|
|
@@ -202,7 +202,6 @@ contract LimitOrderFillTest is BaseTest {
|
|
|
202
202
|
bool isCurrency0 = Currency.unwrap(key.currency0) == address(creatorCoin);
|
|
203
203
|
address orderCoin = _orderCoin(key, isCurrency0);
|
|
204
204
|
|
|
205
|
-
vm.prank(users.factoryOwner);
|
|
206
205
|
limitOrderBook.setMaxFillCount(2);
|
|
207
206
|
|
|
208
207
|
(uint256[] memory orderSizes, int24[] memory orderTicks) = _buildDeterministicOrders(key, isCurrency0, 3, 20e18);
|
|
@@ -336,7 +335,6 @@ contract LimitOrderFillTest is BaseTest {
|
|
|
336
335
|
|
|
337
336
|
// 3. Now DISABLE hook auto-fills
|
|
338
337
|
uint256 originalMaxFillCount = limitOrderBook.getMaxFillCount();
|
|
339
|
-
vm.prank(users.factoryOwner);
|
|
340
338
|
limitOrderBook.setMaxFillCount(0);
|
|
341
339
|
|
|
342
340
|
// 4. Move price past the order WITHOUT triggering hook fills
|
|
@@ -345,7 +343,6 @@ contract LimitOrderFillTest is BaseTest {
|
|
|
345
343
|
_swapSomeCurrencyForCoin(ICoin(address(creatorCoin)), address(zoraToken), swapAmount, swapper);
|
|
346
344
|
|
|
347
345
|
// 5. Restore original maxFillCount
|
|
348
|
-
vm.prank(users.factoryOwner);
|
|
349
346
|
limitOrderBook.setMaxFillCount(originalMaxFillCount);
|
|
350
347
|
|
|
351
348
|
// 6. Verify order exists and check epoch
|
|
@@ -775,7 +772,6 @@ contract LimitOrderFillTest is BaseTest {
|
|
|
775
772
|
address orderCoin = _orderCoin(key, isCurrency0);
|
|
776
773
|
|
|
777
774
|
// Set max fill count to 2 so we can verify default is used
|
|
778
|
-
vm.prank(users.factoryOwner);
|
|
779
775
|
limitOrderBook.setMaxFillCount(2);
|
|
780
776
|
|
|
781
777
|
// Create 5 orders that can be filled
|
|
@@ -821,7 +817,6 @@ contract LimitOrderFillTest is BaseTest {
|
|
|
821
817
|
address orderCoin = _orderCoin(key, isCurrency0);
|
|
822
818
|
|
|
823
819
|
// Set max fill count to 2
|
|
824
|
-
vm.prank(users.factoryOwner);
|
|
825
820
|
limitOrderBook.setMaxFillCount(2);
|
|
826
821
|
|
|
827
822
|
// Create 5 fillable orders
|
|
@@ -46,7 +46,7 @@ contract MockPoolManager {
|
|
|
46
46
|
swapDelta = toBalanceDelta(amount0, amount1);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function modifyLiquidity(PoolKey memory, ModifyLiquidityParams memory, bytes calldata) external returns (BalanceDelta, BalanceDelta) {
|
|
49
|
+
function modifyLiquidity(PoolKey memory, ModifyLiquidityParams memory, bytes calldata) external view returns (BalanceDelta, BalanceDelta) {
|
|
50
50
|
return (liquidityDelta, feeDelta);
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -270,18 +270,25 @@ contract LimitOrderLiquidityPayoutsTest is Test {
|
|
|
270
270
|
assertEq(Currency.unwrap(poolManager.lastTakeCurrency()), address(currency1Token));
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
/// @notice Test that dual positive deltas are consolidated into single payout currency
|
|
273
274
|
function test_burnAndRefundPaysBothCurrenciesWhenPositive() public {
|
|
275
|
+
// isCurrency0 = true (default), so refund should be in currency0
|
|
274
276
|
poolManager.setModifyLiquidityResponse(int128(10), int128(20), 0, 0);
|
|
277
|
+
|
|
278
|
+
// Simulate swap: 20 of currency1 → 18 of currency0
|
|
279
|
+
poolManager.setSwapResponse(int128(18), 0);
|
|
280
|
+
|
|
275
281
|
deal(address(currency0Token), address(poolManager), 100e18);
|
|
276
282
|
deal(address(currency1Token), address(poolManager), 100e18);
|
|
277
283
|
address recipient = makeAddr("dual-recipient");
|
|
278
284
|
|
|
279
285
|
uint128 amountOut = harness.burnAndRefund(poolManager, poolKey, ORDER_ID, recipient);
|
|
280
286
|
|
|
281
|
-
|
|
282
|
-
assertEq(
|
|
283
|
-
assertEq(
|
|
284
|
-
assertEq(
|
|
287
|
+
// Verify consolidated payout: 10 (original) + 18 (swapped) = 28
|
|
288
|
+
assertEq(amountOut, 28, "amountOut should be combined total");
|
|
289
|
+
assertEq(currency0Token.balanceOf(recipient), 28, "recipient receives combined in currency0");
|
|
290
|
+
assertEq(currency1Token.balanceOf(recipient), 0, "recipient should NOT receive currency1");
|
|
291
|
+
assertEq(poolManager.swapCalls(), 1, "swap should consolidate currencies");
|
|
285
292
|
}
|
|
286
293
|
|
|
287
294
|
function test_burnAndPayoutWithoutReferralRoutesAllProceeds() public {
|
|
@@ -340,7 +347,7 @@ contract LimitOrderLiquidityPayoutsTest is Test {
|
|
|
340
347
|
uint256 makerCurrency0Before = currency0Token.balanceOf(maker);
|
|
341
348
|
uint256 makerCurrency1Before = currency1Token.balanceOf(maker);
|
|
342
349
|
|
|
343
|
-
|
|
350
|
+
harness.burnAndPayout(poolManager, poolKey, ORDER_ID, address(0), address(currency0Token), versionLookup);
|
|
344
351
|
|
|
345
352
|
// With the fix: only currency1 is paid out (NOT currency0)
|
|
346
353
|
assertEq(currency0Token.balanceOf(maker), makerCurrency0Before, "maker should NOT receive currency0");
|
|
@@ -503,14 +510,7 @@ contract LimitOrderLiquidityPayoutsTest is Test {
|
|
|
503
510
|
uint256 ref0Before = currency0Token.balanceOf(referral);
|
|
504
511
|
uint256 ref1Before = currency1Token.balanceOf(referral);
|
|
505
512
|
|
|
506
|
-
(Currency makerCoinOut,
|
|
507
|
-
poolManager,
|
|
508
|
-
poolKey,
|
|
509
|
-
ORDER_ID,
|
|
510
|
-
referral,
|
|
511
|
-
address(0),
|
|
512
|
-
versionLookup
|
|
513
|
-
);
|
|
513
|
+
(Currency makerCoinOut, , ) = harness.burnAndPayout(poolManager, poolKey, ORDER_ID, referral, address(0), versionLookup);
|
|
514
514
|
|
|
515
515
|
// Verify maker receives only currency1
|
|
516
516
|
assertEq(Currency.unwrap(makerCoinOut), address(currency1Token), "maker payout should be currency1");
|
|
@@ -11,8 +11,6 @@ import {Vm} from "forge-std/Vm.sol";
|
|
|
11
11
|
contract SwapWithLimitOrdersTest is BaseTest {
|
|
12
12
|
function test_autosellCreatesOrdersForSmallPurchases() public {
|
|
13
13
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
14
|
-
bool isCurrency0 = Currency.unwrap(key.currency0) == address(creatorCoin);
|
|
15
|
-
address orderCoin = _orderCoin(key, isCurrency0);
|
|
16
14
|
|
|
17
15
|
vm.recordLogs();
|
|
18
16
|
_executeSingleHopSwapWithLimitOrders(users.buyer, key, 1e13, _defaultMultiples(), _defaultPercentages());
|
|
@@ -306,11 +306,15 @@ contract SwapWithLimitOrdersTestNonForked is SwapWithLimitOrdersTestBase {
|
|
|
306
306
|
// TODO: Requires controlling tick movement during swap
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
/// forge-config: default.isolate = true
|
|
309
310
|
function test_orderFilling_invertedDirection() public {
|
|
310
311
|
// This test verifies the fix for audit issue #16
|
|
311
312
|
// https://github.com/kadenzipfel/zora-autosell-audit/issues/16
|
|
312
313
|
// The router should pass isCoinCurrency0 (not !isCoinCurrency0) to _fillOrders
|
|
313
314
|
|
|
315
|
+
// Skip past launch fee period to test normal swap behavior
|
|
316
|
+
vm.warp(block.timestamp + 1 days);
|
|
317
|
+
|
|
314
318
|
PoolKey memory key = creatorCoin.getPoolKey();
|
|
315
319
|
|
|
316
320
|
// 1. Create first buyer's orders using swapWithLimitOrders
|
|
@@ -548,7 +552,6 @@ contract SwapWithLimitOrdersTestNonForked is SwapWithLimitOrdersTestBase {
|
|
|
548
552
|
LimitOrderConfig memory limitOrderConfig = _prepareLimitOrderParams(users.buyer, _defaultMultiples(), _defaultPercentages());
|
|
549
553
|
|
|
550
554
|
uint256 previousMax = limitOrderBook.getMaxFillCount();
|
|
551
|
-
vm.prank(users.factoryOwner);
|
|
552
555
|
limitOrderBook.setMaxFillCount(0);
|
|
553
556
|
|
|
554
557
|
bytes memory callData = abi.encodeWithSelector(IERC165.supportsInterface.selector, type(ISupportsLimitOrderFill).interfaceId);
|
|
@@ -571,7 +574,6 @@ contract SwapWithLimitOrdersTestNonForked is SwapWithLimitOrdersTestBase {
|
|
|
571
574
|
assertEq(ordersFilled, 0, "max fill count zero should short-circuit fills");
|
|
572
575
|
|
|
573
576
|
vm.clearMockedCalls();
|
|
574
|
-
vm.prank(users.factoryOwner);
|
|
575
577
|
limitOrderBook.setMaxFillCount(previousMax);
|
|
576
578
|
}
|
|
577
579
|
|