ลดขั้นการแบ่ง volume จาก 1 % เป็น 0.1 % ช่วยเฉพาะเทรดที่สภาพคล่องบาง — คู่ที่มีสภาพคล่องดีได้เพิ่มแค่ 0–0.5 bps แต่ 1,000 ETH → CAKE บน BNB ได้เพิ่ม +102 bps ทำใน SDK แล้วด้วยวิธี coarse-to-fine (~90 ms แทน 1.5–2 s) แต่ยังส่งขึ้น chain ไม่ได้ เพราะ router รับ _volumes เป็นเปอร์เซ็นต์จำนวนเต็ม
The split optimiser assigned whole-percent shares (100 steps). We re-ran the search on the same pool state at 1/200, 1/500 and 1/1000. On liquid pairs the 1 % grid is already within half a basis point of optimal; on a thin, large trade the fine grid spreads the order over 25 pools and gains a full percent. SDK 1.3.2 makes the grid configurable and reaches fine grids cheaply; executing them needs a router with sub-percent volumes.
| case | 1 % → 0.5 % | 1 % → 0.2 % | 1 % → 0.1 % | paths |
|---|---|---|---|---|
| HyperEVM · 100 / 1,000 HYPE → USDT0 | +0.00 bps | +0.00 | +0.00 | 4 / 3 |
| HyperEVM · 10,000 HYPE → USDT0 | +0.14 | +0.23 | +0.26 | 3 |
| HyperEVM · 10,000 USDT0 → WHYPE | +0.00 | +0.01 | +0.01 | 6 → 7 |
| BNB · 1,000 BNB → USDT | +0.18 | +0.40 | +0.50 | 5 → 15 |
| BNB · 100 ETH → CAKE | +0.50 | +0.87 | +1.05 | 7 → 11 |
| BNB · 1,000 ETH → CAKE | +44.8 | +92.2 | +101.9 | 13 → 25 |
Pool state fetched once per pair (maxStateAgeMs) and re-optimised at each grid, so the grid is the only variable. Twelve of the 25 paths on the big case hold 0.1–0.5 % each: shares a 1 % grid cannot express.
Evaluating every candidate path at every 0.1 % step costs 20 × 1,000 path simulations plus a large knapsack: 1.5–2 s per quote on BNB. Instead, 1.3.2 computes the exact 1 % optimum as before, then re-evaluates only a ±2 % window around each path's share (and 0–2 % for the other candidates) on the fine grid and re-optimises. On every benchmark case it reproduced the full-grid optimum (+101.85 vs +101.86 bps) in ~90 ms.
| case | full 0.1 % grid | coarse-to-fine | same result? |
|---|---|---|---|
| BNB · 1,000 ETH → CAKE | 1,490 ms | 96 ms | yes |
| BNB · 1,000 BNB → USDT | 2,127 ms | 93 ms | yes |
| HyperEVM · 1,000 USDT0 → WHYPE | 1,187 ms | 28 ms | yes |
The knapsack itself was rewritten (back-pointers, double-precision values, exact bigint re-sum), which also made the plain 1 % search 20–30 % faster. Regression A/B 1.3.1 vs 1.3.2 at the default grid: 0.00 bps, same paths, 18/18 cases.
_volumes as integer percent. A 0.1 % split cannot be sent to it. 1.3.2 keeps the default at 1 %, lets integrators quote on finer grids (splitResolution), exposes volumeUnits / volumeDenominator, and makes swap() refuse a fine-grid quote instead of rounding it into a different split than the one quoted.To capture the gain on-chain the router needs _volumes in a finer unit (basis points) or, simpler, absolute source amounts per path. After that, routerVolumeDenominator: 1000 unlocks execution with no other SDK change. Try it on Moro Swap: tick "0.1 % split grid (quote only)" and quote 1,000 ETH → CAKE on BNB Chain.
Write-up: benchmark/rounds/3.md, reproduce with benchmark/split-resolution.ts — korrio/moro-sdk-optimized.