@zoralabs/limit-orders 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/.turbo/turbo-build$colon$js.log +50 -51
  2. package/CHANGELOG.md +12 -0
  3. package/abis/ISetLimitOrderConfig.json +27 -0
  4. package/abis/{SimpleAccessManaged.json → Ownable.json} +29 -10
  5. package/abis/Ownable2Step.json +115 -0
  6. package/abis/PermittedCallers.json +181 -0
  7. package/abis/SwapWithLimitOrders.json +116 -3
  8. package/abis/ZoraLimitOrderBook.json +159 -35
  9. package/cache/solidity-files-cache.json +1 -1
  10. package/dist/index.cjs +191 -27
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.js +191 -27
  13. package/dist/index.js.map +1 -1
  14. package/dist/wagmiGenerated.d.ts +217 -32
  15. package/dist/wagmiGenerated.d.ts.map +1 -1
  16. package/out/BalanceDelta.sol/BalanceDeltaLibrary.json +1 -1
  17. package/out/BeforeSwapDelta.sol/BeforeSwapDeltaLibrary.json +1 -1
  18. package/out/BitMath.sol/BitMath.json +1 -1
  19. package/out/BytesLib.sol/BytesLib.json +1 -1
  20. package/out/CoinCommon.sol/CoinCommon.json +1 -1
  21. package/out/CoinConfigurationVersions.sol/CoinConfigurationVersions.json +1 -1
  22. package/out/CoinConstants.sol/CoinConstants.json +1 -1
  23. package/out/Context.sol/Context.json +1 -1
  24. package/out/Currency.sol/CurrencyLibrary.json +1 -1
  25. package/out/CurrencyReserves.sol/CurrencyReserves.json +1 -1
  26. package/out/CustomRevert.sol/CustomRevert.json +1 -1
  27. package/out/DopplerMath.sol/DopplerMath.json +1 -1
  28. package/out/FixedPoint128.sol/FixedPoint128.json +1 -1
  29. package/out/FixedPoint96.sol/FixedPoint96.json +1 -1
  30. package/out/FullMath.sol/FullMath.json +1 -1
  31. package/out/IAllowanceTransfer.sol/IAllowanceTransfer.json +1 -1
  32. package/out/ICoin.sol/ICoin.json +1 -1
  33. package/out/ICoin.sol/IHasCoinType.json +1 -1
  34. package/out/ICoin.sol/IHasPoolKey.json +1 -1
  35. package/out/ICoin.sol/IHasSwapPath.json +1 -1
  36. package/out/ICoin.sol/IHasTotalSupplyForPositions.json +1 -1
  37. package/out/IDeployedCoinVersionLookup.sol/IDeployedCoinVersionLookup.json +1 -1
  38. package/out/IDopplerErrors.sol/IDopplerErrors.json +1 -1
  39. package/out/IEIP712.sol/IEIP712.json +1 -1
  40. package/out/IERC1363.sol/IERC1363.json +1 -1
  41. package/out/IERC165.sol/IERC165.json +1 -1
  42. package/out/IERC20.sol/IERC20.json +1 -1
  43. package/out/IERC20Minimal.sol/IERC20Minimal.json +1 -1
  44. package/out/IERC6909Claims.sol/IERC6909Claims.json +1 -1
  45. package/out/IERC7572.sol/IERC7572.json +1 -1
  46. package/out/IExtsload.sol/IExtsload.json +1 -1
  47. package/out/IExttload.sol/IExttload.json +1 -1
  48. package/out/IHasRewardsRecipients.sol/IHasRewardsRecipients.json +1 -1
  49. package/out/IHooks.sol/IHooks.json +1 -1
  50. package/out/IMsgSender.sol/IMsgSender.json +1 -1
  51. package/out/IPoolManager.sol/IPoolManager.json +1 -1
  52. package/out/IProtocolFees.sol/IProtocolFees.json +1 -1
  53. package/out/ISetLimitOrderConfig.sol/ISetLimitOrderConfig.json +1 -0
  54. package/out/ISupportsLimitOrderFill.sol/ISupportsLimitOrderFill.json +1 -1
  55. package/out/ISwapPathRouter.sol/ISwapPathRouter.json +1 -1
  56. package/out/ISwapRouter.sol/ISwapRouter.json +1 -1
  57. package/out/IUniswapV3SwapCallback.sol/IUniswapV3SwapCallback.json +1 -1
  58. package/out/IUpgradeableV4Hook.sol/IUpgradeableDestinationV4Hook.json +1 -1
  59. package/out/IUpgradeableV4Hook.sol/IUpgradeableDestinationV4HookWithUpdateableFee.json +1 -1
  60. package/out/IUpgradeableV4Hook.sol/IUpgradeableV4Hook.json +1 -1
  61. package/out/IWETH.sol/IWETH.json +1 -1
  62. package/out/IZoraHookRegistry.sol/IZoraHookRegistry.json +1 -1
  63. package/out/IZoraLimitOrderBook.sol/IZoraLimitOrderBook.json +1 -1
  64. package/out/IZoraLimitOrderBookCoinsInterface.sol/IZoraLimitOrderBookCoinsInterface.json +1 -1
  65. package/out/IZoraV4CoinHook.sol/IZoraV4CoinHook.json +1 -1
  66. package/out/LimitOrderCommon.sol/LimitOrderCommon.json +1 -1
  67. package/out/LimitOrderCreate.sol/LimitOrderCreate.json +1 -1
  68. package/out/LimitOrderFill.sol/LimitOrderFill.json +1 -1
  69. package/out/LimitOrderViews.sol/LimitOrderViews.json +1 -1
  70. package/out/LimitOrderWithdraw.sol/LimitOrderWithdraw.json +1 -1
  71. package/out/LiquidityAmounts.sol/LiquidityAmounts.json +1 -1
  72. package/out/LiquidityMath.sol/LiquidityMath.json +1 -1
  73. package/out/Lock.sol/Lock.json +1 -1
  74. package/out/NonzeroDeltaCount.sol/NonzeroDeltaCount.json +1 -1
  75. package/out/Ownable.sol/Ownable.json +1 -0
  76. package/out/Ownable2Step.sol/Ownable2Step.json +1 -0
  77. package/out/Path.sol/Path.json +1 -1
  78. package/out/PathKey.sol/PathKeyLibrary.json +1 -1
  79. package/out/PermittedCallers.sol/PermittedCallers.json +1 -0
  80. package/out/PoolId.sol/PoolIdLibrary.json +1 -1
  81. package/out/Position.sol/Position.json +1 -1
  82. package/out/SafeCast.sol/SafeCast.json +1 -1
  83. package/out/SafeCast160.sol/SafeCast160.json +1 -1
  84. package/out/SafeERC20.sol/SafeERC20.json +1 -1
  85. package/out/SqrtPriceMath.sol/SqrtPriceMath.json +1 -1
  86. package/out/StateLibrary.sol/StateLibrary.json +1 -1
  87. package/out/SwapWithLimitOrders.sol/SwapWithLimitOrders.json +1 -1
  88. package/out/TickBitmap.sol/TickBitmap.json +1 -1
  89. package/out/TickMath.sol/TickMath.json +1 -1
  90. package/out/TransientSlot.sol/TransientSlot.json +1 -1
  91. package/out/TransientStateLibrary.sol/TransientStateLibrary.json +1 -1
  92. package/out/UniV4SwapToCurrency.sol/UniV4SwapToCurrency.json +1 -1
  93. package/out/UnsafeMath.sol/UnsafeMath.json +1 -1
  94. package/out/V3ToV4SwapLib.sol/V3ToV4SwapLib.json +1 -1
  95. package/out/ZoraLimitOrderBook.sol/ZoraLimitOrderBook.json +1 -1
  96. package/out/build-info/37e0124d88d60569.json +1 -0
  97. package/out/uniswap/BitMath.sol/BitMath.json +1 -1
  98. package/out/uniswap/CustomRevert.sol/CustomRevert.json +1 -1
  99. package/out/uniswap/FullMath.sol/FullMath.json +1 -1
  100. package/out/uniswap/SafeCast.sol/SafeCast.json +1 -1
  101. package/out/uniswap/TickMath.sol/TickMath.json +1 -1
  102. package/package/wagmiGenerated.ts +190 -26
  103. package/package.json +1 -1
  104. package/src/IZoraLimitOrderBook.sol +3 -5
  105. package/src/ZoraLimitOrderBook.sol +14 -45
  106. package/src/access/PermittedCallers.sol +41 -0
  107. package/src/router/ISetLimitOrderConfig.sol +12 -0
  108. package/src/router/SwapWithLimitOrders.sol +8 -9
  109. package/test/LimitOrderAccessControl.t.sol +173 -156
  110. package/test/LimitOrderFill.t.sol +0 -5
  111. package/test/SwapWithLimitOrders.t.sol +0 -2
  112. package/test/SwapWithLimitOrdersRouter.t.sol +0 -2
  113. package/test/gas/LimitOrderFillGas.t.sol +0 -7
  114. package/test/gas/LimitOrderSwapGas.t.sol +0 -6
  115. package/test/unit/SwapLimitOrdersUnit.t.sol +4 -4
  116. package/test/unit/SwapLimitOrdersValidation.t.sol +8 -8
  117. package/test/utils/BaseTest.sol +7 -16
  118. package/test/utils/TestableZoraLimitOrderBook.sol +2 -2
  119. package/abis/IAuthority.json +0 -31
  120. package/abis/SimpleAccessManager.json +0 -351
  121. package/out/IAuthority.sol/IAuthority.json +0 -1
  122. package/out/SimpleAccessManaged.sol/SimpleAccessManaged.json +0 -1
  123. package/out/SimpleAccessManager.sol/SimpleAccessManager.json +0 -1
  124. package/out/build-info/876cc09bc44cc8a7.json +0 -1
  125. package/src/access/SimpleAccessManaged.sol +0 -76
  126. package/src/access/SimpleAccessManager.sol +0 -268
  127. package/test/SimpleAccessManager.t.sol +0 -420
@@ -10,7 +10,6 @@ pragma solidity ^0.8.28;
10
10
  import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
11
11
  import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
12
12
  import {TransientStateLibrary} from "@uniswap/v4-core/src/libraries/TransientStateLibrary.sol";
13
- import {SimpleAccessManaged} from "./access/SimpleAccessManaged.sol";
14
13
 
15
14
  import {IDeployedCoinVersionLookup} from "@zoralabs/coins/src/interfaces/IDeployedCoinVersionLookup.sol";
16
15
  import {IZoraHookRegistry} from "@zoralabs/coins/src/interfaces/IZoraHookRegistry.sol";
@@ -21,50 +20,35 @@ import {LimitOrderFill} from "./libs/LimitOrderFill.sol";
21
20
  import {LimitOrderWithdraw} from "./libs/LimitOrderWithdraw.sol";
22
21
  import {LimitOrderViews} from "./libs/LimitOrderViews.sol";
23
22
  import {LimitOrderTypes} from "./libs/LimitOrderTypes.sol";
23
+ import {PermittedCallers} from "./access/PermittedCallers.sol";
24
24
 
25
- contract ZoraLimitOrderBook is IZoraLimitOrderBook, SimpleAccessManaged {
25
+ contract ZoraLimitOrderBook is IZoraLimitOrderBook, PermittedCallers {
26
26
  IPoolManager public immutable poolManager;
27
27
  IDeployedCoinVersionLookup public immutable zoraCoinVersionLookup;
28
28
  IZoraHookRegistry public immutable zoraHookRegistry;
29
29
  address public immutable weth;
30
30
 
31
- constructor(
32
- address poolManager_,
33
- address zoraCoinVersionLookup_,
34
- address zoraHookRegistry_,
35
- address authority_,
36
- address weth_
37
- ) SimpleAccessManaged(authority_) {
31
+ constructor(address poolManager_, address zoraCoinVersionLookup_, address zoraHookRegistry_, address owner_, address weth_) PermittedCallers(owner_) {
32
+ require(poolManager_ != address(0), AddressZero());
33
+ require(zoraCoinVersionLookup_ != address(0), AddressZero());
34
+ require(zoraHookRegistry_ != address(0), AddressZero());
35
+ require(weth_ != address(0), AddressZero());
36
+
38
37
  poolManager = IPoolManager(poolManager_);
39
38
  zoraCoinVersionLookup = IDeployedCoinVersionLookup(zoraCoinVersionLookup_);
40
39
  zoraHookRegistry = IZoraHookRegistry(zoraHookRegistry_);
41
- if (weth_ == address(0)) {
42
- revert AddressZero();
43
- }
44
40
  weth = weth_;
45
41
  }
46
42
 
47
- function tickQueueBalance(bytes32 poolKeyHash, address coin, int24 tick) internal view returns (uint256) {
48
- return LimitOrderStorage.layout().tickQueues[poolKeyHash][coin][tick].balance;
49
- }
50
-
51
43
  /// @inheritdoc IZoraLimitOrderBook
52
44
  function balanceOf(address maker, address coin) external view override returns (uint256) {
53
45
  return LimitOrderStorage.layout().makerBalances[maker][coin];
54
46
  }
55
47
 
56
- function getOrder(bytes32 id) internal view returns (LimitOrderTypes.LimitOrder memory) {
57
- return LimitOrderStorage.layout().limitOrders[id];
58
- }
59
-
60
48
  function getTickQueue(bytes32 poolKeyHash, address coin, int24 tick) internal view returns (LimitOrderTypes.Queue memory) {
61
49
  return LimitOrderStorage.layout().tickQueues[poolKeyHash][coin][tick];
62
50
  }
63
51
 
64
- function getPoolKey(bytes32 poolKeyHash) internal view returns (PoolKey memory) {
65
- return LimitOrderStorage.layout().poolKeys[poolKeyHash];
66
- }
67
-
68
52
  function getPoolEpoch(bytes32 poolKeyHash) internal view returns (uint256) {
69
53
  return LimitOrderStorage.layout().poolEpochs[poolKeyHash];
70
54
  }
@@ -73,10 +57,6 @@ contract ZoraLimitOrderBook is IZoraLimitOrderBook, SimpleAccessManaged {
73
57
  return LimitOrderStorage.layout().makerNonces[maker];
74
58
  }
75
59
 
76
- function getOrderId(bytes32 poolKeyHash, address coin, int24 tick, address maker, uint256 nonce) internal pure returns (bytes32) {
77
- return keccak256(abi.encode(poolKeyHash, coin, tick, maker, nonce));
78
- }
79
-
80
60
  /// @inheritdoc IZoraLimitOrderBook
81
61
  function create(
82
62
  PoolKey memory key,
@@ -84,8 +64,7 @@ contract ZoraLimitOrderBook is IZoraLimitOrderBook, SimpleAccessManaged {
84
64
  uint256[] memory orderSizes,
85
65
  int24[] memory orderTicks,
86
66
  address maker
87
- ) external payable override returns (bytes32[] memory) {
88
- _checkCanCall(this.create.selector);
67
+ ) external payable override onlyPermitted returns (bytes32[] memory) {
89
68
  return LimitOrderCreate.create(LimitOrderStorage.layout(), poolManager, key, isCurrency0, orderSizes, orderTicks, maker);
90
69
  }
91
70
 
@@ -152,8 +131,10 @@ contract ZoraLimitOrderBook is IZoraLimitOrderBook, SimpleAccessManaged {
152
131
 
153
132
  /// @inheritdoc IZoraLimitOrderBook
154
133
  function withdraw(bytes32[] calldata orderIds, address coin, uint256 minAmountOut, address recipient) external override {
155
- bytes32[] memory orderIdsCopy = orderIds;
156
- _unlock(CallbackId.WITHDRAW_ORDERS, _encodeWithdrawOrders(msg.sender, orderIdsCopy, coin, minAmountOut, recipient));
134
+ _unlock(
135
+ CallbackId.WITHDRAW_ORDERS,
136
+ abi.encode(WithdrawOrdersCallbackData({maker: msg.sender, orderIds: orderIds, coin: coin, minAmountOut: minAmountOut, recipient: recipient}))
137
+ );
157
138
  }
158
139
 
159
140
  /// @notice Processes pool-manager unlock callbacks and routes them to the correct handler.
@@ -184,9 +165,7 @@ contract ZoraLimitOrderBook is IZoraLimitOrderBook, SimpleAccessManaged {
184
165
  return LimitOrderStorage.layout().maxFillCount;
185
166
  }
186
167
 
187
- function setMaxFillCount(uint256 maxFillCount) external {
188
- _checkCanCall(this.setMaxFillCount.selector);
189
-
168
+ function setMaxFillCount(uint256 maxFillCount) external onlyOwner {
190
169
  LimitOrderStorage.layout().maxFillCount = maxFillCount;
191
170
  }
192
171
 
@@ -218,16 +197,6 @@ contract ZoraLimitOrderBook is IZoraLimitOrderBook, SimpleAccessManaged {
218
197
  data.orderIds = orderIds;
219
198
  }
220
199
 
221
- function _encodeWithdrawOrders(
222
- address maker,
223
- bytes32[] memory orderIds,
224
- address coin,
225
- uint256 minAmountOut,
226
- address recipient
227
- ) private pure returns (bytes memory) {
228
- return abi.encode(WithdrawOrdersCallbackData({maker: maker, orderIds: orderIds, coin: coin, minAmountOut: minAmountOut, recipient: recipient}));
229
- }
230
-
231
200
  function _unlock(CallbackId callbackId, bytes memory payload) private {
232
201
  poolManager.unlock(abi.encode(callbackId, payload));
233
202
  }
@@ -0,0 +1,41 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
5
+ import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
6
+
7
+ abstract contract PermittedCallers is Ownable2Step {
8
+ address private constant PUBLIC_ACCESS = address(0);
9
+
10
+ mapping(address caller => bool permitted) private _permittedCallers;
11
+
12
+ event PermittedCallerUpdated(address indexed caller, bool permitted);
13
+
14
+ error CallerNotPermitted();
15
+ error PermittedCallersLengthMismatch();
16
+
17
+ constructor(address owner_) Ownable(owner_) {
18
+ _permittedCallers[PUBLIC_ACCESS] = true;
19
+ }
20
+
21
+ modifier onlyPermitted() {
22
+ require(_isPermitted(msg.sender), CallerNotPermitted());
23
+ _;
24
+ }
25
+
26
+ function isPermittedCaller(address caller) public view returns (bool) {
27
+ return _isPermitted(caller);
28
+ }
29
+
30
+ function setPermittedCallers(address[] calldata callers, bool[] calldata permitted) external onlyOwner {
31
+ require(callers.length == permitted.length, PermittedCallersLengthMismatch());
32
+ for (uint256 i = 0; i < callers.length; i++) {
33
+ _permittedCallers[callers[i]] = permitted[i];
34
+ emit PermittedCallerUpdated(callers[i], permitted[i]);
35
+ }
36
+ }
37
+
38
+ function _isPermitted(address caller) internal view returns (bool) {
39
+ return _permittedCallers[PUBLIC_ACCESS] || _permittedCallers[caller];
40
+ }
41
+ }
@@ -0,0 +1,12 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.20;
3
+
4
+ import {LimitOrderConfig} from "../libs/SwapLimitOrders.sol";
5
+
6
+ /// @title ISetLimitOrderConfig
7
+ /// @notice Interface for setting limit order configuration
8
+ interface ISetLimitOrderConfig {
9
+ /// @notice Sets the canonical limit order configuration
10
+ /// @param config The new limit order configuration
11
+ function setLimitOrderConfig(LimitOrderConfig memory config) external;
12
+ }
@@ -18,6 +18,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
18
18
 
19
19
  import {IZoraLimitOrderBook} from "../IZoraLimitOrderBook.sol";
20
20
  import {SwapLimitOrders, LimitOrderConfig, Orders} from "../libs/SwapLimitOrders.sol";
21
+ import {ISetLimitOrderConfig} from "./ISetLimitOrderConfig.sol";
21
22
  import {ISwapRouter} from "@zoralabs/shared-contracts/interfaces/uniswap/ISwapRouter.sol";
22
23
  import {ISupportsLimitOrderFill} from "@zoralabs/coins/src/interfaces/ISupportsLimitOrderFill.sol";
23
24
  import {IMsgSender} from "@zoralabs/coins/src/interfaces/IMsgSender.sol";
@@ -25,7 +26,8 @@ import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
25
26
  import {TransientSlot} from "@openzeppelin/contracts/utils/TransientSlot.sol";
26
27
  import {Path} from "@zoralabs/shared-contracts/libs/UniswapV3/Path.sol";
27
28
  import {V3ToV4SwapLib} from "@zoralabs/coins/src/libs/V3ToV4SwapLib.sol";
28
- import {SimpleAccessManaged} from "../access/SimpleAccessManaged.sol";
29
+ import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
30
+ import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
29
31
  import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol";
30
32
 
31
33
  /// @title SwapWithLimitOrders
@@ -35,7 +37,7 @@ import {IAllowanceTransfer} from "permit2/src/interfaces/IAllowanceTransfer.sol"
35
37
  /// Users call swapWithLimitOrders() directly, which triggers the unlock callback flow.
36
38
  /// Uses Permit2 for token approvals, matching the universal-router pattern.
37
39
  /// @author oveddan
38
- contract SwapWithLimitOrders is IMsgSender {
40
+ contract SwapWithLimitOrders is ISetLimitOrderConfig, Ownable2Step, IMsgSender {
39
41
  using SafeERC20 for IERC20;
40
42
  using BalanceDeltaLibrary for BalanceDelta;
41
43
  using CurrencyLibrary for Currency;
@@ -121,9 +123,6 @@ contract SwapWithLimitOrders is IMsgSender {
121
123
  /// @notice Error thrown when caller is not the pool manager
122
124
  error OnlyPoolManager();
123
125
 
124
- /// @notice Error thrown when caller is not the authority
125
- error OnlyAuthority();
126
-
127
126
  /// @notice Error thrown when config does not match canonical config
128
127
  error InvalidLimitOrderConfig();
129
128
 
@@ -141,7 +140,8 @@ contract SwapWithLimitOrders is IMsgSender {
141
140
  /// @param zoraLimitOrderBook_ The limit order book contract
142
141
  /// @param swapRouter_ The Uniswap V3 swap router
143
142
  /// @param permit2_ The Permit2 contract address (0x000000000022D473030F116dDEE9F6B43aC78BA3)
144
- constructor(IPoolManager poolManager_, IZoraLimitOrderBook zoraLimitOrderBook_, ISwapRouter swapRouter_, address permit2_) {
143
+ /// @param owner_ The owner address
144
+ constructor(IPoolManager poolManager_, IZoraLimitOrderBook zoraLimitOrderBook_, ISwapRouter swapRouter_, address permit2_, address owner_) Ownable(owner_) {
145
145
  require(address(poolManager_) != address(0), "PoolManager cannot be zero");
146
146
  require(address(zoraLimitOrderBook_) != address(0), "ZoraLimitOrderBook cannot be zero");
147
147
  require(address(swapRouter_) != address(0), "SwapRouter cannot be zero");
@@ -159,10 +159,9 @@ contract SwapWithLimitOrders is IMsgSender {
159
159
  }
160
160
 
161
161
  /// @notice Sets the canonical limit order configuration
162
- /// @dev Only callable by zoraLimitOrderBook.authority()
162
+ /// @dev Only callable by the owner
163
163
  /// @param config The new limit order configuration
164
- function setLimitOrderConfig(LimitOrderConfig memory config) external {
165
- require(msg.sender == SimpleAccessManaged(address(zoraLimitOrderBook)).authority(), OnlyAuthority());
164
+ function setLimitOrderConfig(LimitOrderConfig memory config) external onlyOwner {
166
165
  SwapLimitOrders.validate(config);
167
166
  _limitOrderConfig = config;
168
167
  emit LimitOrderConfigUpdated(config.multiples, config.percentages);