Get early access

Order Split

Split one order across N pools. Run the legs in parallel. Recombine against a floor, or revert the whole script.

LiquidityRoutingAtomic
How it runsBase mainnet · 8453
Inputs
pools=[poolA, poolB, poolC, poolD]tokenIn=USDCtokenOut=WETHamount=250,000minOut=99.8
In-transaction
01Split amount across N pools by computed weights4 legs
02Execute N swaps in parallel4 calls
03Recombine outputs into single resultΣ legs
04Require: sum(out) ≥ minOut
true → return totalfalse → REVERT WHOLE SCRIPT
Result
1 tx · N legs · all-or-nothing
order-split.sauce.ts
Base · 8453READ-ONLY
1import { IERC20 } from "@openzeppelin/contracts/build/contracts/IERC20.json";2import { IV3SwapRouter } from "@uniswap/swap-router-contracts/artifacts/contracts/interfaces/IV3SwapRouter.sol/IV3SwapRouter.json";3import { IUniswapV3Pool } from "@uniswap/v3-core/artifacts/contracts/interfaces/IUniswapV3Pool.sol/IUniswapV3Pool.json";45// Split one order across two Uniswap V3 pools, weighting each leg by the6// pool's live liquidity, swap both legs via SwapRouter02, then require the7// combined output clears the floor — all inside one transaction. Router is8// fixed (Base mainnet); the tokens, amount, caller, pools and floor are9// parameters.1011function main(12 tokenIn: Address, tokenOut: Address, amountIn: Uint256, caller: Address,13 pool1Addr: Address, pool2Addr: Address, minOut: Uint256,14): Uint256 {15 const router: Address = 0x2626664c2603336E57B271c5C0b26F421741e481;1617 // Pull the input tokens in and let the router spend them.18 const token = IERC20.at(tokenIn);19 token.transferFrom(caller, address.self, amountIn);20 token.approve(router, amountIn);2122 // Weight the split by each pool's live liquidity at inclusion.23 const liqA: Uint256 = IUniswapV3Pool.at(pool1Addr).liquidity();24 const liqB: Uint256 = IUniswapV3Pool.at(pool2Addr).liquidity();25 const liqTotal: Uint256 = liqA + liqB;26 if (liqTotal === 0) throw "no liquidity";2728 const legA: Uint256 = (amountIn * liqA) / liqTotal;29 const legB: Uint256 = amountIn - legA;3031 const feeA: Uint256 = IUniswapV3Pool.at(pool1Addr).fee();32 const feeB: Uint256 = IUniswapV3Pool.at(pool2Addr).fee();3334 // Swap each leg. Keys a-g sort alphabetically onto ExactInputSingleParams:35 // a=tokenIn, b=tokenOut, c=fee, d=recipient, e=amountIn, f=amountOutMinimum, g=sqrtPriceLimitX9636 const r = IV3SwapRouter.at(router);37 const outA: Uint256 = r.exactInputSingle({ a: tokenIn, b: tokenOut, c: feeA, d: caller, e: legA, f: 0, g: 0 });38 const outB: Uint256 = r.exactInputSingle({ a: tokenIn, b: tokenOut, c: feeB, d: caller, e: legB, f: 0, g: 0 });3940 // Recombine and enforce the floor across the whole order.41 const outTotal: Uint256 = outA + outB;42 if (outTotal < minOut) throw "min out not met";43 return outTotal;44}
Try it liveLive on Base mainnet
01Connect wallet
Loading…
02Configure inputs
Connect wallet to continue
03Compile
Compile to continue
04Execute
Compile first

About

Order split takes a large order, splits it across N pools by depth, and runs the legs in parallel. The outputs recombine into a single number that has to clear a floor; if not, the whole script reverts. No partial fills, no orphaned approvals.

When to use this

  • Large-size swap routes that exceed any single pool
  • Treasury rebalances priced against an exit minimum
  • Cross-venue aggregation with whole-script revert on shortfall