Custom pricing hook on BNB Chain

Uniswap v4 Hook Contract 0x91fb28d8f4906df4e8c71806dfeb882dd82815d8 on BNB Chain · Custom pricing

Volume (24h)
$25.83K
Value locked (TVL)
$204.87K
All-time volume
$3.60M
Pools using this hook
12
Swaps (24h)
374 (86 traders)
Total swaps
54,006

What it does

An IndexHook for Uniswap v4 pools that pair an index token with a collateral token; it charges a per-pool custom fee on swaps routed to the index token, sets the pool's dynamic LP fee, waives fees for the index token's own native-pool swaps, and tracks index token balances held in native pools.

How it works step by step

  • Only pools explicitly allowed by the hook owner or by the index token factory can interact with the hook (allowedPools check on every callback).
  • beforeSwap takes a custom hook fee (customPoolFee, in pips of swap amount) from the swap delta via poolManager.take and sends it to the index token address, when custom hook fees are configured.
  • Swaps initiated by the index token itself on its own native pool receive a 0% LP fee via the OVERRIDE_FEE_FLAG.
  • afterSwap, afterAddLiquidity, afterRemoveLiquidity and afterDonate update indexInPools accounting and call giveExceptionToLimited on the index config so that index-token transfers into the pool manager are permitted.
  • afterInitialize sets the pool's initial dynamic LP fee to 0.30% for dynamic-fee pools, and setDynamicLPFee (callable only by the index config) updates that fee within 0.001% to 2.00% bounds.
Swap behaviour
beforeSwap may take a custom hook fee in the unspecified-side currency and forward it to the index token; the index token's own swaps get a zero fee override; afterSwap updates index reserve tracking and grants transient exceptions to limited accounts through the index config.
Liquidity behaviour
afterAddLiquidity and afterRemoveLiquidity update indexInPools using the principal delta plus fees accrued; afterAddLiquidity may require the provider to be allowed (allowedLPsOnPool or an index token itself) and grants limited-account exceptions. Liquidity provision by non-allowed accounts reverts in that path.
Fee behaviour
The pool's dynamic LP fee is set by the index config (within 10 to 20000 pips) and the hook's custom fee (customPoolFee) is charged in beforeSwap as a percentage of swap amount, taken to the index token, when enabled by the owner per pool.
Owner & admin controls
The owner (set at construction, an EOA or contract, not verified) can allowPool, allowPools is restricted to index tokens, setAllowedLiquidityProvider, and enableCustomHookFeesForPool. Dynamic fee and custom fee changes are gated to the registered index config contract, not the owner. Owner can be transferred via the FactoryChild/Ownable pattern; no pause function is present. The factory owner and factory can register indexes.

Enabled Uniswap v4 callbacks

afterInitialize, afterAddLiquidity, afterRemoveLiquidity, beforeSwap, afterSwap, afterDonate, beforeSwapReturnDelta

afterInitialize sets the initial dynamic fee; afterAddLiquidity and afterRemoveLiquidity track index token balances and enforce LP allowlisting on add; beforeSwap applies the custom fee and zero-fee override; afterSwap updates tracking and exceptions; afterDonate grants exceptions for donations; beforeSwapReturnDelta lets beforeSwap return a delta that takes a fee from the swap.

Security & trust assessment

Risk level: medium (verified source, medium confidence).

Who controls it: The hook owner can allow arbitrary pools and LP addresses and toggle custom hook fees per pool. The index config contract (set by the factory) controls dynamic LP fees and custom fee amounts for each index pool. The factory owner can register indexes. A privileged key on the index config could change the fee charged on every swap in that pool within the bounds allowed by the hook.

Risk to user funds: The hook can take a fee from swap deltas in beforeSwap and send it to the index token, and it can grant transfer exceptions to limited accounts at the pool manager. It does not appear to hold user funds itself beyond transient deltas, and there is no pause or withdraw function in the decoded functions. Reverts in afterAddLiquidity can block LP provision for non-allowed accounts.

Security findings

  • [medium] Owner-controlled custom fee via per-pool toggle: The owner enables custom hook fees per pool, and the index config (registered by the factory) sets the custom fee amount in pips through setDynamicLPFee with changeCustomHookFee true. The amount is capped only by the 2% MAX_DYNAMIC_FEE check on the dynamic fee path, but the custom hook fee path is validated by the same bounds only when called through _safeUpdateDynamicLPFee, so the fee charged on swaps depends on configuration by the index config.
  • [medium] Hook takes tokens from swaps via return delta: beforeSwapReturnDelta is enabled and beforeSwap returns a nonzero specified/unspecified delta, meaning the hook extracts a fee from every swap on enabled pools and moves it to the index token address using poolManager.take. This is a user-facing charge that can be changed through the index config's configuration.
  • [medium] Exception grants to limited accounts via external config: afterSwap, afterAddLiquidity, afterRemoveLiquidity and afterDonate call giveExceptionToLimited on the index config contract at the pool manager address. Those calls depend on the trust placed in the index config (factory-deployed, not independently verified here), and a misconfigured config could affect transfer permissions for the pool manager.
  • [info] Unverifiable proprietary dependencies: The source for IMsgSender, IRolesFeeRouter and several imports was omitted, so the msg.sender resolution used for the router and position manager could not be fully verified. The contract is under a proprietary license.
  • [info] Upgradeability not present on the hook: IndexHook inherits Initializable and FactoryChild but has no upgrade function in its ABI, so the hook itself is not upgradeable; upgrades happen at the factory level for newly deployed indexes only.

Contract details

Verified source
No
Bytecode size
10,370 bytes
Upgradeable proxy
No
Detected patterns
dynamic-fee, moves-currency, return-delta

Pools using Custom pricing hook