Index / Limit order
pattern · UNLICENSED · last updated 2026-08-27
Limit order
Rest liquidity at a tick and fill it in afterSwap when the pool trades through that price.
Uniswap’s LimitOrder example records the last tick on afterInitialize. On afterSwap it walks ticks the swap just crossed and fills any epoch resting at those ticks by removing that one-tick-wide liquidity. Users call place() to add an order; withdraw() after Fill. Flags must be afterInitialize + afterSwap. This is the example-contracts file, UNLICENSED, not a production CLOB. Production forks add cancel, partial fill, and gas accounting. Copy the full Solidity from the permalink. Listing is not an audit.
Permission bits
These bits must match the deployed address. Confirm on-chain before you route.
afterInitializeafterSwap
Solidity
Excerpt from contracts/hooks/examples/LimitOrder.sol. Copy the full file to implement this. Not an audit.
// SPDX-License-Identifier: UNLICENSED
function getHookPermissions() public pure override returns (Hooks.Permissions memory) {
return Hooks.Permissions({
beforeInitialize: false,
afterInitialize: true,
beforeAddLiquidity: false,
beforeRemoveLiquidity: false,
afterAddLiquidity: false,
afterRemoveLiquidity: false,
beforeSwap: false,
afterSwap: true,
beforeDonate: false,
afterDonate: false,
beforeSwapReturnDelta: false,
afterSwapReturnDelta: false,
afterAddLiquidityReturnDelta: false,
afterRemoveLiquidityReturnDelta: false
});
}
function afterSwap(
address,
PoolKey calldata key,
IPoolManager.SwapParams calldata params,
BalanceDelta,
bytes calldata
) external override onlyByManager returns (bytes4, int128) {
(int24 tickLower, int24 lower, int24 upper) = _getCrossedTicks(key.toId(), key.tickSpacing);
if (lower > upper) return (LimitOrder.afterSwap.selector, 0);
bool zeroForOne = !params.zeroForOne;
for (; lower <= upper; lower += key.tickSpacing) {
_fillEpoch(key, lower, zeroForOne);
}
setTickLowerLast(key.toId(), tickLower);
return (LimitOrder.afterSwap.selector, 0);
}Spec
| Kind | pattern |
|---|---|
| Status | experimental |
| License | UNLICENSED |
| Source | https://github.com/Uniswap/v4-periphery |
| Categories | Limit orders |
| Properties | Vanilla swap |
| Chains | Ethereum |
| Docs | https://docs.uniswap.org/contracts/v4/concepts/hooks |
FAQ
Can I paste this into production? The snippet is an excerpt. Use the full file at the source URL, match flags to the address, and treat this page as a map, not a guarantee.
How do I build this safely? Start with secure v4 hooks and the OpenZeppelin hooks guide.