V4HOOKSCUT SHEET DIRECTORY

Index / LimitOrderHook

pattern · MIT · last updated 2026-08-27

LimitOrderHook

Place out-of-range liquidity, fill on afterSwap tick cross, cancel or withdraw via unlock.

OpenZeppelin’s LimitOrderHook (MIT) is the library-shaped fill-on-cross. afterInitialize stores last tick; afterSwap walks crossed ticks and _fillOrder. Users call placeOrder, cancelOrder, and withdraw through unlockCallback. Fees accrue per liquidity unit so late joiners do not steal earlier fees. Compare with Uniswap’s UNLICENSED LimitOrder example — this file adds cancel and fee accounting. Experimental library code. Copy the full file from the permalink. Listing is not an audit.

Permission bits

These bits must match the deployed address. Confirm on-chain before you route.

Initialize
ba
Liquidity
baba
Swap
ba
Donate
ba
Return delta
baaa

afterInitializeafterSwap

Solidity

Excerpt from src/general/LimitOrderHook.sol. Copy the full file to implement this. Not an audit.

// SPDX-License-Identifier: MIT
// OpenZeppelin Uniswap Hooks — excerpt. Full file: source.url
function getHookPermissions() public pure virtual override returns (Hooks.Permissions memory permissions) {
    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, SwapParams calldata params, BalanceDelta, bytes calldata)
    internal
    virtual
    override
    returns (bytes4, int128)
{
    (int24 tickLower, int24 lower, int24 upper) = _getCrossedTicks(key.toId(), key.tickSpacing);
    if (lower > upper) return (this.afterSwap.selector, 0);
    _tickLowerLasts[key.toId()] = tickLower;
    bool zeroForOne = !params.zeroForOne;
    for (; lower <= upper; lower += key.tickSpacing) {
        _fillOrder(key, lower, zeroForOne);
    }
    return (this.afterSwap.selector, 0);
}

Spec

Kindpattern
Statusexperimental
LicenseMIT
Sourcehttps://github.com/OpenZeppelin/uniswap-hooks
CategoriesLimit orders
PropertiesVanilla swap
ChainsEthereum
Websitehttps://v4hooks.com/learn/openzeppelin-hooks
Docshttps://github.com/OpenZeppelin/uniswap-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.