Dynamic fee hook on Base

Uniswap v4 Hook Contract 0x8ba3380579cd498c61f31e03f71b237fdb1ce8cc on Base · Dynamic fee

Volume (24h)
$251
Value locked (TVL)
$0
All-time volume
$251
Pools using this hook
1
Swaps (24h)
2 (1 traders)
Total swaps
2

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