The threat scenario covered in this article is "malicious hook owner updates the oracle parameters resulting in invalid price".
The example illustrating such a vulnerability was based on the EulerMedianOracle
hook that can be found here.
This article is one of a series where we present some implementations of "Bad Hooks" as part of our research supported by the Uniswap Foundation Grant.
All presented bad hooks are drawn from the extensive threat modeling sessions conducted throughout our research. For a deeper understanding, refer to our previous article detailing the possible threats originating from various use cases.
Hook introduction
The EulerMedianOracle
hook contract implements an alternative to the TWAP oracle that saves the current tick on each swap. It calculates the price similarly to the median oracle created by the Euler protocol. This approach mitigates some security risks as when using TWAP: "lower-liquidity pools are prone to manipulation".
Additionally, the hook has a function that allows you to get the median price within a given time period. Here you can find the original implementation: EulerMedianOracle.sol
For the purpose of this article, we have created an updated custom hook implementation, BadEulerMedianOracle
, with a backdoor that allows the hook owner to update the saved tick values. Here is the updated version: BadEulerMedianOracle.sol
The problem
The malicious version of the oracle hook contract contains the updatePriceTicks
function, which can be called only by the hook owner.
As you can see in the picture, the hook function allows the owner to update the ringBuffers
storage variable. This variable is later used in the readOracle
function to calculate the median price.
That said, simply the updatePriceTicks
function is a backdoor.
Attack scenario
The PoC of the attack has been implemented in the test_abuser_read
test and can be found here: BadEulerMedianOracle.t.sol#L59.
Let’s imagine there is a lending protocol that uses this oracle to calculate the value of provided collateral when borrowing some other assets.
The goal of the attack is to manipulate the prices and make the collateral’s value higher, resulting in borrowing more assets and leaving the lending protocol with bad debt.
Step 1: The hook must be deployed and some legitimate swaps need to be executed to populate the oracle with some ticks. This is achieved with the createSwaps
function.
Step 2: The lending protocol gets the current price using the readOracle
function during a legitimate borrow operation. The price return is equal to 15 (the unit does not matter in this scenario).
Step 3: The malicious hook owner updates the ticks with arbitrary values leading to a higher price.
Step 4: The malicious hook owner adds the collateral covered by their to the lending protocol and borrows other assets. The protocol gets the current, manipulated price using the readOracle
function (the price is not over 10x higher) and allows the borrower to get more assets.
That simply means that the malicious hook owner can control the value of their collateral in the lending protocol.
How to stay secure?
It's crucial to adhere to specific security measures when developing or integrating Uniswap V4 hooks. Below are key guidelines to ensure robust security in these processes.
Security Guidelines for Web3 Developers Constructing Hooks:
- Eliminate Backdoor Functionalities: Ensure that your hook does not include any functionalities that would permit the owner or any other entity to alter the values utilized by other protocols or users. This step is critical in maintaining the integrity and trustworthiness of the hook.
- Ownership Strategy: It is advisable to either avoid the ownership design pattern altogether or to renounce ownership of the smart contract immediately after the hook's establishment. This measure reduces the risk of centralized control and potential manipulation.
Security Recommendations for Developers Integrating Uniswap v4 Hooks with Critical-Level Values:
- Vigilance Against Suspicious Functions: Diligently inspect the hook for any functions that might modify variables. These variables could be directly or indirectly involved in the calculation of values your protocol relies on. Identifying and addressing such functions is essential in safeguarding the accuracy and reliability of your protocol's operations.
- Caution with Powerful Ownership Roles: Be wary of integrating custom hooks that are under the control of active owners, especially those with the authority to modify a wide range of hook parameters. Such hooks pose a heightened risk of centralization and potential interference, which could compromise the protocol's functionality and security.
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.
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.