-
Notifications
You must be signed in to change notification settings - Fork 24
fix: enforce at the code level to not support hooks #208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Summary by OctaneNew ContractsNo new contracts were added. Updated Contracts
🔗 Commit Hash: dffca50 |
WalkthroughThe changes introduce a new PoolKey validation in MainnetController to prevent pools with hooks from being configured, and refactor UniswapV4Lib by converting an internal poolKey retrieval function to a public getter function. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/MainnetController.sol(2 hunks)src/libraries/UniswapV4Lib.sol(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: coverage
- GitHub Check: test
- GitHub Check: build
- GitHub Check: Octane automated security check
🔇 Additional comments (3)
src/libraries/UniswapV4Lib.sol (2)
56-56: LGTM: Refactor to use public getter.The change from internal
_getPoolKeyFromPoolIdto the new publicgetPoolKeyFromPoolIdmaintains the same functionality while improving code reusability.Also applies to: 179-179
246-248: The bytes32 to bytes25 cast is correct and follows Uniswap V4's standard implementation.The PositionManager's poolKeys mapping expects bytes25, and the poolId is truncated to 25 bytes to lookup PoolKey in the poolKeys mapping. This is the standard conversion used in Uniswap V4: bytes25 _poolId = bytes25(PoolId.unwrap(_poolKey.toId())).
src/MainnetController.sol (1)
13-13: LGTM: Required import for hook validation.The PoolKey import is necessary for the new hook validation logic introduced in
setUniswapV4TickLimits.
| PoolKey memory poolKey = UniswapV4Lib.getPoolKeyFromPoolId(poolId); | ||
|
|
||
| require(address(poolKey.hooks) == address(0), "MC/pool-has-hooks"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hook validation is incomplete - critical gap in swap operations.
While this validation correctly prevents configuring tick limits for pools with hooks, it doesn't prevent swaps on such pools. The swapUniswapV4 function (line 719-738) relies on maxSlippages[address(uint160(uint256(poolId)))] which is set via setMaxSlippage (line 267-274), bypassing this hook check entirely.
Attack scenario:
- Admin sets
maxSlippagefor a pool with hooks (no validation) - Relayer calls
swapUniswapV4with that poolId - Swap executes on a hooked pool, violating the "no hooks" requirement
🔎 Recommended fix: Add hook validation to swap operations
Option 1: Add validation in UniswapV4Lib.swap function
In src/libraries/UniswapV4Lib.sol, add hook validation after retrieving the poolKey:
function swap(
address proxy,
address rateLimits,
bytes32 poolId,
address tokenIn,
uint128 amountIn,
uint128 amountOutMin,
uint256 maxSlippage
)
external
{
require(maxSlippage != 0, "MC/max-slippage-not-set");
PoolKey memory poolKey = getPoolKeyFromPoolId(poolId);
+
+ require(address(poolKey.hooks) == address(0), "MC/pool-has-hooks");
require(
tokenIn == Currency.unwrap(poolKey.currency0) ||Option 2: Add validation in setMaxSlippage for Uniswap V4 pools
Modify setMaxSlippage to detect and validate Uniswap V4 poolIds. However, this is more complex as you'd need to distinguish pool types.
Recommendation: Option 1 is cleaner and ensures runtime protection.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/MainnetController.sol around lines 335-337 the code checks PoolKey memory
poolKey = UniswapV4Lib.getPoolKeyFromPoolId(poolId);
require(address(poolKey.hooks) == address(0), "MC/pool-has-hooks"); but swap
paths still allow swaps against pools with hooks via swapUniswapV4 (lines
~719-738) because maxSlippage is set elsewhere; to fix, add the same hooks
validation inside the UniswapV4Lib.swap implementation immediately after
retrieving the poolKey (or at the start of swapUniswapV4) so swaps revert for
hooked pools; use the same revert message/semantic ("MC/pool-has-hooks") and
ensure the check uses address(poolKey.hooks) == address(0) to block any pool
with nonzero hooks.
Overview
🔗 Commit Hash: dffca50 |
Summary by CodeRabbit
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.