Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Herbicide is a mission-critical developer security platform to code, audit, deploy, monitor, and operate Uniswap v4 hook applications with confidence. Integrating directly into the developer workflow, Herbicide makes it easy and fast for developers and operators to prevent and fix security issues pre and post-deployment.
The document details the architecture, feature composition, roadmap, and other project-related aspects of Herbicide.
(app)
Overview
Introduction
Quick Start
tutorials
Use cases
Malicious | Vulnerable Hook Detection
Our project aims to enhance security within the Uniswap V4 ecosystem by operating an Anti-Hook Monitoring solution. This solution will continuously monitor Pool Manager contracts deployed on Uni Chain and rigorously analyze the security of Hooks configured during the initialization process. We comprehensively assess potential risks and vulnerabilities by leveraging dynamic and static analysis methods. Through dynamic analysis, we verify that Hooks function safely across various operational scenarios, while static analysis helps preemptively identify security flaws at the code level.
With this thorough examination, we intend to build an allowlist of verified Hooks, providing a secure environment that Uniswap users can trust. Furthermore, to offer a recognized security standard for developers and users alike, we plan to issue SBTs exclusively to certified Hook Contracts. This issuance reflects our commitment to security and the broader advancement of Uniswap V4 and Uni Chain. Through Anti-Hook Monitoring, we aim to strengthen the Uniswap V4 ecosystem and support a secure onboarding experience.
This page provides a brief overview of the components and tests within Herbicide. Herbicide requires Uniswap V4’s PoolKey as an input to operate. It is recommended that the Hook Contract be deployed for analysis on the Unichain Sepolia Network (Chain ID: 1301) and initialized with the Uniswap V4 Pool Manager Contract on Unichain Sepolia.
When using specific Hooks, the logic of afterSwap
, beforeSwap
, beforeAddLiquidity
, afterAddLiquidity
, beforeRemoveLiquidity
, and afterRemoveLiquidity
can impact token movements by influencing Delta Amount. Through Dynamic Analysis, we simulate the token amounts users are expected to pay or receive during swap/modifyLiquidity actions, tracking fund movements across each execution entity (Hook Contract, PoolManager, Router).
By comparing the simulation results for amountIn and amountOut, users can verify the Actual Price when using a particular Pool. Additionally, this feature enhances user convenience by displaying real-time market prices, sourced through Pyth Oracle, for reference alongside simulation results.
Provides simple threat detection and information extraction functions for Hook Contract code written in Solidity.
The Hook Contract Scanner helps developers easily understand Libraries, Modifiers, require/assert/revert conditions, and Access Control Logic in the Hook Contract.
For comprehensive static analysis, the source code must be verified and uploaded to the Contract. Static analysis is powered by and , while dynamic analysis operates on a -based framework. Threats that may arise within Uniswap V4 Hooks are detailed in the Uniswap V4 Hook Security documentation.
Our project seeks to enhance the security of Uniswap V4 Hook Contracts by developing an advanced static analysis solution leveraging LLMs. Since Hook Contracts are a type of Smart Contract, developers can freely include custom functions and assembly code written in Yul, which adds to code complexity and makes it challenging for conventional static analysis tools to detect specific patterns or behaviors effectively.
We are exploring using LLMs to enhance static analysis and address these challenges. By training an LLM on smart contract code patterns, we aim to achieve a deep understanding of the complex structures within Hook functions and assembly code. This approach allows the LLM to recognize unique characteristics and potential vulnerabilities within Hook Contracts, enabling proactive identification of unintended behaviors or security flaws in the code. Such advanced analysis goes beyond merely detecting syntactic errors. It will offer a practical evaluation of hidden risks within Hook Contracts, contributing to a safer DeFi ecosystem on UniChain.
This project is designed as a web service, allowing users to submit a Pool Key from Uniswap V4 and choose between dynamic and static analysis options. Users can access this service via a web interface. When a Pool Key initialized in the Uniswap V4 Pool Manager is provided, the system begins its analysis based on this Pool Key.
The Pool Key information is stored in the API server, and a Task is dispatched to a Message Queue. If a Task is present in the Queue, the Worker executes it. Static analysis utilizes Semgrep and Slither, while dynamic analysis operates on a Foundry-based system. Results from both types of analysis are interpreted, aggregated, and stored in Redis.
Users can access and review their analysis results using the Task ID associated with each request.
To utilize Herbicide, users can select between two input methods.
The Hook Contract must be deployed on the Unichain.
The PoolKey includes the two token addresses to be exchanged (currency0, currency1), LP fees, tick spacing, and the Hook Contract address.
To run an Initialize Test with a specific deployer address, provide the address as an additional parameter. If omitted, the test will default to the standard address for execution.
Detection Available
Malicious Hook Detection: Issues a warning if the Hook attempts to misappropriate user funds or withdraws more tokens than the user intended.
Price Abnormality Detection: Alerts users if there is a significant discrepancy between the simulated price calculated by Herbicide and the actual swap price.
Hook Delta Simulation: Simulates the amounts transferred during Swap/ModifyLiquidity operations, allowing users to understand the specific fund flow characteristics of the Hook.
When a Hook Contract is provided, Herbicide uses its Semgrep script to perform static analysis, detecting potential threats and processing Hook Contract information for review.
onlyPoolManager: Confirms that onlyPoolManager is implemented to ensure access control for hook functions.
Double Initialize Storage Check: Verifies if the Storage accessed by beforeInitialize/afterInitialize
functions is managed by PoolId during Hook initialization.
tx.origin Warning: Issues a warning if access control relies on tx.origin
, which can introduce security vulnerabilities.
The specified Hook should be initialized (or be eligible for initialization) with the Pool Manager at using the provided PoolKey.
Static Analysis with Slither: Provides security inspections and detailed contract information using on verified Hook Contracts from BlockScout, facilitating efficient auditing of the Hook Contract.
Analytics
Track analytics from your docs
Support
Add support widgets to your docs
Interactive
Add extra functionality to your docs
Visitor Authentication
Protect your docs and require sign-in
The StopLoss contract leverages Uniswap V4’s custom user hook functionality to implement a stop loss feature. This hook automatically sells tokens when the price in a specified pool meets the user-defined stop-loss conditions, thereby preventing further losses. The functionality of this hook is summarized as follows:
Users create a stop-loss order by executing the placeStopLoss()
function.
After each swap, the afterSwap
function compares the previous and current ticks, executing the order if the conditions are met.
Let's take a look at the afterSwap
function in this hook.
The function lacks a modifier and any additional ACL mechanism. Through this function, the fillStopLoss()
function can be called separately, allowing storage values to be altered. This may lead to unexpected behavior in the hook, and appropriate measures are necessary. Herbicide can detect these risks and alert users accordingly.
This ArrakisHook
stores information about the pool key in beforeInitialize
right before initialization, enabling it to manage liquidity through ERC1155.
Let's take a look at the beforeInitialize()
in this hook.
This contract is a hook implemented to initialize information about the pool key in beforeInitialize
. However, this hook does not implement any access control for beforeInitialize
, nor does it take any measures regarding the number of initializations. Since the pool key is initialized
in beforeInitialize
, if a new initialization is performed on this hook, all existing hook assets will be locked.
Herbicide detects the storage values of such cases to ensure that users can use the hook safely.
What does Herbicide detect?
Detects changes in the Hook's storage due to the actions of beforeInitialize / afterInitialize
if the same Hook can be deployed to the PoolManager
. Confirms whether the storage accessed by the beforeInitialize/afterInitialize
functions during Hook initialization is managed by PoolId.
Detects cases where a specific Hook does not operate after a certain period has elapsed.
For Hook functions such as beforeInitialize
/ afterInitialize
/ beforeSwap
/ afterSwap
/ etc.
, detects whether entities other than the PoolManager can execute each function.
Can identify risks of gas griefing through gas usage and warns if it can steal user funds or take more tokens than the user intends to pay.
Warns when there is a significant difference between the price simulated by Herbicide and the actual price at which the swap occurs.
Detects and warns if the Hook Contract is implemented as a proxy.
Hook Delta Simulation: Simulates the amount of funds moved during Swap/ModifyLiquidity
, allowing users to directly understand the characteristics of the fund flow in the Hook.
Static Analysis with Slither: Provides processed information such as security checks and contract information for Hook Contracts verified on BlockScout using Slither, making audits more convenient.
Static Analysis with Semgrep: Based on the Herbicide Semgrep Script, it extracts and displays information about the Contract as follows.
Library Information
Modifier Information
Inheritance Information
Variable Information
The analysis is supported for Uniswap V4 Hook Contracts interacting with the Uniswap V4 The exact initialized values in the Pool Manager must be correctly entered. Each hook should be implemented per the IHook
and BaseHook
interfaces, interacting with and
A malicious hook can monitor the amount of tokens a user has approved.
The malicious hook takes the entire approved token amount through ERC6909.
It then settles only the necessary amount required for a legitimate Swap/ModifyLiquidity
.
Through this process, the malicious hook can effectively steal the maximum possible token amount the user has approved for the transaction.
The image above illustrates the process in which the Malicious Hook exploits the token approval mechanism. The first step shows the Malicious Hook verifying the approved token amount. In the second step, it proceeds to transfer the entire approved token quantity to ERC6909. Finally, the required amount is settled for legitimate Swap/ModifyLiquidity actions, allowing the Malicious Hook to maximize the tokens stolen from the User.
Hooks can significantly influence PoolKeys' behavior. For example, if a hook triggers a revert, it could render the associated pool unusable. Such cases, which compromise user accessibility, include attacks like gas griefing. Herbicide addresses these risks by detecting such hooks through dynamic analysis testing.
Unified Security Framework and Trust Considerations
Uniswap V4 has implemented a range of mechanisms to provide a secure and permissionless environment for user-defined liquidity operations, particularly through its new Hook functionality. However, this flexibility introduces certain risks and trust assumptions. Below, we explore the core security elements and specific considerations for maintaining robust user and liquidity provider trust.
Core Security Components
Singleton Architecture
Uniswap V4’s core resides within the single PoolManager
contract, centralizing the management of all pools and enforcing a controlled environment for liquidity operations.
This differs significantly from the previous version, where each pool operated within its individual contract, providing stronger guarantees on interaction consistency.
Hook Contract Security
Hook contracts allow custom business logic to run before and after liquidity operations (e.g., beforeAddLiquidity
, afterRemoveLiquidity
), allowing advanced customization.
Given their direct interaction with token flows, Hooks may impose security risks if not designed correctly. Malicious Hooks could steal user assets or excessively inflate gas costs, which is why dynamic and static analysis tools, such as Herbicide, are recommended for threat detection.
Dynamic and Static Fee Management for Liquidity Providers
Fees in Uniswap V4 can be either static or dynamically adjustable, configurable through Hooks at initialization. However, as dynamic fees can be updated on an ongoing basis, additional scrutiny on these adjustments is required to avoid exploitation.
Critical Trust Assumptions
Transaction Security and Slippage Control
Core contracts do not have built-in slippage protection, assuming that the periphery contracts will handle this function. Users and developers must ensure they use well-vetted periphery contracts to avoid excessive slippage in swaps.
User and LP Asset Safety
Reentrancy and unusual token contracts (e.g., rebase tokens) introduce unique vulnerabilities. To mitigate these, rigorous contract review and adherence to ERC-20 standards are critical.
Potentially malicious Hooks can alter swap or liquidity positions to the detriment of users, emphasizing the need for security mechanisms that check slippage and enforce LP protections.
Permissions and Privilege Levels
Protocol Fee Controller: Authorized to set protocol fees up to a capped 0.1% and to direct accrued fees.
Owner: Maintains the authority to update the Protocol Fee Controller.
Hooks with Dynamic Fees: Authorized to adjust fees on dynamically configured pools.
Immutable Operations and Potential Upgradability
Certain Hooks could theoretically include upgradability, which introduces post-deployment risk if unchecked. Users and LPs are encouraged to carefully review Hooks or use those audited by trusted entities.
To safeguard against the above risks, users, developers, and auditors are advised to:
Leverage Security Audits: Routine analysis using dynamic and static tools, such as Herbicide’s Hook monitoring, can help detect and remediate vulnerabilities.
Implement Trustworthy Oracles: Ensure Hooks rely on credible oracles when conducting price-sensitive operations.
Restrict Unauthorized Access: Apply onlyPoolManager modifiers or similar controls on sensitive Hook functions.
Monitor for Malicious Activities: Utilize security features within periphery contracts for additional slippage and transaction safety protections.
Using the Detectors provided by Slither, it is possible to detect threats within the Hook. Herbicide automatically executes the following Detectors to find and warn about threats.
Using the Slither-Printer, it displays critical information regarding the access control of the contract. In Herbicide, the Printer is automatically executed to extract and display.
Prints require statements in the function.
Prints modify applied to the function.
Prints require statements with msg.sender
, in the function which writes state variables.
info-variable
Prints state variables and the functions using them.
info-inline-access-control
Checks require&assert&revert conditions.
info-inheritance
Prints the contract's inheritance information.
info-library
Prints the usage of libraries of the contract.
In the Simple Contract Analyzer, users can input contract to receive processed key information according to predefined Semgrep rules by Herbicide. This lets users easily review details about functions and storage variables declared in
info-layer2-assignee
Checks storage re-used while double-initializing the hook.
low-call
Checks if the hook is low-calling to other addresses.
getSlot0-check
Checks if the hook is calling getSlot0
function, as it is dangerous if the hook operates as an oracle, returning the getSlot0
value as the price of the pool.
missing-token-transfer-while-burnt
Checks if the hook is not transfer the underlying token while the token is burnt.
missing-onlyPoolManager-modifier
Checks if onlyPoolManager
modifier is not applied to the hook functions.
misconfigured-hook
Checks if the hook functions are not yet implemented, while the function flag of getHookPermissions
returns true
.
Verifies whether the liquidity pool corresponding to the PoolKey is functioning correctly.
The above basic tests are conducted periodically. The intervals for each period are as follows:
1 hour, 3 hours, 6 hours, 12 hours, 1 day, 1 week, 1 month, 1 year, 3 years, 5 years, 7 years, 10 years After a certain period of time, it is confirmed whether the liquidity pool operates normally, and a warning is issued for Hooks with implemented Time Locks.
Each Hook Function is executed by calling the Hook Contract through the unlockCallback
in the PoolManager
. If Hook Functions are called by other Users or Contracts, unintended behavior may occur, so the function caller should be restricted using the onlyPoolManager
modifier or require statement.
Herbicide warns if Hook Functions can be called externally.
Although the same PoolKey
cannot be used to initialize a Pool in the PoolManager
, if storage is not managed by PoolID
, side effects may occur when initializing the same Hook with a different PoolKey
.
Herbicide changes the tick interval of the Pool key you entered to check if it can be initialized, and warns if the same storage is used.
If the Hook Contract does not manage storage by PoolID
, it should be checked and managed based on PoolID
, or additional measures should be taken to prevent reinitialization.
If the Hook Contract operates using the Proxy Pattern, it warns that the logic of the Hook may change.
It compares the gas usage of modifyLiquidity
and swap without using the Hook, and the gas usage of modifyLiquidity
and swap when using the Hook. This allows the detection of malicious Gas Griefing by the Hook, and users can predict the gas usage when using the Hook.
When performing a Swap for a Pool using the Hook, the use of the Hook may cause fluctuations in the token price. Additionally, the Swap may be executed at a price different from the predicted one.
Herbicide can be used to predict such token prices in advance.
If the predicted price by Herbicide and the Simulated Actual Price differ by more than 5%, a warning is issued.
It provides market token price information calculated through Pyth Oracle for convenient comparison.
Tests modifyLiquidity
and swap for
Tests modifyLiquidity
, swap, and donate for
IDX
Hook Name
Type
Minimum
Time-Lock
OnlyBy
PoolManager
Proxy
Re-
Initialize
Gas-
Griefing
P1
DeltaReturningHook
Uniswap Basic
P
P
P
P
P
P
P2
CustomCurveHook
Uniswap Basic
Detect
Detect
False Positive
P
P
P
P3
DynamicFeesTestHook
Uniswap Basic
P
P
Detect
P
P
P
P4
DynamicReturnFeeTestHook
Uniswap Basic
P
P
Detect
P
P
P
P5
FeeTakingHook
Uniswap Basic
P
P
P
P
P
P
P6
LPFeeTakingHook
Uniswap Basic
P
P
P
P
P
P
P7
FullRange
Uniswap Labs
Detect
Detect
False Positive
P
P
P
P8
GeomeanOracle
Uniswap Labs
Detect
Detect
False Positive
P
P
P
P9
LimitOrder
Uniswap Labs
P
P
P
P
P
P
P10
VolatilityOracle
Uniswap Labs
P
P
Detect
P
P
P
P11
StopLoss
Community
P
P
Detect
P
P
P
P12
TradingDays
Community
P
Detect
Detect
P
P
P
P13
ArrkisHook
ETHCC_Paris
P
P
Detect
P
Detect
P