Believe it or not, Uniswap v4 will soon meet everyone!
This time, the Uniswap team has set ambitious goals and plans to introduce many new features, including unlimited number of liquidity pools and dynamic fees for each trading pair, singleton design, flash accounting, Hook, and support for ERC1155 token standard. Utilizing the transient storage introduced by EIP-1153, Uniswap v4 is expected to be released after the Ethereum Cancun upgrade. Among the many innovations, the Hook mechanism has gained wide attention due to its powerful potential. The Hook mechanism allows specific code to be executed at specific points in the lifecycle of a liquidity pool, greatly enhancing the scalability and flexibility of the pools. However, the Hook mechanism can also be a double-edged sword. While it is powerful and flexible, safely using Hook is also a significant challenge. The complexity of Hook inevitably brings new potential attack vectors. Therefore, we hope to write a series of articles to systematically introduce the security issues and potential risks related to the Hook mechanism, in order to promote the security development of the community. We believe that these insights will help build secure Uniswap v4 Hooks. As the opening article of this series, this article introduces the concepts related to the Hook mechanism in Uniswap v4 and outlines the security risks associated with the Hook mechanism.
Before diving deeper, we need a basic understanding of the mechanisms behind Uniswap v4. According to the official announcement [1] and whitepaper [2], Hooks, singleton architecture, and flash accounting are three important features that enable customized liquidity pools and efficient routing across multiple pools.
Hooks refer to contracts that run at different stages of a liquidity pool’s lifecycle. The Uniswap team hopes to enable anyone to make tradeoff decisions by introducing Hooks. This way, native support for dynamic fees, on-chain limit orders, or time-weighted average market makers (TWAMMs) to split up large orders can be implemented. Currently, there are eight callback Hooks, divided into four pairs (each pair contains one before and one after callback):
Below is the flow of the swap Hook introduced in the whitepaper [2].
Figure 1: Flow of Swap Hook
The Uniswap team demonstrated the methodology with some examples (e.g. TWAMM Hook [3]), and community participants have also made contributions. The official documentation [4] also links to the Awesome Uniswap v4 Hooks [5] repository, which collects more Hook examples.
The singleton architecture and flash accounting aim to improve performance by reducing costs and ensuring efficiency. It introduces a new singleton contract where all liquidity pools are stored in the same smart contract. This singleton design relies on a PoolManager to store and manage the state of all pools. In earlier versions of the Uniswap protocol, operations like swapping or adding liquidity involved direct token transfers. Version 4 is different in that it introduces flash accounting and a lock mechanism.
👇🏻 The lock mechanism works as follows: 1. A locker contract requests a lock from the PoolManager. 2.The PoolManager adds the locker contract’s address to the lockData queue and calls its lockAcquired callback. 3. The locker contract executes its logic in the callback. Interactions with the pool during execution may result in non-zero currency increments. However, by the end of execution, all increments must net to zero. Additionally, if the lockData queue is non-empty, only the last locker contract can execute operations. 4. The PoolManager checks the state of the lockData queue and currency increments. After verification, the PoolManager removes the locker contract.
In summary, the lock mechanism prevents concurrent access and ensures all transactions can be settled. Locker contracts request locks in sequence, then execute trades via the lockAcquired callback. Corresponding Hook callbacks are triggered before and after each pool operation. Finally, the PoolManager checks states. This means operations adjust internal net balances (i.e. delta) rather than performing instant transfers. Any modifications are recorded in the pool’s internal balances, with actual transfers occurring when the operation (i.e. lock) concludes. This process guarantees no outstanding tokens, maintaining funds integrity. Due to the lock mechanism, external owned accounts (EOAs) cannot interact directly with the PoolManager. Instead, any interaction must go through a contract. This contract acts as an intermediary locker, requesting a lock before conducting any pool operations. (12/08)
👇🏻 There are two main contract interaction scenarios:
Before discussing related security issues, we need to establish the threat model. We primarily consider the following two cases:
In the following sections, we will discuss potential security issues according to these two threat models.
Threat Model I focuses on vulnerabilities associated with the Hook itself. This threat model assumes the developer and their Hook are not malicious. However, existing known vulnerabilities in smart contracts may also appear in Hooks. For example, if a Hook is implemented as an upgradeable contract, it may encounter issues related to vulnerabilities like the OpenZeppelin UUPSUpgradeable one. Given the above factors, we choose to focus on potential vulnerabilities unique to version 4. In Uniswap v4, Hooks are smart contracts that can execute custom logic before or after core pool operations (including initialization, position modification, swapping, and collection). Although Hooks are expected to implement a standard interface, they also allow for custom logic. Therefore, our discussion will be limited to logic involving the standard Hook interfaces. We will then try to identify potential sources of vulnerabilities, e.g. how Hooks might abuse these standard Hook functions.
👇🏻 Specifically, we will focus on the following two types of Hooks:
Note that hooks outside these two scopes are not discussed here. Since there are no real-world Hook use cases at the time of this writing, we will take some information from the Awesome Uniswap v4 Hooks repository. After an in-depth study of the Awesome Uniswap v4 Hooks repository (commit hash 3a0a444922f26605ec27a41929f3ced924af6075), we identified several severe vulnerabilities. These vulnerabilities stem mainly from risky interactions between the hook, PoolManager, and external third parties, and can be divided into two categories: access control issues and input validation issues. Specific findings are shown in the table below:
In summary, we identified 22 relevant projects (excluding those unrelated to Uniswap v4). Among these projects, we believe 8 (36%) have vulnerabilities. Among the 8 vulnerable projects, 6 have access control issues and 2 are vulnerable to untrusted external calls.
In this part of the discussion, we mainly focus on issues callback functions in v4 may cause, including the 8 hook callbacks and the lock callback. Of course there are other cases that need verification but they vary by design and are currently out of scope. These functions should only be callable by the PoolManager, not other addresses (including EOAs and contracts). For example, in the case where rewards are distributed from the pool’s keys, the rewards could be incorrectly claimed if the corresponding functions were callable by arbitrary accounts. Therefore, establishing strong access control mechanisms is crucial for hooks since they can be invoked by parties other than the pools themselves. By strictly governing access permissions, liquidity pools can significantly reduce risks associated with unauthorized or malicious interactions with hooks.
In Uniswap v4, due to the lock mechanism, users must obtain a lock through a contract before executing any pool operations. This ensures the currently interacting contract is the latest locker contract. Nonetheless, there still exists a potential attack scenario of untrusted external calls due to improper input validation in some vulnerable Hook implementations:
Untrusted external calls are extremely dangerous as they can lead to various types of attacks including the well-known reentrancy attacks. To attack these vulnerable hooks, the attacker can register a malicious pool with fake tokens for themselves, then invoke the hook to execute operations on the pool. When interacting with the pool, malicious token logic hijacks control flow for misconduct.
To circumvent such hook-related security issues, it is critical to properly execute necessary access control on sensitive external/public functions and validate inputs to verify interactions. Additionally, reentrancy guards may help ensure hooks are not re-entered during standard logic flows. By implementing proper security safeguards, pools can reduce risks associated with such threats.
In this threat model, we assume the developer and their hook are malicious. Given the broad scope, we only focus on security issues related to version 4. The key then lies in whether hooks provided can handle user transfers or authorizations of cryptocurrencies. Since the method of accessing hooks determines permissions that may be granted to hooks, we categorize hooks into two types based on this:
Figure 2:Example of malicious hook
In this case, users’ cryptocurrency assets (including native tokens and other tokens) are transferred or approved to the router. Since the PoolManager performs balance checks, malicious hooks do not easily directly steal these assets. However, potential attack surfaces still exist. For example, the fee management mechanism in version 4 may be manipulated by an attacker via hooks.
When hooks are used as entry points, the situation becomes more complex. Here, since users can interact directly with the hook, the hook is granted more power. In theory, the hook can execute any desired operations through such interactions. In version 4, verification of code logic is extremely critical. The main issue is whether the code logic can be manipulated. If the hook is upgradeable, this means a hook that appears secure may turn malicious after an upgrade, posing significant risks. These risks include:
An essential point is assessing whether hooks are malicious. Specifically, for managed hooks we should look out for fee management behavior; while for standalone hooks, the main focus is on whether they are upgradeable.
In this article, we first briefly outlined the core mechanisms related to Uniswap v4 Hook security issues. We then proposed two threat models and briefly outlined associated security risks. In follow-up articles, we will conduct in-depth analyses on the security issues under each threat model. Stay tuned!
References
[1] Our Vision for Uniswap V4
https://blog.uniswap.org/uniswap-v4
[2] Uniswap v4 whitepaper draft
https://github.com/Uniswap/v4-core/blob/main/whitepaper-v4-draft.pdf
[3] Uniswap v4 TWAMM Hook
https://blog.uniswap.org/v4-twamm-hook
[4] Hook Examples
https://docs.uniswapfoundation.org/hooks/hook-examples
[5] Awesome Uniswap v4 Hooks
https://github.com/fewwwww/awesome-uniswap-hooks
[6] UUPSUpgradeable Vulnerability Post-mortem
https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680
About BlockSec BlockSec is a leading global blockchain security company founded in 2021 by renowned experts in the security industry. The company is dedicated to enhancing security and usability for the Web3 world to promote widespread adoption of Web3. To achieve this, BlockSec provides smart contract and EVM chain security auditing services, a security development, testing, and hacker interception system called Phalcon for project owners, a fund tracking and investigation platform called MetaSleuth, as well as efficiency plugins for web3 builders called MetaDock. Currently, the company has served over 300 clients, including well-known projects such as MetaMask, Compound, Uniswap Foundation, Forta, PancakeSwap, and has received two rounds of funding totaling over tens of millions of dollars from investment institutions such as Oasis Capital, IDG Capital, and Distributed Capital. Homepage:www.blocksec.com
Twitter:https://twitter.com/BlockSecTeam
Phalcon: https://phalcon.xyz/
MetaSleuth: https://metasleuth.io/
MetaDock: https://blocksec.com/metadock
Believe it or not, Uniswap v4 will soon meet everyone!
This time, the Uniswap team has set ambitious goals and plans to introduce many new features, including unlimited number of liquidity pools and dynamic fees for each trading pair, singleton design, flash accounting, Hook, and support for ERC1155 token standard. Utilizing the transient storage introduced by EIP-1153, Uniswap v4 is expected to be released after the Ethereum Cancun upgrade. Among the many innovations, the Hook mechanism has gained wide attention due to its powerful potential. The Hook mechanism allows specific code to be executed at specific points in the lifecycle of a liquidity pool, greatly enhancing the scalability and flexibility of the pools. However, the Hook mechanism can also be a double-edged sword. While it is powerful and flexible, safely using Hook is also a significant challenge. The complexity of Hook inevitably brings new potential attack vectors. Therefore, we hope to write a series of articles to systematically introduce the security issues and potential risks related to the Hook mechanism, in order to promote the security development of the community. We believe that these insights will help build secure Uniswap v4 Hooks. As the opening article of this series, this article introduces the concepts related to the Hook mechanism in Uniswap v4 and outlines the security risks associated with the Hook mechanism.
Before diving deeper, we need a basic understanding of the mechanisms behind Uniswap v4. According to the official announcement [1] and whitepaper [2], Hooks, singleton architecture, and flash accounting are three important features that enable customized liquidity pools and efficient routing across multiple pools.
Hooks refer to contracts that run at different stages of a liquidity pool’s lifecycle. The Uniswap team hopes to enable anyone to make tradeoff decisions by introducing Hooks. This way, native support for dynamic fees, on-chain limit orders, or time-weighted average market makers (TWAMMs) to split up large orders can be implemented. Currently, there are eight callback Hooks, divided into four pairs (each pair contains one before and one after callback):
Below is the flow of the swap Hook introduced in the whitepaper [2].
Figure 1: Flow of Swap Hook
The Uniswap team demonstrated the methodology with some examples (e.g. TWAMM Hook [3]), and community participants have also made contributions. The official documentation [4] also links to the Awesome Uniswap v4 Hooks [5] repository, which collects more Hook examples.
The singleton architecture and flash accounting aim to improve performance by reducing costs and ensuring efficiency. It introduces a new singleton contract where all liquidity pools are stored in the same smart contract. This singleton design relies on a PoolManager to store and manage the state of all pools. In earlier versions of the Uniswap protocol, operations like swapping or adding liquidity involved direct token transfers. Version 4 is different in that it introduces flash accounting and a lock mechanism.
👇🏻 The lock mechanism works as follows: 1. A locker contract requests a lock from the PoolManager. 2.The PoolManager adds the locker contract’s address to the lockData queue and calls its lockAcquired callback. 3. The locker contract executes its logic in the callback. Interactions with the pool during execution may result in non-zero currency increments. However, by the end of execution, all increments must net to zero. Additionally, if the lockData queue is non-empty, only the last locker contract can execute operations. 4. The PoolManager checks the state of the lockData queue and currency increments. After verification, the PoolManager removes the locker contract.
In summary, the lock mechanism prevents concurrent access and ensures all transactions can be settled. Locker contracts request locks in sequence, then execute trades via the lockAcquired callback. Corresponding Hook callbacks are triggered before and after each pool operation. Finally, the PoolManager checks states. This means operations adjust internal net balances (i.e. delta) rather than performing instant transfers. Any modifications are recorded in the pool’s internal balances, with actual transfers occurring when the operation (i.e. lock) concludes. This process guarantees no outstanding tokens, maintaining funds integrity. Due to the lock mechanism, external owned accounts (EOAs) cannot interact directly with the PoolManager. Instead, any interaction must go through a contract. This contract acts as an intermediary locker, requesting a lock before conducting any pool operations. (12/08)
👇🏻 There are two main contract interaction scenarios:
Before discussing related security issues, we need to establish the threat model. We primarily consider the following two cases:
In the following sections, we will discuss potential security issues according to these two threat models.
Threat Model I focuses on vulnerabilities associated with the Hook itself. This threat model assumes the developer and their Hook are not malicious. However, existing known vulnerabilities in smart contracts may also appear in Hooks. For example, if a Hook is implemented as an upgradeable contract, it may encounter issues related to vulnerabilities like the OpenZeppelin UUPSUpgradeable one. Given the above factors, we choose to focus on potential vulnerabilities unique to version 4. In Uniswap v4, Hooks are smart contracts that can execute custom logic before or after core pool operations (including initialization, position modification, swapping, and collection). Although Hooks are expected to implement a standard interface, they also allow for custom logic. Therefore, our discussion will be limited to logic involving the standard Hook interfaces. We will then try to identify potential sources of vulnerabilities, e.g. how Hooks might abuse these standard Hook functions.
👇🏻 Specifically, we will focus on the following two types of Hooks:
Note that hooks outside these two scopes are not discussed here. Since there are no real-world Hook use cases at the time of this writing, we will take some information from the Awesome Uniswap v4 Hooks repository. After an in-depth study of the Awesome Uniswap v4 Hooks repository (commit hash 3a0a444922f26605ec27a41929f3ced924af6075), we identified several severe vulnerabilities. These vulnerabilities stem mainly from risky interactions between the hook, PoolManager, and external third parties, and can be divided into two categories: access control issues and input validation issues. Specific findings are shown in the table below:
In summary, we identified 22 relevant projects (excluding those unrelated to Uniswap v4). Among these projects, we believe 8 (36%) have vulnerabilities. Among the 8 vulnerable projects, 6 have access control issues and 2 are vulnerable to untrusted external calls.
In this part of the discussion, we mainly focus on issues callback functions in v4 may cause, including the 8 hook callbacks and the lock callback. Of course there are other cases that need verification but they vary by design and are currently out of scope. These functions should only be callable by the PoolManager, not other addresses (including EOAs and contracts). For example, in the case where rewards are distributed from the pool’s keys, the rewards could be incorrectly claimed if the corresponding functions were callable by arbitrary accounts. Therefore, establishing strong access control mechanisms is crucial for hooks since they can be invoked by parties other than the pools themselves. By strictly governing access permissions, liquidity pools can significantly reduce risks associated with unauthorized or malicious interactions with hooks.
In Uniswap v4, due to the lock mechanism, users must obtain a lock through a contract before executing any pool operations. This ensures the currently interacting contract is the latest locker contract. Nonetheless, there still exists a potential attack scenario of untrusted external calls due to improper input validation in some vulnerable Hook implementations:
Untrusted external calls are extremely dangerous as they can lead to various types of attacks including the well-known reentrancy attacks. To attack these vulnerable hooks, the attacker can register a malicious pool with fake tokens for themselves, then invoke the hook to execute operations on the pool. When interacting with the pool, malicious token logic hijacks control flow for misconduct.
To circumvent such hook-related security issues, it is critical to properly execute necessary access control on sensitive external/public functions and validate inputs to verify interactions. Additionally, reentrancy guards may help ensure hooks are not re-entered during standard logic flows. By implementing proper security safeguards, pools can reduce risks associated with such threats.
In this threat model, we assume the developer and their hook are malicious. Given the broad scope, we only focus on security issues related to version 4. The key then lies in whether hooks provided can handle user transfers or authorizations of cryptocurrencies. Since the method of accessing hooks determines permissions that may be granted to hooks, we categorize hooks into two types based on this:
Figure 2:Example of malicious hook
In this case, users’ cryptocurrency assets (including native tokens and other tokens) are transferred or approved to the router. Since the PoolManager performs balance checks, malicious hooks do not easily directly steal these assets. However, potential attack surfaces still exist. For example, the fee management mechanism in version 4 may be manipulated by an attacker via hooks.
When hooks are used as entry points, the situation becomes more complex. Here, since users can interact directly with the hook, the hook is granted more power. In theory, the hook can execute any desired operations through such interactions. In version 4, verification of code logic is extremely critical. The main issue is whether the code logic can be manipulated. If the hook is upgradeable, this means a hook that appears secure may turn malicious after an upgrade, posing significant risks. These risks include:
An essential point is assessing whether hooks are malicious. Specifically, for managed hooks we should look out for fee management behavior; while for standalone hooks, the main focus is on whether they are upgradeable.
In this article, we first briefly outlined the core mechanisms related to Uniswap v4 Hook security issues. We then proposed two threat models and briefly outlined associated security risks. In follow-up articles, we will conduct in-depth analyses on the security issues under each threat model. Stay tuned!
References
[1] Our Vision for Uniswap V4
https://blog.uniswap.org/uniswap-v4
[2] Uniswap v4 whitepaper draft
https://github.com/Uniswap/v4-core/blob/main/whitepaper-v4-draft.pdf
[3] Uniswap v4 TWAMM Hook
https://blog.uniswap.org/v4-twamm-hook
[4] Hook Examples
https://docs.uniswapfoundation.org/hooks/hook-examples
[5] Awesome Uniswap v4 Hooks
https://github.com/fewwwww/awesome-uniswap-hooks
[6] UUPSUpgradeable Vulnerability Post-mortem
https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680
About BlockSec BlockSec is a leading global blockchain security company founded in 2021 by renowned experts in the security industry. The company is dedicated to enhancing security and usability for the Web3 world to promote widespread adoption of Web3. To achieve this, BlockSec provides smart contract and EVM chain security auditing services, a security development, testing, and hacker interception system called Phalcon for project owners, a fund tracking and investigation platform called MetaSleuth, as well as efficiency plugins for web3 builders called MetaDock. Currently, the company has served over 300 clients, including well-known projects such as MetaMask, Compound, Uniswap Foundation, Forta, PancakeSwap, and has received two rounds of funding totaling over tens of millions of dollars from investment institutions such as Oasis Capital, IDG Capital, and Distributed Capital. Homepage:www.blocksec.com
Twitter:https://twitter.com/BlockSecTeam
Phalcon: https://phalcon.xyz/
MetaSleuth: https://metasleuth.io/
MetaDock: https://blocksec.com/metadock