FactoryHook on Robinhood Chain

Uniswap v4 Hook Contract 0xee588bcf2bd3e658f5160489f4199d1851bbf0cc on Robinhood Chain · Dynamic fee · Verified contract

Volume (24h)
$45
Value locked (TVL)
$10.60K
All-time volume
$937.17K
Pools using this hook
41
Swaps (24h)
14 (9 traders)
Total swaps
14,491

What it does

A singleton Uniswap v4 hook for graduated BCToken pools that charges a time-decaying volatility-aware swap fee, splits it between LPs and a non-LP share paid to a treasury, staking vault and coin fee recipient, and blocks swaps until the coin has graduated.

How it works step by step

  • Rejects swaps on any pool whose coin has not graduated (reverts with NotLPd when the coin's isLPd() is false).
  • Tracks volatility as time-decayed absolute tick displacement since the previous swap, capped at 900 ticks, and feeds it into a fee chain.
  • Runs a fee chain of up to 4 external calculator stages, each under a 50,000 gas stipend, starting from a 0.30% base fee and clamped to 10% (or 50% during a declared sniper window of up to one hour).
  • Enforces a 3 bps protocol floor on the swap and splits the remainder: LPs receive a grossed-up LP fee override, while the non-LP share is taken as a hook delta (exact input) or charged after the swap (exact output).
  • Distributes the non-LP share to the treasury, an optional staking vault and the coin's fee recipient, and notifies up to 8 bound observers under a shared 600,000 gas budget.
  • Maintains a truncated tick oracle checkpointed in afterSwap and readable through observe().
Swap behaviour
beforeSwap checks graduation, updates volatility, runs the fee chain, floors the fee at 300 pips, and sets an LP fee override. For exact-input swaps it takes the non-LP share as a before-swap hook delta and distributes it immediately; for exact-output swaps it stores the rate in transient storage. afterSwap checkpoints the oracle, charges the non-LP share on exact-output swaps and notifies observers.
Liquidity behaviour
No liquidity callbacks.
Fee behaviour
Total fee starts at 3000 pips (0.30%) and is set per swap by the fee chain plus a volatility-driven input, clamped to 100000 pips (10%) or 500000 pips during a sniper window, and floored at 300 pips. The LP share is delivered as a dynamic LP fee override; the protocol/non-LP share is a hook delta taken to the treasury (protocolFeeRatio percent with the 3 bps floor), the staking vault (communityFeeRatio percent of remainder, only when vault supply is non-zero) and the coin fee recipient.
Owner & admin controls
The factory owner (read from BC_TOKEN_FACTORY.owner()) can call setProtocolFeeRatio (0 to 100), setStakingVaultFactory (validated against the factory's hook) and setStakingVault per registered pool (validated against the coin asset and hook). The liquidity manager (BC_TOKEN_FACTORY.liquidityManager()) controls registerPool and pool initialization. Fee calculator and observer addresses are set per pool at registration and are not changeable afterwards in this source. No pause function, no proxy and no upgrade path were found in the source.

Enabled Uniswap v4 callbacks

beforeInitialize, afterInitialize, beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta

beforeInitialize restricts pool initialization to the liquidity manager for registered dynamic-fee pools. afterInitialize seeds the volatility and oracle state from the opening tick. beforeSwap gates on graduation, computes the fee, takes the exact-input protocol share as a hook delta and sets the LP fee override. afterSwap checkpoints the oracle, charges exact-output protocol share as a hook delta and notifies observers. beforeSwapReturnDelta and afterSwapReturnDelta allow the hook to take currency from swaps.

Security & trust assessment

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

Who controls it: The factory owner can raise the protocol share of non-LP fees to 100 percent and rewire the staking vault per pool. The liquidity manager controls which pools are registered and initialized. Neither can directly move LP principal through this hook, but they can change fee economics for swappers and redirect fee revenue.

Risk to user funds: The hook takes the non-LP fee from every fee-bearing swap as a hook delta, held in and drawn from the pool's own reserves, and distributes it to the treasury, vault and recipient. It does not hold a user balance or custody LP positions and has no liquidity callbacks. Swaps can be blocked by reserve drain, by a reverting vault or recipient call, or by a non-graduated coin.

Security findings

  • [info] Hook delta takes currency from swaps: beforeSwap and afterSwap return non-zero deltas and take the non-LP fee through poolManager.take, so the hook directly moves pool and swapper funds on every fee-bearing swap; this is the intended fee mechanism.
  • [medium] Swaps depend on pool reserves and external recipients: _distributeFee calls poolManager.take for the treasury, vault and recipient; if the pool's reserves of the fee currency are drained the swap reverts. A revert in IBCToken.getFeeRecipient or IStakingVault.totalSupply/asset calls would also block swaps, and the coin leg of the vault call is not guarded.
  • [medium] Fee calculators and observers are arbitrary third-party code: Registered per pool through hookConfig, these contracts receive calls during registerPool (which can revert the coin deploy) and during every swap; calculators run under staticcall with a stipend, while observers receive raw calls with a shared gas budget and their nested V4 operations run inside the swap unlock. Creator-chosen addresses are trusted only as far as the registration gate allows, and the gating depends on implementations checking msg.sender.
  • [medium] Admin can redirect non-LP fee share: The factory owner can set protocolFeeRatio up to 100 percent, which sends the whole non-LP share to the treasury, and can replace the staking vault for a pool with any contract that passes asset and hook checks. Both changes apply to subsequent swaps.
  • [low] Oracle and volatility are manipulable within a block: Volatility is derived from pre-swap pool ticks and decays over 600 seconds; an actor can move price across a block to set the next swap's fee, and the oracle clamp is anchored to the block's opening tick, limiting but not removing manipulation.

Contract details

Verified source
Yes (FactoryHook)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
19,852 bytes
Upgradeable proxy
No
Detected patterns
dynamic-fee, erc20, liquidity-management, mev-protection, moves-currency, oracle, return-delta, rewards

Pools using FactoryHook