James Bachini

Uniswap v4 Hooks

Uniswap V4

Hooks in Uniswap v4 are external contracts that execute specific actions at certain points during the execution of a liquidity pool. These hooks provide flexibility and customization options for developers to create additional features for liquidity pools.

Uniswap v4 Hooks

Uniswap v4 hooks can be used to:

  • Execute large orders gradually over time using TWAMM (Time-Weighted Average Market Making)
  • Implement on-chain limit orders that fill at specific prices
  • Adjust fees dynamically based on market volatility or price movements
  • Develop mechanisms to prevent or syphon MEV for liquidity providers
  • Create custom oracle implementations (Uniswap TWAP price lookup is no longer implemented as default)
  • Execute malicious code, users need to be careful about which pools they interact with

A 3rd party developer can write a solidity hook contract with custom logic prior to setting up the pool. When the liquidity pool is created on Uniswap v4, the hook contract can be specified.

Uniswap v4 currently supports eight different hook callbacks:

  • beforeInitialize
  • afterInitialize
  • beforeModifyPosition
  • afterModifyPosition
  • beforeSwap
  • afterSwap
  • beforeDonate
  • afterDonate

The donate hooks run before and after donate() is called which transfers fees to the pool at the end of the transaction. Uniswap v4 enables fees to be charged for both swapping and withdrawing liquidity

The capabilities of a hook are determined by immutable flags set when the pool is created.

There are example hooks published by the Uniswap team at: https://github.com/Uniswap/v4-periphery/tree/main/contracts/hooks/examples

And some code that I’ve been playing with here: https://github.com/jamesbachini/Uniswap-v4-Tests

We start by importing relevant libraries including the v4-core Hooks.sol

import {Hooks} from "@uniswap/v4-core/contracts/libraries/Hooks.sol";

We can then overwrite the getHooksCalls() function to declare what hooks we wish to activate.

function getHooksCalls() public pure override returns (Hooks.Calls memory) {
    return Hooks.Calls({
        beforeInitialize: false,
        afterInitialize: false,
        beforeModifyPosition: false,
        afterModifyPosition: false,
        beforeSwap: true,
        afterSwap: false,
        beforeDonate: false,
        afterDonate: false
    });
}

We can then overwrite the beforeSwap function

function beforeSwap(
    address,
    IPoolManager.PoolKey calldata key,
    IPoolManager.SwapParams calldata
) external override poolManagerOnly returns (bytes4) {
    // doSomethingInteresting
    return ThisContract.beforeSwap.selector;
}

We return the 4 byte selector for the function after our code executes.

Uniswap v4 hooks provide Solidity developers with a lot more power to create liquidity pools with custom logic and functionality. There are security concerns around how users are exposed to that custom logic which could potentially contain malicious code. For devs it provides an opportunity to more closely integrate DeFi protocols with the largest decentralized exchange and create new systems for efficient liquidity.


Get The Blockchain Sector Newsletter, binge the YouTube channel and connect with me on Twitter

The Blockchain Sector newsletter goes out a few times a month when there is breaking news or interesting developments to discuss. All the content I produce is free, if you’d like to help please share this content on social media.

Thank you.

James Bachini

Disclaimer: Not a financial advisor, not financial advice. The content I create is to document my journey and for educational and entertainment purposes only. It is not under any circumstances investment advice. I am not an investment or trading professional and am learning myself while still making plenty of mistakes along the way. Any code published is experimental and not production ready to be used for financial transactions. Do your own research and do not play with funds you do not want to lose.