Dynamic fee hook on Ethereum
Uniswap v4 Hook Contract 0x8a6f8d2744d2241edf9e006d914400dcce1aa8cc on Ethereum · Dynamic fee
- Volume (24h)
- $613
- Value locked (TVL)
- <$0.01
- All-time volume
- $1.99K
- Pools using this hook
- 1
- Swaps (24h)
- 6 (4 traders)
- Total swaps
- 16
What it does
A dynamic-fee hook on BSC that can adjust swap fees within configured bounds and take a share of swap currency through return deltas, with redeemable balances tracked per position.
This read was written for the hook 0x9c75…a8cc on BNB Chain and reused here: the two share a code shape, so constants such as fees, owners and addresses can differ.
How it works step by step
- Runs logic on pool initialization and before liquidity is added
- Applies a configurable fee in beforeSwap bounded by MIN_FEE_BPS and MAX_FEE_BPS
- Uses before and after swap return deltas to take or adjust currency during swaps
- Calls take on the pool manager to collect currency owed to the hook
- Tracks owed balances per position and exposes redeem for claiming them
- Uses unlock and unlockCallback to settle accounting with the pool manager
- Swap behaviour
- beforeSwap and afterSwap run on every swap and the hook can return deltas that adjust settled amounts, so it can take or give currency during the swap in addition to any fee logic.
- Liquidity behaviour
- beforeAddLiquidity is permitted and afterAddLiquidity, beforeRemoveLiquidity and afterRemoveLiquidity are present as view-level dispatch entries. Storage reads of owed(bytes32,address) and a redeem function suggest that liquidity-related claims or balances are tracked per position key and can be redeemed. Whether liquidity is added or removed on the hook's behalf cannot be determined.
- Fee behaviour
- Exposes MIN_FEE_BPS, MAX_FEE_BPS and FeeOutOfRange(uint16) and a configs(bytes32) mapping, which indicates a configurable fee bounded by min and max values. The exact fee formula and whether the fee is applied via an override flag in beforeSwap cannot be determined from the bytecode alone.
- Owner & admin controls
- A setFactory(address) selector exists and the contract stores an address in slot 0 that is written only by setFactory, so a privileged setter appears to control the factory reference. A deployer() getter and a NotDeployer() revert suggest a deployer-only gate on at least one function, but the exact gated functions cannot be confirmed without source. No pause or upgrade functions were identified.
Enabled Uniswap v4 callbacks
beforeInitialize, beforeAddLiquidity, beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta
beforeInitialize: validates or sets up pool state when a pool is created. beforeAddLiquidity: runs logic before liquidity is added. beforeSwap: sets a dynamic fee or swap parameters before each swap. afterSwap: updates accounting after each swap. beforeSwapReturnDelta: lets the hook return a delta that alters the swap amounts, so it can take or give currency during a swap. afterSwapReturnDelta: lets the hook return a post-swap delta that alters settled amounts.
Security & trust assessment
Risk level: medium, estimated (decoded bytecode, low confidence).
Who controls it: A privileged deployer or factory-setter key could potentially change factory-linked behaviour and, if the fee bounds are adjustable through configs, could set fees within the allowed range, shifting value between traders and LPs.
Risk to user funds: The hook can take currency during swaps through return deltas and can unlock the pool manager to move funds, so it can directly affect swap proceeds and pool balances. Redeem and owed mappings suggest it also holds claimable balances on behalf of users.
Security findings
- [high] Hook takes currency through return deltas: The hook has both beforeSwapReturnDelta and afterSwapReturnDelta enabled and calls take(address,address,uint256) against the pool manager, so it can take currency from swaps. This is a material capability that changes swap settlement.
- [medium] Privileged setter controls factory reference: The bytecode contains setFactory(address) writing storage slot 0 along with a deployer-only revert, indicating a privileged account that can repoint a factory reference.
- [medium] Self-unlock flow moves pool funds: The hook calls unlock(bytes) and implements unlockCallback(bytes), so it can unlock the pool manager on its own behalf, which allows it to move funds in a self-unlock flow.
- [low] Fee is bounded but adjustable: Fee bounds MIN_FEE_BPS and MAX_FEE_BPS are exposed with a FeeOutOfRange guard, which limits how far a fee can be set but does not remove a privileged fee-setting path.
- [info] Analysis limited to decoded bytecode: Without verified source, the exact logic of configs, owed, redeem and the gated functions cannot be confirmed, so the risk assessment rests on selectors and storage inference only.
Contract details
- Verified source
- No
- Bytecode size
- 7,261 bytes
- Upgradeable proxy
- No
- Detected patterns
- moves-currency, return-delta, self-unlock
Pools using Dynamic fee hook
- ETH / TEST (0.00% fee) — 24h volume $613, TVL <$0.01, 6 swaps today