The threat scenario covered in this article is "attacker calls hooks directly on the hook contract".

The example illustrating such a vulnerability was based on the FullRange hook contract and can be found here.

This article is one of a series presenting various implementations of "Bad Hooks". This research is supported by the Uniswap Foundation Grant.

All presented bad hooks are drawn from the extensive threat modeling sessions. For a deeper understanding, refer to previous article detailing the possible threats originating from various Uniswap V4 hooks use cases.

Hook introduction

The FullRange hook contract is a liquidity pool manager that allows a Uniswap V4 pool to provide liquidity for a range of prices. Anyone can rebalance the Uniswap liquidity pool added by the contract to align it with the current price in the pool. This can be used to create a market maker for a volatile asset or to provide more liquidity for a thin market.

The rebalancing of the hook’s liquidity is achieved with the _rebalance function available here.

This article presents an existing vulnerability in the hook contract and the attacker’s scenario that exploits this vulnerability to lock tokens of other liquidity pools.

The problem

The FullRange hook contract implements three Uniswap V4 hooks. Let’s have a look at beforeInitialize hook function.

Can you see what’s the problem here?

The beforeInitialize hook

You are right. The problem is that anyone can call the beforeInitialize function. It should be callable only by the Uniswap V4 Pool Manager.

Attack scenario

The goal of this attack is to lock the tokens added previously by other liquidity providers, effectively leading to the loss of those tokens.

The PoC of the attack has been implemented in the test_abuser_FullRange_removeLiquidityForOverridenPool test and can be found here.

Step 1: The hook must be deployed and a new liquidity pool must be initialized using this hook.

The initialization of Uniswap V4 pool

Step 2: The legitimate liquidity provider (a victim) adds some liquidity to the pool via the FullRange hook. They want to add ideally 10 tokens (with 18 decimals) and at least 9 tokens.

Addind liquidity to Uniswap V4 pool

The test checks whether, after calling the addLiquidity function (that should add at least 9 of each tokens and ideally 10 tokens) those 10 tokens (both token0 and token1) were pulled from the liquidity provider.

Step 3: The attacker calls beforeInitialize function with the same key as the previously initialized pool.

Unauthorized call to beforeInitialize

The FullRange hook will create a new liquidity pool token and override the current one in poolInfo mapping (check out the implementation above). The original pool token is removed from the pool and no longer can be used to withdraw liquidity.

Step 4: The victim (liquidity provider) comes back to withdraw the liquidity, but the call to removeLiquidity function reverts, locking the victim's tokens.

Reverting call to removeLiquidity function

Why? When you look at the removeLiquidity function, you will notice that it burns the liquidity token of the provider. However, the liquidity token was overridden by the attacker and the victim does not possess any amount of the new token.

The removeLiquidity function

How to stay secure?

It's crucial to take security seriously when building Uniswap V4 hooks. Same as other DeFi projects, they control user’s funds and may put them at risk. That’s why it is important to stay security aware and build Uniswap V4 hooks based on best security practices.

To mitigate the risk described in this article, you should remember to correctly implement the access control for hook’s functions.

More things that can be done to keep Uniswap V4 hooks secure:

  • Use existing tools and security checklists to improve the security of your hooks. Check out the SCSVS C9: Uniswap V4 Hook checklist.
  • Do not release your hook without the security audit.

Whether you are building a Uniswap V4 hook or integrating with one, let us help you to make it secure!.

  • Did you like this article? Share it on social media!

Composable Security 🇵🇱⛓️ is a Polish company specializing in increasing the security of projects based on smart contracts written in Solidity. Examples of projects that have trusted us are market leaders such as FujiDAO, Enjin, Volmex Finance, DIVA Protocol or Tellor. We are creators of the Smart Contract Security Verification Standard. Speakers at various conferences such as EthCC, ETHWarsaw, or OWASP AppSec EU. Authors of numerous publications on DeFi security. Experienced auditors operating in the IT Security space since 2016.

Damian Rusinek

Damian Rusinek

Managing Partner & Smart Contract Security Auditor

About the author

PhD, Speaker, Co-Author of SCSVS and White Hat. Professionally dealing with security since 2009, contributing to the crypto space since 2017. Smart contract security research lead.

View all posts (13)