@zoralabs/limit-orders 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$js.log +85 -0
- package/AUDIT_NOTES.md +33 -0
- package/AUDIT_RFP.md +408 -0
- package/CHANGELOG.md +25 -0
- package/GAS_COMPARISON_RESULTS.md +194 -0
- package/LICENSE +21 -0
- package/README.md +650 -0
- package/SPEC.md +291 -0
- package/abis/BalanceDeltaLibrary.json +15 -0
- package/abis/BeforeSwapDeltaLibrary.json +15 -0
- package/abis/CurrencyLibrary.json +25 -0
- package/abis/CustomRevert.json +28 -0
- package/abis/IAllowanceTransfer.json +486 -0
- package/abis/IAuthority.json +31 -0
- package/abis/ICoin.json +1074 -0
- package/abis/IDeployedCoinVersionLookup.json +21 -0
- package/abis/IDopplerErrors.json +44 -0
- package/abis/IEIP712.json +15 -0
- package/abis/IERC1363.json +373 -0
- package/abis/IERC165.json +21 -0
- package/abis/IERC20.json +185 -0
- package/abis/IERC20Minimal.json +172 -0
- package/abis/IERC6909Claims.json +288 -0
- package/abis/IERC7572.json +21 -0
- package/abis/IExtsload.json +64 -0
- package/abis/IExttload.json +40 -0
- package/abis/IHasCoinType.json +15 -0
- package/abis/IHasPoolKey.json +42 -0
- package/abis/IHasRewardsRecipients.json +54 -0
- package/abis/IHasSwapPath.json +60 -0
- package/abis/IHasTotalSupplyForPositions.json +15 -0
- package/abis/IHooks.json +789 -0
- package/abis/IMsgSender.json +15 -0
- package/abis/IPoolManager.json +1286 -0
- package/abis/IProtocolFees.json +174 -0
- package/abis/ISupportsLimitOrderFill.json +15 -0
- package/abis/ISwapPathRouter.json +92 -0
- package/abis/ISwapRouter.json +219 -0
- package/abis/IUniswapV3SwapCallback.json +25 -0
- package/abis/IUpgradeableDestinationV4Hook.json +84 -0
- package/abis/IUpgradeableDestinationV4HookWithUpdateableFee.json +95 -0
- package/abis/IUpgradeableV4Hook.json +112 -0
- package/abis/IZoraHookRegistry.json +188 -0
- package/abis/IZoraLimitOrderBook.json +623 -0
- package/abis/IZoraLimitOrderBookCoinsInterface.json +67 -0
- package/abis/IZoraV4CoinHook.json +610 -0
- package/abis/Permit2Payments.json +7 -0
- package/abis/Position.json +7 -0
- package/abis/SafeCast.json +7 -0
- package/abis/SafeCast160.json +7 -0
- package/abis/SafeERC20.json +34 -0
- package/abis/SimpleAccessManaged.json +57 -0
- package/abis/SimpleAccessManager.json +351 -0
- package/abis/SqrtPriceMath.json +22 -0
- package/abis/StateLibrary.json +80 -0
- package/abis/SwapLimitOrders.json +22 -0
- package/abis/SwapWithLimitOrders.json +457 -0
- package/abis/TickBitmap.json +18 -0
- package/abis/TickMath.json +24 -0
- package/abis/V3ToV4SwapLib.json +28 -0
- package/abis/ZoraLimitOrderBook.json +771 -0
- package/cache/solidity-files-cache.json +1 -0
- package/dist/index.cjs +760 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +731 -0
- package/dist/index.js.map +1 -0
- package/dist/wagmiGenerated.d.ts +1012 -0
- package/dist/wagmiGenerated.d.ts.map +1 -0
- package/foundry.toml +29 -0
- package/gas_comparison.py +49 -0
- package/out/BalanceDelta.sol/BalanceDeltaLibrary.json +1 -0
- package/out/BeforeSwapDelta.sol/BeforeSwapDeltaLibrary.json +1 -0
- package/out/BitMath.sol/BitMath.json +1 -0
- package/out/BytesLib.sol/BytesLib.json +1 -0
- package/out/CoinCommon.sol/CoinCommon.json +1 -0
- package/out/CoinConfigurationVersions.sol/CoinConfigurationVersions.json +1 -0
- package/out/CoinConstants.sol/CoinConstants.json +1 -0
- package/out/Context.sol/Context.json +1 -0
- package/out/Currency.sol/CurrencyLibrary.json +1 -0
- package/out/CurrencyReserves.sol/CurrencyReserves.json +1 -0
- package/out/CustomRevert.sol/CustomRevert.json +1 -0
- package/out/DopplerMath.sol/DopplerMath.json +1 -0
- package/out/FixedPoint128.sol/FixedPoint128.json +1 -0
- package/out/FixedPoint96.sol/FixedPoint96.json +1 -0
- package/out/FullMath.sol/FullMath.json +1 -0
- package/out/IAllowanceTransfer.sol/IAllowanceTransfer.json +1 -0
- package/out/IAuthority.sol/IAuthority.json +1 -0
- package/out/ICoin.sol/ICoin.json +1 -0
- package/out/ICoin.sol/IHasCoinType.json +1 -0
- package/out/ICoin.sol/IHasPoolKey.json +1 -0
- package/out/ICoin.sol/IHasSwapPath.json +1 -0
- package/out/ICoin.sol/IHasTotalSupplyForPositions.json +1 -0
- package/out/IDeployedCoinVersionLookup.sol/IDeployedCoinVersionLookup.json +1 -0
- package/out/IDopplerErrors.sol/IDopplerErrors.json +1 -0
- package/out/IEIP712.sol/IEIP712.json +1 -0
- package/out/IERC1363.sol/IERC1363.json +1 -0
- package/out/IERC165.sol/IERC165.json +1 -0
- package/out/IERC20.sol/IERC20.json +1 -0
- package/out/IERC20Minimal.sol/IERC20Minimal.json +1 -0
- package/out/IERC6909Claims.sol/IERC6909Claims.json +1 -0
- package/out/IERC7572.sol/IERC7572.json +1 -0
- package/out/IExtsload.sol/IExtsload.json +1 -0
- package/out/IExttload.sol/IExttload.json +1 -0
- package/out/IHasRewardsRecipients.sol/IHasRewardsRecipients.json +1 -0
- package/out/IHooks.sol/IHooks.json +1 -0
- package/out/IMsgSender.sol/IMsgSender.json +1 -0
- package/out/IPoolManager.sol/IPoolManager.json +1 -0
- package/out/IProtocolFees.sol/IProtocolFees.json +1 -0
- package/out/ISupportsLimitOrderFill.sol/ISupportsLimitOrderFill.json +1 -0
- package/out/ISwapPathRouter.sol/ISwapPathRouter.json +1 -0
- package/out/ISwapRouter.sol/ISwapRouter.json +1 -0
- package/out/IUniswapV3SwapCallback.sol/IUniswapV3SwapCallback.json +1 -0
- package/out/IUpgradeableV4Hook.sol/IUpgradeableDestinationV4Hook.json +1 -0
- package/out/IUpgradeableV4Hook.sol/IUpgradeableDestinationV4HookWithUpdateableFee.json +1 -0
- package/out/IUpgradeableV4Hook.sol/IUpgradeableV4Hook.json +1 -0
- package/out/IZoraHookRegistry.sol/IZoraHookRegistry.json +1 -0
- package/out/IZoraLimitOrderBook.sol/IZoraLimitOrderBook.json +1 -0
- package/out/IZoraLimitOrderBookCoinsInterface.sol/IZoraLimitOrderBookCoinsInterface.json +1 -0
- package/out/IZoraV4CoinHook.sol/IZoraV4CoinHook.json +1 -0
- package/out/LimitOrderBitmap.sol/LimitOrderBitmap.json +1 -0
- package/out/LimitOrderCommon.sol/LimitOrderCommon.json +1 -0
- package/out/LimitOrderCreate.sol/LimitOrderCreate.json +1 -0
- package/out/LimitOrderFill.sol/LimitOrderFill.json +1 -0
- package/out/LimitOrderLiquidity.sol/LimitOrderLiquidity.json +1 -0
- package/out/LimitOrderQueues.sol/LimitOrderQueues.json +1 -0
- package/out/LimitOrderStorage.sol/LimitOrderStorage.json +1 -0
- package/out/LimitOrderTypes.sol/LimitOrderTypes.json +1 -0
- package/out/LimitOrderWithdraw.sol/LimitOrderWithdraw.json +1 -0
- package/out/LiquidityAmounts.sol/LiquidityAmounts.json +1 -0
- package/out/LiquidityMath.sol/LiquidityMath.json +1 -0
- package/out/Lock.sol/Lock.json +1 -0
- package/out/NonzeroDeltaCount.sol/NonzeroDeltaCount.json +1 -0
- package/out/Path.sol/Path.json +1 -0
- package/out/PathKey.sol/PathKeyLibrary.json +1 -0
- package/out/Permit2Payments.sol/Permit2Payments.json +1 -0
- package/out/PoolId.sol/PoolIdLibrary.json +1 -0
- package/out/Position.sol/Position.json +1 -0
- package/out/SafeCast.sol/SafeCast.json +1 -0
- package/out/SafeCast160.sol/SafeCast160.json +1 -0
- package/out/SafeERC20.sol/SafeERC20.json +1 -0
- package/out/SimpleAccessManaged.sol/SimpleAccessManaged.json +1 -0
- package/out/SimpleAccessManager.sol/SimpleAccessManager.json +1 -0
- package/out/SqrtPriceMath.sol/SqrtPriceMath.json +1 -0
- package/out/StateLibrary.sol/StateLibrary.json +1 -0
- package/out/SwapLimitOrders.sol/SwapLimitOrders.json +1 -0
- package/out/SwapWithLimitOrders.sol/SwapWithLimitOrders.json +1 -0
- package/out/TickBitmap.sol/TickBitmap.json +1 -0
- package/out/TickMath.sol/TickMath.json +1 -0
- package/out/TransientSlot.sol/TransientSlot.json +1 -0
- package/out/TransientStateLibrary.sol/TransientStateLibrary.json +1 -0
- package/out/UniV4SwapToCurrency.sol/UniV4SwapToCurrency.json +1 -0
- package/out/UnsafeMath.sol/UnsafeMath.json +1 -0
- package/out/V3ToV4SwapLib.sol/V3ToV4SwapLib.json +1 -0
- package/out/ZoraLimitOrderBook.sol/ZoraLimitOrderBook.json +1 -0
- package/out/build-info/69718f10d1dc37f0.json +1 -0
- package/out/uniswap/BitMath.sol/BitMath.json +1 -0
- package/out/uniswap/CustomRevert.sol/CustomRevert.json +1 -0
- package/out/uniswap/FullMath.sol/FullMath.json +1 -0
- package/out/uniswap/SafeCast.sol/SafeCast.json +1 -0
- package/out/uniswap/TickMath.sol/TickMath.json +1 -0
- package/package/index.ts +1 -0
- package/package/wagmiGenerated.ts +738 -0
- package/package.json +57 -0
- package/remappings.txt +11 -0
- package/src/IZoraLimitOrderBook.sol +195 -0
- package/src/ZoraLimitOrderBook.sol +220 -0
- package/src/access/SimpleAccessManaged.sol +76 -0
- package/src/access/SimpleAccessManager.sol +268 -0
- package/src/libs/LimitOrderBitmap.sol +84 -0
- package/src/libs/LimitOrderCommon.sol +91 -0
- package/src/libs/LimitOrderCreate.sol +277 -0
- package/src/libs/LimitOrderFill.sol +362 -0
- package/src/libs/LimitOrderLiquidity.sol +222 -0
- package/src/libs/LimitOrderQueues.sol +101 -0
- package/src/libs/LimitOrderStorage.sol +34 -0
- package/src/libs/LimitOrderTypes.sol +41 -0
- package/src/libs/LimitOrderWithdraw.sol +100 -0
- package/src/libs/Permit2Payments.sol +41 -0
- package/src/libs/SwapLimitOrders.sol +209 -0
- package/src/router/SwapWithLimitOrders.sol +454 -0
- package/test/LimitOrderAccessControl.t.sol +461 -0
- package/test/LimitOrderBitmap.t.sol +194 -0
- package/test/LimitOrderCreate.t.sol +348 -0
- package/test/LimitOrderFill.t.sol +1005 -0
- package/test/LimitOrderLibraries.t.sol +354 -0
- package/test/LimitOrderLiquidityPayouts.t.sol +333 -0
- package/test/LimitOrderV4Pools.t.sol +157 -0
- package/test/LimitOrderWithdraw.t.sol +653 -0
- package/test/SimpleAccessManager.t.sol +420 -0
- package/test/SwapWithLimitOrders.t.sol +107 -0
- package/test/SwapWithLimitOrdersRouter.t.sol +1073 -0
- package/test/gas/LimitOrderFillGas.t.sol +1008 -0
- package/test/gas/LimitOrderSwapGas.t.sol +403 -0
- package/test/gas/logs/gas_benchmarks_fill_20251201.log +30 -0
- package/test/gas/logs/gas_benchmarks_swap_20251201.log +27 -0
- package/test/unit/LimitOrderBitmapUnit.t.sol +276 -0
- package/test/unit/LimitOrderCreateUnit.t.sol +358 -0
- package/test/unit/SwapLimitOrdersUnit.t.sol +672 -0
- package/test/unit/SwapLimitOrdersValidation.t.sol +423 -0
- package/test/unit/SwapWithLimitOrdersUnit.t.sol +321 -0
- package/test/utils/BaseTest.sol +793 -0
- package/test/utils/TestableZoraLimitOrderBook.sol +54 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.json +9 -0
- package/tsup.config.ts +11 -0
- package/wagmi.config.ts +18 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
> @zoralabs/limit-orders@0.2.0 build:js /home/runner/work/zora-protocol-private/zora-protocol-private/packages/limit-orders
|
|
3
|
+
> pnpm run wagmi:generate && pnpm run copy-abis && pnpm run prettier:write && tsup
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
> @zoralabs/limit-orders@0.2.0 wagmi:generate /home/runner/work/zora-protocol-private/zora-protocol-private/packages/limit-orders
|
|
7
|
+
> pnpm run build:contracts:minimal && wagmi generate && pnpm exec rename-generated-abi-casing ./package/wagmiGenerated.ts
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
> @zoralabs/limit-orders@0.2.0 build:contracts:minimal /home/runner/work/zora-protocol-private/zora-protocol-private/packages/limit-orders
|
|
11
|
+
> forge build src/ --no-metadata
|
|
12
|
+
|
|
13
|
+
Compiling 90 files with Solc 0.8.28
|
|
14
|
+
Solc 0.8.28 finished in 7.62s
|
|
15
|
+
Compiler run successful!
|
|
16
|
+
[33m-[39m Validating plugins
|
|
17
|
+
[32m✔[39m Validating plugins
|
|
18
|
+
[33m-[39m Resolving contracts
|
|
19
|
+
[32m✔[39m Resolving contracts
|
|
20
|
+
[33m-[39m Running plugins
|
|
21
|
+
[32m✔[39m Running plugins
|
|
22
|
+
[33m-[39m Writing to [90mpackage/wagmiGenerated.ts[39m
|
|
23
|
+
[32m✔[39m Writing to [90mpackage/wagmiGenerated.ts[39m
|
|
24
|
+
🔄 Processing 1 file(s) to replace 'Abi' with 'ABI'...
|
|
25
|
+
📝 Processing ./package/wagmiGenerated.ts...
|
|
26
|
+
✅ Updated ./package/wagmiGenerated.ts (3 replacements)
|
|
27
|
+
✨ All files processed successfully!
|
|
28
|
+
|
|
29
|
+
> @zoralabs/limit-orders@0.2.0 copy-abis /home/runner/work/zora-protocol-private/zora-protocol-private/packages/limit-orders
|
|
30
|
+
> pnpm exec bundle-abis
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
> @zoralabs/limit-orders@0.2.0 prettier:write /home/runner/work/zora-protocol-private/zora-protocol-private/packages/limit-orders
|
|
34
|
+
> prettier --write 'src/**/*.sol' 'test/**/*.sol'
|
|
35
|
+
|
|
36
|
+
src/access/SimpleAccessManaged.sol 357ms (unchanged)
|
|
37
|
+
src/access/SimpleAccessManager.sol 269ms (unchanged)
|
|
38
|
+
src/IZoraLimitOrderBook.sol 59ms (unchanged)
|
|
39
|
+
src/libs/LimitOrderBitmap.sol 153ms (unchanged)
|
|
40
|
+
src/libs/LimitOrderCommon.sol 171ms (unchanged)
|
|
41
|
+
src/libs/LimitOrderCreate.sol 359ms (unchanged)
|
|
42
|
+
src/libs/LimitOrderFill.sol 360ms (unchanged)
|
|
43
|
+
src/libs/LimitOrderLiquidity.sol 224ms (unchanged)
|
|
44
|
+
src/libs/LimitOrderQueues.sol 44ms (unchanged)
|
|
45
|
+
src/libs/LimitOrderStorage.sol 15ms (unchanged)
|
|
46
|
+
src/libs/LimitOrderTypes.sol 2ms (unchanged)
|
|
47
|
+
src/libs/LimitOrderWithdraw.sol 100ms (unchanged)
|
|
48
|
+
src/libs/Permit2Payments.sol 23ms (unchanged)
|
|
49
|
+
src/libs/SwapLimitOrders.sol 151ms (unchanged)
|
|
50
|
+
src/router/SwapWithLimitOrders.sol 265ms (unchanged)
|
|
51
|
+
src/ZoraLimitOrderBook.sol 121ms (unchanged)
|
|
52
|
+
test/gas/LimitOrderFillGas.t.sol 821ms (unchanged)
|
|
53
|
+
test/gas/LimitOrderSwapGas.t.sol 318ms (unchanged)
|
|
54
|
+
test/LimitOrderAccessControl.t.sol 390ms (unchanged)
|
|
55
|
+
test/LimitOrderBitmap.t.sol 217ms (unchanged)
|
|
56
|
+
test/LimitOrderCreate.t.sol 395ms (unchanged)
|
|
57
|
+
test/LimitOrderFill.t.sol 1038ms (unchanged)
|
|
58
|
+
test/LimitOrderLibraries.t.sol 393ms (unchanged)
|
|
59
|
+
test/LimitOrderLiquidityPayouts.t.sol 264ms (unchanged)
|
|
60
|
+
test/LimitOrderV4Pools.t.sol 149ms (unchanged)
|
|
61
|
+
test/LimitOrderWithdraw.t.sol 639ms (unchanged)
|
|
62
|
+
test/SimpleAccessManager.t.sol 328ms (unchanged)
|
|
63
|
+
test/SwapWithLimitOrders.t.sol 125ms (unchanged)
|
|
64
|
+
test/SwapWithLimitOrdersRouter.t.sol 554ms (unchanged)
|
|
65
|
+
test/unit/LimitOrderBitmapUnit.t.sol 176ms (unchanged)
|
|
66
|
+
test/unit/LimitOrderCreateUnit.t.sol 151ms (unchanged)
|
|
67
|
+
test/unit/SwapLimitOrdersUnit.t.sol 525ms (unchanged)
|
|
68
|
+
test/unit/SwapLimitOrdersValidation.t.sol 253ms (unchanged)
|
|
69
|
+
test/unit/SwapWithLimitOrdersUnit.t.sol 96ms (unchanged)
|
|
70
|
+
test/utils/BaseTest.sol 606ms (unchanged)
|
|
71
|
+
test/utils/TestableZoraLimitOrderBook.sol 37ms (unchanged)
|
|
72
|
+
[34mCLI[39m Building entry: package/index.ts
|
|
73
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
74
|
+
[34mCLI[39m tsup v8.4.0
|
|
75
|
+
[34mCLI[39m Using tsup config: /home/runner/work/zora-protocol-private/zora-protocol-private/packages/limit-orders/tsup.config.ts
|
|
76
|
+
[34mCLI[39m Target: es2021
|
|
77
|
+
[34mCLI[39m Cleaning output folder
|
|
78
|
+
[34mCJS[39m Build start
|
|
79
|
+
[34mESM[39m Build start
|
|
80
|
+
[32mESM[39m [1mdist/index.js [22m[32m20.36 KB[39m
|
|
81
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m36.51 KB[39m
|
|
82
|
+
[32mESM[39m ⚡️ Build success in 34ms
|
|
83
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m21.52 KB[39m
|
|
84
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m36.63 KB[39m
|
|
85
|
+
[32mCJS[39m ⚡️ Build success in 38ms
|
package/AUDIT_NOTES.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Zora Limit Orders — Audit Notes
|
|
2
|
+
|
|
3
|
+
This document highlights areas of concern for security reviewers.
|
|
4
|
+
|
|
5
|
+
Related docs:
|
|
6
|
+
|
|
7
|
+
- [`README.md`](./README.md) — architecture & diagrams
|
|
8
|
+
- [`SPEC.md`](./SPEC.md) — normative behavior + invariants
|
|
9
|
+
- [`AUDIT_RFP.md`](./AUDIT_RFP.md) — audit scope
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Code Hotspots
|
|
14
|
+
|
|
15
|
+
Highest-risk logic:
|
|
16
|
+
|
|
17
|
+
- `src/ZoraLimitOrderBook.sol` — entrypoints + unlock routing
|
|
18
|
+
- `src/libs/LimitOrderFill.sol` — epoch + bitmap + queue traversal
|
|
19
|
+
- `src/libs/LimitOrderQueues.sol` — linked list operations
|
|
20
|
+
- `src/libs/LimitOrderBitmap.sol` — tick discovery
|
|
21
|
+
- `src/libs/LimitOrderLiquidity.sol` — settlement + payouts
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Areas of Concern
|
|
26
|
+
|
|
27
|
+
1. **Linked list integrity** — queue corruption could strand funds
|
|
28
|
+
2. **Bitmap correctness** — tick iteration edge cases and word boundaries
|
|
29
|
+
3. **Epoch isolation** — same-transaction fill prevention, especially with nested creates
|
|
30
|
+
4. **Settlement correctness** — currency deltas must settle in all paths (ERC20/native)
|
|
31
|
+
5. **Access control** — admin must not be able to access user funds or block withdrawals
|
|
32
|
+
6. **Reentrancy surface** — unlock callbacks, token transfers, hook interactions
|
|
33
|
+
7. **Gas/DoS** — pathological queues, maxFillCount edge cases
|
package/AUDIT_RFP.md
ADDED
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# Zora Protocol Limit Orders (aka "Autosell") - Audit Scope Document
|
|
2
|
+
|
|
3
|
+
**Version**: 1.2
|
|
4
|
+
**Date**: 2025-12-12
|
|
5
|
+
**Branch**: `autosell`
|
|
6
|
+
**Purpose**: Audit scope and technical reference for engaged auditors
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Executive Summary
|
|
11
|
+
|
|
12
|
+
Zora has implemented a limit orders system that enables users to create onchain
|
|
13
|
+
orders that automatically execute when Uniswap V4 pool prices reach
|
|
14
|
+
predetermined ticks. This document provides complete scope, technical analysis,
|
|
15
|
+
and security considerations for the audit engagement.
|
|
16
|
+
|
|
17
|
+
**Scope**: ~2,758 lines of Solidity across 16 new files
|
|
18
|
+
**Focus Areas**: Linked list integrity, epoch-based execution isolation, bitmap optimization, access control
|
|
19
|
+
**Ideal Auditor Profile**: Strong familiarity with DeFi protocols and Uniswap V4 architecture (liquidity positions, hook patterns, unlock callbacks, transient storage)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Technical Architecture Reference
|
|
24
|
+
|
|
25
|
+
**Supporting docs**
|
|
26
|
+
|
|
27
|
+
- [`README.md`](./README.md) — architecture, diagrams, execution paths
|
|
28
|
+
- [`SPEC.md`](./SPEC.md) — normative behavior and invariants (“what must be true”)
|
|
29
|
+
- [`AUDIT_NOTES.md`](./AUDIT_NOTES.md) — threat model + audit checklist
|
|
30
|
+
|
|
31
|
+
This RFP focuses on audit scope, security considerations, and deliverables.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Quick Navigation
|
|
36
|
+
|
|
37
|
+
### Part 1: Audit Scope & Process
|
|
38
|
+
|
|
39
|
+
- [Audit Scope](#part-1-audit-scope) - What's in/out of scope
|
|
40
|
+
- [Areas of Technical Complexity](#areas-of-technical-complexity) - Implementation details
|
|
41
|
+
- [Audit Deliverables](#audit-deliverables)
|
|
42
|
+
- [Timeline & Process](#timeline-and-process)
|
|
43
|
+
- [Clarifications Needed](#clarifications-needed)
|
|
44
|
+
|
|
45
|
+
### Part 2: Technical Implementation
|
|
46
|
+
|
|
47
|
+
- [File Structure](#file-structure) - All 15 files documented
|
|
48
|
+
- [Data Structures](#data-structures) - LimitOrder, Queue, Order IDs
|
|
49
|
+
- [Storage Organization](#storage-organization) - Storage layout
|
|
50
|
+
- [External Functions](#external-functions) - create, fill, withdraw
|
|
51
|
+
|
|
52
|
+
### Part 3: Additional Information
|
|
53
|
+
|
|
54
|
+
- [Known Limitations](#known-limitations)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
# PART 1: AUDIT SCOPE
|
|
59
|
+
|
|
60
|
+
## Overview
|
|
61
|
+
|
|
62
|
+
_For detailed architecture, see [README: Overview](./README.md#1-overview) and [Limit Orders Architecture](./README.md#3-limit-orders-architecture-overview)_
|
|
63
|
+
|
|
64
|
+
The limit orders system allows users to:
|
|
65
|
+
|
|
66
|
+
1. **Create orders** by adding Uniswap V4 liquidity positions across a one-tick-spacing range
|
|
67
|
+
2. **Fill orders** automatically when pool price crosses into the order's range
|
|
68
|
+
3. **Withdraw orders** by cancelling specific orders by ID and withdrawing the resulting funds to a recipient.
|
|
69
|
+
- The call cancels orders in the order provided until `minAmountOut` is reached (or cancels all provided orders if `minAmountOut == 0`).
|
|
70
|
+
- Cancellation is whole-order only (no proportional/partial cancellation).
|
|
71
|
+
|
|
72
|
+
**Key Innovation**: Implements limit orders as single-sided Uniswap V4 liquidity positions, providing a completely native onchain approach that keeps liquidity in the pools for improved trading. Uses linked list queues, bitmap optimization, and epoch-based execution isolation for efficient order matching.
|
|
73
|
+
|
|
74
|
+
## In-Scope Contracts
|
|
75
|
+
|
|
76
|
+
### Primary Package: `packages/limit-orders/src/`
|
|
77
|
+
|
|
78
|
+
#### Core Contracts (2 files, ~418 LOC)
|
|
79
|
+
|
|
80
|
+
**ZoraLimitOrderBook.sol** (229 lines)
|
|
81
|
+
|
|
82
|
+
- Main contract implementing the order book
|
|
83
|
+
- Manages pool manager unlock/callback patterns
|
|
84
|
+
- Delegates to library contracts for execution
|
|
85
|
+
- Access control via SimpleAccessManaged
|
|
86
|
+
|
|
87
|
+
**IZoraLimitOrderBook.sol** (189 lines)
|
|
88
|
+
|
|
89
|
+
- Public API interface and event definitions
|
|
90
|
+
- 3 callback types: CREATE, FILL, WITHDRAW_ORDERS
|
|
91
|
+
- 21 error types for validation
|
|
92
|
+
- Data structure definitions for callbacks
|
|
93
|
+
|
|
94
|
+
#### Access Control (2 files, ~345 LOC)
|
|
95
|
+
|
|
96
|
+
**access/SimpleAccessManaged.sol** (76 lines)
|
|
97
|
+
|
|
98
|
+
- Lightweight fork of OpenZeppelin's [AccessManaged](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessManaged) contract, reduced in complexity to minimize code size
|
|
99
|
+
- Uses the same security architecture (authority-based permissions via `IAuthority.canCall()`)
|
|
100
|
+
- Removes time-based permissions methodology (no delays, no scheduled operations)
|
|
101
|
+
- Controls `create()` and `setMaxFillCount()` functions
|
|
102
|
+
|
|
103
|
+
**access/SimpleAccessManager.sol** (268 lines)
|
|
104
|
+
|
|
105
|
+
- Full role-based access manager implementation
|
|
106
|
+
- Provides complete `IAuthority` interface implementation
|
|
107
|
+
- Supports role-based permissions with admin delegation
|
|
108
|
+
- `PUBLIC_ROLE` support for unrestricted functions
|
|
109
|
+
- Function selector mapping to specific roles
|
|
110
|
+
|
|
111
|
+
#### Type Definitions & Storage (2 files, ~79 LOC)
|
|
112
|
+
|
|
113
|
+
**LimitOrderTypes.sol** (44 lines)
|
|
114
|
+
|
|
115
|
+
- OrderStatus enum: INACTIVE, OPEN, FILLED
|
|
116
|
+
- LimitOrder struct (224 bytes / 7 storage slots with linked list pointers)
|
|
117
|
+
- Queue struct (96 bytes / 3 storage slots with head/tail/length/balance)
|
|
118
|
+
|
|
119
|
+
**LimitOrderStorage.sol** (35 lines)
|
|
120
|
+
|
|
121
|
+
- Storage slot derived from `keccak256("zora.limit.order.book.storage")`
|
|
122
|
+
- Storage slot: `0x98b43bb10ca7bc310641b07883d9e14c04b3983640df6b07dd1c99d10a3c6cec`
|
|
123
|
+
- Layout with 6 mappings for orders, queues, epochs, bitmaps, nonces, and maker balances
|
|
124
|
+
|
|
125
|
+
#### Order Lifecycle Libraries (3 files, ~722 LOC)
|
|
126
|
+
|
|
127
|
+
**LimitOrderCreate.sol** (277 lines)
|
|
128
|
+
|
|
129
|
+
- Order creation with validation
|
|
130
|
+
- Calls `poolManager.modifyLiquidity()` with positive `liquidityDelta` to add liquidity
|
|
131
|
+
- Manages callback data and execution
|
|
132
|
+
- Handles residual amount refunds
|
|
133
|
+
- Implementation details: Input validation, liquidity calculations, nonce management
|
|
134
|
+
|
|
135
|
+
**LimitOrderFill.sol** (345 lines)
|
|
136
|
+
|
|
137
|
+
- Core fill execution logic
|
|
138
|
+
- Epoch-based execution isolation mechanism
|
|
139
|
+
- Two fill modes: tick range-based and order ID-based
|
|
140
|
+
- Bitmap-based tick iteration optimization
|
|
141
|
+
- Assembly optimizations in tight loops
|
|
142
|
+
- Implementation details: Epoch checks, bitmap manipulation, linked list traversal
|
|
143
|
+
|
|
144
|
+
**LimitOrderWithdraw.sol** (100 lines)
|
|
145
|
+
|
|
146
|
+
- Cancellation and withdrawal logic
|
|
147
|
+
- Order-specific withdrawal (cancels provided order ids sequentially until `minAmountOut` is reached)
|
|
148
|
+
- Burns liquidity and issues refunds
|
|
149
|
+
- Implementation details: Owner validation, balance accounting, liquidity burning
|
|
150
|
+
|
|
151
|
+
#### Support Libraries (6 files, ~648 LOC)
|
|
152
|
+
|
|
153
|
+
**LimitOrderCommon.sol** (91 lines)
|
|
154
|
+
|
|
155
|
+
- Order metadata extraction helpers
|
|
156
|
+
- Records orders in queues and bitmaps
|
|
157
|
+
- Removes orders from queues and bitmaps
|
|
158
|
+
- Tick determination logic
|
|
159
|
+
|
|
160
|
+
**LimitOrderQueues.sol** (101 lines)
|
|
161
|
+
|
|
162
|
+
- Linked list implementation
|
|
163
|
+
- Single tick queue system
|
|
164
|
+
- Operations: enqueue, unlink, clearLinks
|
|
165
|
+
- Direct storage slot manipulation for gas optimization
|
|
166
|
+
- Implementation details: Linked list integrity, concurrent modifications
|
|
167
|
+
|
|
168
|
+
**LimitOrderBitmap.sol** (84 lines)
|
|
169
|
+
|
|
170
|
+
- Bitmap management for tick activation tracking
|
|
171
|
+
- Sets/clears bits when ticks become active/inactive
|
|
172
|
+
- `getExecutableTicks()` for efficient range queries
|
|
173
|
+
- Implementation details: Bit manipulation correctness, boundary conditions
|
|
174
|
+
|
|
175
|
+
**LimitOrderLiquidity.sol** (222 lines)
|
|
176
|
+
|
|
177
|
+
- Uniswap V4 liquidity management
|
|
178
|
+
- Helper functions for adding liquidity during order creation (`_mintLiquidity()`)
|
|
179
|
+
- Removes liquidity during fills/cancels (`burnAndPayout()`, `burnAndRefund()`)
|
|
180
|
+
- Handles fee distribution and swap paths
|
|
181
|
+
- Supports alternative payout currencies
|
|
182
|
+
- Implementation details: Liquidity calculations, fee distribution, swap execution
|
|
183
|
+
|
|
184
|
+
**SwapLimitOrders.sol** (209 lines)
|
|
185
|
+
|
|
186
|
+
- Configuration for automatic order creation post-swap
|
|
187
|
+
- Validates multiples and percentages
|
|
188
|
+
- Computes order ladders from price multiples
|
|
189
|
+
- Square root math for price alignment
|
|
190
|
+
|
|
191
|
+
**Permit2Payments.sol** (41 lines)
|
|
192
|
+
|
|
193
|
+
- Abstract contract for Permit2 token transfers
|
|
194
|
+
- Based on Uniswap's universal-router module
|
|
195
|
+
- Enables gasless token approvals
|
|
196
|
+
|
|
197
|
+
#### Router Contract (1 file, ~454 LOC)
|
|
198
|
+
|
|
199
|
+
_See [README: SwapWithLimitOrders Router](./README.md#2-swapwithlimitorders-router) for detailed architecture_
|
|
200
|
+
|
|
201
|
+
**router/SwapWithLimitOrders.sol** (454 lines)
|
|
202
|
+
|
|
203
|
+
- Standalone router for combined operations
|
|
204
|
+
- Executes V3→V4 swaps + order creation + fills
|
|
205
|
+
- Implements pool manager callback pattern
|
|
206
|
+
- Attempts to fill orders if price crosses
|
|
207
|
+
|
|
208
|
+
### Integration Points: `packages/coins/src/`
|
|
209
|
+
|
|
210
|
+
_For Zora Coins platform architecture, see [README: Coins Platform Architecture](./README.md#2-coins-platform-architecture)_
|
|
211
|
+
|
|
212
|
+
#### Modified Hook Contract
|
|
213
|
+
|
|
214
|
+
**hooks/ZoraV4CoinHook.sol** (modifications only)
|
|
215
|
+
|
|
216
|
+
- Integration point for automatic limit order fills during swaps
|
|
217
|
+
- Calls `limitOrderBook.fill()` in `afterSwap` hook
|
|
218
|
+
- Passes fill referral information
|
|
219
|
+
|
|
220
|
+
**Related Support Libraries**:
|
|
221
|
+
|
|
222
|
+
- `libs/V3ToV4SwapLib.sol` - V3 migration support
|
|
223
|
+
- `libs/CoinRewardsV4.sol` - Reward distribution
|
|
224
|
+
|
|
225
|
+
## Out-of-Scope
|
|
226
|
+
|
|
227
|
+
### Explicitly Excluded
|
|
228
|
+
|
|
229
|
+
**Deployment Scripts**:
|
|
230
|
+
|
|
231
|
+
- `packages/coins/src/deployment/CoinsDeployerBase.sol`
|
|
232
|
+
- All files in `script/` directories across all packages
|
|
233
|
+
- All deployment infrastructure and tooling
|
|
234
|
+
|
|
235
|
+
**Test Files**:
|
|
236
|
+
|
|
237
|
+
- All files in `test/` directories (except as behavioral reference)
|
|
238
|
+
- Test utilities and mocks
|
|
239
|
+
|
|
240
|
+
**Legacy Code**:
|
|
241
|
+
|
|
242
|
+
- `legacy/` directory contents
|
|
243
|
+
- Deprecated contracts from previous versions
|
|
244
|
+
|
|
245
|
+
**Documentation & Tooling**:
|
|
246
|
+
|
|
247
|
+
- `docs/` and `nft-docs/` directories
|
|
248
|
+
- Build scripts and configuration files
|
|
249
|
+
- SDK packages (`coins-sdk`, `protocol-deployments`)
|
|
250
|
+
|
|
251
|
+
**External Dependencies** (auditing the dependencies themselves is out of scope, but integration risks are a key focus):
|
|
252
|
+
|
|
253
|
+
- Uniswap V4 core contracts (`@uniswap/v4-core`) - **Integration analysis is critical**: how we interact with pool manager, liquidity operations, unlock callbacks, and balance settlements
|
|
254
|
+
- OpenZeppelin contracts (`@openzeppelin/contracts`) - Used for IAuthority, IERC20, SafeERC20, TransientSlot
|
|
255
|
+
|
|
256
|
+
**Critical Integration Patterns to Audit**:
|
|
257
|
+
|
|
258
|
+
We are particularly interested in identifying risks in how our code interacts with Uniswap V4:
|
|
259
|
+
|
|
260
|
+
- **Unlock callback patterns**: nested unlock handling when orders are created during fills (see `LimitOrderCreate.sol:44`), potential reentrancy through callbacks, unlock state verification
|
|
261
|
+
- **Liquidity position management**: salt-based position isolation using orderIds as salts (see `LimitOrderCreate.sol:200`, `LimitOrderLiquidity.sol:64`), tick range calculations, liquidity delta correctness
|
|
262
|
+
- **Balance accounting**: settle/take/sync patterns (see `LimitOrderLiquidity.sol`), currency delta tracking via `TransientStateLibrary.currencyDelta`, ETH vs ERC20 handling
|
|
263
|
+
- **Transient storage usage**: `isUnlocked` checks for access control (see `ZoraLimitOrderBook.sol:90`), currency delta reading for settlement verification
|
|
264
|
+
- **Position lifecycle**: `modifyLiquidity` calls with positive delta (mint) and negative delta (burn), fee accumulation via `feesDelta` and distribution to makers/referrals
|
|
265
|
+
|
|
266
|
+
## Areas of Technical Complexity
|
|
267
|
+
|
|
268
|
+
**Linked List Implementation** ([`LimitOrderQueues.sol`](src/libs/LimitOrderQueues.sol), [`LimitOrderCommon.sol`](src/libs/LimitOrderCommon.sol)) - See [README: Tick Queue System](./README.md#tick-queue-system): Tick-based linked lists enable O(1) insertion/removal when order ID is known. Orders are indexed by `(poolKeyHash, coin, tick)` for efficient fill operations.
|
|
269
|
+
|
|
270
|
+
**Epoch-Based Execution Isolation** ([`LimitOrderFill.sol`](src/libs/LimitOrderFill.sol), [`LimitOrderStorage.sol`](src/libs/LimitOrderStorage.sol)) - See [README: Epoch-Based Protection](./README.md#epoch-based-protection): Orders cannot be filled in the same epoch they were created. Each pool maintains an independent epoch counter (uint256) that increments at the start of each fill. Orders store uint32 createdEpoch and are skipped if `createdEpoch >= currentEpoch`. This ensures orders created during fill execution wait for the next fill operation.
|
|
271
|
+
|
|
272
|
+
**Bitmap Optimization** ([`LimitOrderBitmap.sol`](src/libs/LimitOrderBitmap.sol), [`LimitOrderCommon.sol`](src/libs/LimitOrderCommon.sol)) - See [README: Tick Discovery](./README.md#tick-discovery-bitmap-implementation): Active ticks tracked via bitmap structure for gas-efficient iteration. One bitmap per (poolKeyHash, coin) combination with word-based storage (256 ticks per uint256). Uses Uniswap's TickBitmap library for word-boundary traversal.
|
|
273
|
+
|
|
274
|
+
**Access Control** ([`SimpleAccessManaged.sol`](src/access/SimpleAccessManaged.sol)) - See [README: Access Control](./README.md#access-control-via-simpleaccessmanaged): Lightweight fork of OpenZeppelin's [AccessManaged](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessManaged) that removes time-based permissions. Protects `create()` and `setMaxFillCount()` via authority contract's `canCall()` interface. Fill operations have additional restrictions during pool unlock (only registered hooks).
|
|
275
|
+
|
|
276
|
+
**Liquidity Management** ([`LimitOrderLiquidity.sol`](src/libs/LimitOrderLiquidity.sol), [`LimitOrderCreate.sol`](src/libs/LimitOrderCreate.sol), [`LimitOrderWithdraw.sol`](src/libs/LimitOrderWithdraw.sol)) - See [README: Single-Sided Liquidity](./README.md#single-sided-liquidity): Orders implemented as Uniswap V4 liquidity positions across one-tick-spacing ranges using orderID as salt. Supports ERC20 and ETH, alternative payout currencies via swap paths, residual refunds, and fee distribution to makers/referrals.
|
|
277
|
+
|
|
278
|
+
**Unlock Callback Pattern** ([`ZoraLimitOrderBook.sol`](src/ZoraLimitOrderBook.sol)) - See [README: Component Interaction Flows](./README.md#component-interaction-flows): All state-changing operations occur within Uniswap V4's unlock callback mechanism. Three callback types: CREATE, FILL, WITHDRAW_ORDERS. All balance changes must be settled atomically before unlock completes.
|
|
279
|
+
|
|
280
|
+
**Token Accounting** ([`LimitOrderLiquidity.sol`](src/libs/LimitOrderLiquidity.sol)) - See [README: Component Interaction Flows](./README.md#component-interaction-flows): Handles ERC20 and native ETH transfers through pool manager's sync/settle/take pattern with balance verification before and after transfers.
|
|
281
|
+
|
|
282
|
+
**Gas Optimization** ([`LimitOrderFill.sol`](src/libs/LimitOrderFill.sol)): `maxFillCount` parameter limits orders processed per call. Bitmap optimization skips empty ticks. Assembly optimizations in hot loops. Multiple fill calls may be needed for large queues (100+ orders).
|
|
283
|
+
|
|
284
|
+
**Security Model** - See [README: Security Model & Guarantees](./README.md#5-security-model--guarantees): Documents protocol security guarantees, actor analysis, admin capabilities/limitations, and why `create()` is access controlled.
|
|
285
|
+
|
|
286
|
+
**DOS Prevention** - See [README: Gas Limits & DOS Prevention](./README.md#6-gas-limits--dos-prevention): Details on `maxFillCount` parameter, gas analysis from testing, and Fusaka/future hard fork considerations.
|
|
287
|
+
|
|
288
|
+
**Fill Execution Paths** - See [README: Fill Execution Paths](./README.md#4-fill-execution-paths): Documents the three distinct fill paths (auto-fill from hook, router fill, third-party fill), hook migration requirements, and universal Uniswap V4 compatibility.
|
|
289
|
+
|
|
290
|
+
## Code Statistics
|
|
291
|
+
|
|
292
|
+
**Solidity Code**:
|
|
293
|
+
|
|
294
|
+
- Core implementation: ~2,758 lines
|
|
295
|
+
- Primary contract: 220 lines
|
|
296
|
+
- Libraries: ~1,689 lines
|
|
297
|
+
- Interface: 195 lines
|
|
298
|
+
- Access control: 344 lines (SimpleAccessManaged + SimpleAccessManager)
|
|
299
|
+
- Router: 454 lines
|
|
300
|
+
|
|
301
|
+
**Test Files**: 6 test contracts in `packages/limit-orders/test/`
|
|
302
|
+
|
|
303
|
+
**Modified Existing Code**:
|
|
304
|
+
|
|
305
|
+
- ZoraV4CoinHook.sol: ~50-100 lines modified for integration
|
|
306
|
+
- Supporting libraries: TBD based on actual changes
|
|
307
|
+
|
|
308
|
+
**Note for Auditors**: Understanding the integration points will require familiarity with the existing Zora Coins protocol architecture (hooks, reward distribution, coin versioning). Auditors should account for time to review relevant portions of `packages/coins/` in their proposals.
|
|
309
|
+
|
|
310
|
+
## Audit Deliverables
|
|
311
|
+
|
|
312
|
+
We are looking for a comprehensive security assessment that includes:
|
|
313
|
+
|
|
314
|
+
- **Security findings** with severity classifications, impact analysis, and remediation recommendations
|
|
315
|
+
- **Integration risk assessment** focusing on Uniswap V4 interactions and Zora Coins protocol integration
|
|
316
|
+
- **Code quality analysis** including gas optimization opportunities and best practices
|
|
317
|
+
- **Testing artifacts** such as custom test cases, fuzzing results, or static analysis outputs developed during the audit
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
# PART 2: TECHNICAL IMPLEMENTATION
|
|
322
|
+
|
|
323
|
+
## File Structure
|
|
324
|
+
|
|
325
|
+
### Complete Package Organization
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
packages/limit-orders/src/
|
|
329
|
+
├── ZoraLimitOrderBook.sol (220 lines) - Main contract
|
|
330
|
+
├── IZoraLimitOrderBook.sol (195 lines) - Interface
|
|
331
|
+
├── access/
|
|
332
|
+
│ ├── SimpleAccessManaged.sol (76 lines) - Access control base
|
|
333
|
+
│ └── SimpleAccessManager.sol (268 lines) - Role-based access manager
|
|
334
|
+
├── libs/
|
|
335
|
+
│ ├── LimitOrderCreate.sol (277 lines) - Creation logic
|
|
336
|
+
│ ├── LimitOrderFill.sol (345 lines) - Fill logic (MOST COMPLEX)
|
|
337
|
+
│ ├── LimitOrderWithdraw.sol (100 lines) - Withdrawal logic
|
|
338
|
+
│ ├── LimitOrderStorage.sol (34 lines) - Storage layout
|
|
339
|
+
│ ├── LimitOrderTypes.sol (41 lines) - Type definitions
|
|
340
|
+
│ ├── LimitOrderCommon.sol (91 lines) - Common utilities
|
|
341
|
+
│ ├── LimitOrderQueues.sol (101 lines) - Linked list ops
|
|
342
|
+
│ ├── LimitOrderBitmap.sol (84 lines) - Bitmap tracking
|
|
343
|
+
│ ├── LimitOrderLiquidity.sol (222 lines) - Liquidity management
|
|
344
|
+
│ ├── SwapLimitOrders.sol (209 lines) - Config helper
|
|
345
|
+
│ └── Permit2Payments.sol (41 lines) - Permit2 support
|
|
346
|
+
└── router/
|
|
347
|
+
└── SwapWithLimitOrders.sol (454 lines) - Router contract
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
## Data Structures
|
|
351
|
+
|
|
352
|
+
For detailed documentation of data structures (LimitOrder struct, Queue struct, OrderStatus enum) and the tick queue system, see the [README.md](./README.md#tick-queue-system).
|
|
353
|
+
|
|
354
|
+
**Order ID Generation**: Deterministic hash of `keccak256(abi.encode(poolKeyHash, coin, tick, maker, nonce))` where nonce increments per maker.
|
|
355
|
+
(_Implementation detail_: `LimitOrderCreate.sol` hashes 5x 32-byte words, equivalent to `abi.encode(...)` rather than `abi.encodePacked(...)`.)
|
|
356
|
+
|
|
357
|
+
**Callback Data Structures** ([`IZoraLimitOrderBook.sol`](src/IZoraLimitOrderBook.sol)): OrderBatch, CreateCallbackData, FillCallbackData, WithdrawOrdersCallbackData
|
|
358
|
+
|
|
359
|
+
## Storage Organization
|
|
360
|
+
|
|
361
|
+
Uses diamond storage pattern at slot `0x98b43bb10ca7bc310641b07883d9e14c04b3983640df6b07dd1c99d10a3c6cec`. For details on storage layout and the diamond pattern implementation, see [`LimitOrderStorage.sol`](src/libs/LimitOrderStorage.sol) and [README.md](./README.md#diamond-storage-pattern).
|
|
362
|
+
|
|
363
|
+
## External Functions
|
|
364
|
+
|
|
365
|
+
_See [README: Order Creation Flow](./README.md#order-creation-flow) and [Withdrawal Flow](./README.md#withdrawal-flow) for detailed interaction diagrams_
|
|
366
|
+
|
|
367
|
+
See [`IZoraLimitOrderBook.sol`](src/IZoraLimitOrderBook.sol) for full signatures and documentation.
|
|
368
|
+
|
|
369
|
+
**`create()`** ([ZoraLimitOrderBook.sol:73-82](src/ZoraLimitOrderBook.sol#L73-L82)): Creates new limit order(s) by adding liquidity via `poolManager.modifyLiquidity()`. Requires authorization via SimpleAccessManaged. Generates order IDs, records in queues, sets bitmap bits, handles residual refunds.
|
|
370
|
+
|
|
371
|
+
**`fill()` - Range-based** ([ZoraLimitOrderBook.sol:85-127](src/ZoraLimitOrderBook.sol#L85-L127)): Fills orders within a tick range. Anyone can call; restricted to registered hooks during pool unlock. Bumps epoch, traverses bitmap for active ticks, processes orders, burns liquidity, distributes payouts.
|
|
372
|
+
|
|
373
|
+
**`fill()` - Order-specific** ([ZoraLimitOrderBook.sol:129-142](src/ZoraLimitOrderBook.sol#L129-L142)): Fills specific orders by ID. Operates on explicit order ID batches.
|
|
374
|
+
|
|
375
|
+
**`withdraw()`** ([ZoraLimitOrderBook.sol:141-147](src/ZoraLimitOrderBook.sol#L141-L147)): Cancel specific orders by ID. Takes `orderIds`, `coin`, `minAmountOut`, and `recipient` parameters. Validates ownership and status, burns liquidity, issues refunds.
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
# PART 3: ADDITIONAL INFORMATION
|
|
380
|
+
|
|
381
|
+
## Known Limitations
|
|
382
|
+
|
|
383
|
+
1. **Multi-block scenarios**: Epochs only prevent same-transaction, not cross-block
|
|
384
|
+
2. **Gas Limits**: Large queues (100s/1000s of orders) may need multiple fills
|
|
385
|
+
3. **No Partial Fills**: Orders fill completely or not at all
|
|
386
|
+
4. **Tick Spacing**: Limited by pool's tick spacing
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
# CONCLUSION
|
|
391
|
+
|
|
392
|
+
The Zora Limit Orders implementation uses sophisticated data structures (linked lists, bitmaps) to provide an onchain order book integrated with Uniswap V4.
|
|
393
|
+
|
|
394
|
+
## Next Steps for Auditors
|
|
395
|
+
|
|
396
|
+
1. Review this document and supporting docs ([README.md](./README.md), [SPEC.md](./SPEC.md), [AUDIT_NOTES.md](./AUDIT_NOTES.md))
|
|
397
|
+
2. Familiarize yourself with Uniswap V4 architecture if needed
|
|
398
|
+
3. Begin review with code hotspots identified in [AUDIT_NOTES.md](./AUDIT_NOTES.md#1-code-hotspots-fast-path)
|
|
399
|
+
4. Submit questions or clarifications as needed
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
**Document Version**: 1.2
|
|
404
|
+
**Last Updated**: 2025-12-12
|
|
405
|
+
**Based On**: Actual implementation in `packages/limit-orders/`
|
|
406
|
+
**Branch**: `autosell`
|
|
407
|
+
|
|
408
|
+
For questions or clarifications, please contact [Will Binns](mailto:will.binns@ourzora.com).
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @zoralabs/limit-orders
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c59a6fac: Initial release of limit orders protocol
|
|
8
|
+
|
|
9
|
+
Introduces a limit order system built on top of Uniswap V4 concentrated liquidity positions:
|
|
10
|
+
|
|
11
|
+
- **Orders as V4 Positions**: Each limit order is a single-tick-wide Uniswap V4 liquidity position, enabling makers to place orders at specific price points
|
|
12
|
+
- **FIFO Queue System**: Orders are organized in queues by `(poolKeyHash, coin, tick)` with bitmap-based tick tracking for efficient iteration
|
|
13
|
+
- **Epoch-Based Fill Protection**: Orders cannot be filled in the same epoch they were created, preventing same-transaction manipulation
|
|
14
|
+
|
|
15
|
+
**Fill Integration Modes:**
|
|
16
|
+
|
|
17
|
+
- **Auto-fill via Hook**: The Zora hook now calls `fill()` on the limit order book during `afterSwap`, automatically filling orders as swaps cross through their tick ranges
|
|
18
|
+
- **Router Fallback**: For legacy hooks, the router can call `fill()` post-swap
|
|
19
|
+
- **Third-party Fill**: Anyone can call `fill()` when the PoolManager is locked, incentivized by LP fee collection
|
|
20
|
+
|
|
21
|
+
**Fee Model:**
|
|
22
|
+
|
|
23
|
+
- Fill referrals receive accrued LP fees from filled positions
|
|
24
|
+
- Makers receive full proceeds on withdrawal
|
|
25
|
+
- Makers can cancel their limit orders to withdraw the backing currency
|