DopplerHookInitializer on Robinhood Chain

Uniswap v4 Hook Contract 0x4e3468951d49f2eea976ed0d6e75ffcb44a9a544 on Robinhood Chain · Launchpad · Verified contract

Volume (24h)
$3.99M
Value locked (TVL)
$14.82M
All-time volume
$1.79B
Pools using this hook
208,710
Swaps (24h)
50,670 (4,710 traders)
Total swaps
24.4M

What it does

A launchpad hook and initializer that seeds a new token's Uniswap v4 pool with multi-curve liquidity, locks it so fees go to beneficiaries, and lets an approved companion Doppler hook set dynamic LP fees and take a share of swap output.

How it works step by step

  • Called by the Airlock, it creates the asset/numeraire pool with this contract as hook, initializes it at the curve start price and mints multiple liquidity positions spread across the configured curves.
  • Only the hook itself can initialize pools (beforeInitialize requires sender == this), so no one else can create pools using it.
  • If beneficiaries are provided, the pool is Locked and LP fees are collected from the positions and split by shares among beneficiaries (MasterChef-style accounting). The protocol owner gets a minimum share.
  • An optional Doppler hook, enabled by the Airlock owner, can be linked to a pool. It gets onInitialization, onSwap and onGraduation callbacks, can set the dynamic LP fee (capped at 10%) and can take a currency amount on swaps.
  • On exitLiquidity (Airlock only, unlocked pools), all positions are burned and the proceeds are sent to the Airlock for migration once the far tick has been reached. For locked pools, graduate() marks the pool graduated after the far tick is reached and calls the Doppler hook's onGraduation.
Swap behaviour
afterSwap looks up the pool's linked Doppler hook. If one is set and has the swap flag enabled, it calls onSwap and receives a fee currency and an int128 delta. If the delta is positive, the hook takes that amount from the PoolManager, pays it back via settleFor to credit the Doppler hook, and returns the delta to the PoolManager as an afterSwap return delta, so the swapper's output is reduced by that amount. A Swap event is always emitted. Without a Doppler hook, swaps are unchanged.
Liquidity behaviour
afterAddLiquidity and afterRemoveLiquidity only emit a ModifyLiquidity event and return a zero delta. Liquidity is actually minted, burned or collected by the contract itself through unlockCallback during initialization, exit and fee collection.
Fee behaviour
If a Doppler hook is set, the pool uses a dynamic fee, initially set to initData.fee and later updatable by that Doppler hook via updateDynamicLPFee, capped at 100,000 (10%). Otherwise a static fee is used. Fees accrued on the locked positions are collected by collectFees and distributed pro rata to beneficiaries by shares. Separately, the Doppler hook can take an extra amount from swaps through the afterSwap return delta. On migration, the Airlock takes a protocol and integrator cut from the fees.
Owner & admin controls
The Airlock owner can enable or disable Doppler hook contracts and set their callback flags via setDopplerHookState. The asset's timelock (or an authority it delegated to via delegateAuthority) can set or replace the Doppler hook of a Locked pool and its graduation calldata. The linked Doppler hook can change the pool's dynamic LP fee up to 10%. Beneficiaries can transfer their shares with updateBeneficiary. The contract is not a proxy, and no pause function was found. Airlock-only functions are initialize and exitLiquidity.

Enabled Uniswap v4 callbacks

beforeInitialize, afterAddLiquidity, afterRemoveLiquidity, afterSwap, afterSwapReturnDelta

beforeInitialize restricts pool creation to this contract itself. afterAddLiquidity and afterRemoveLiquidity emit ModifyLiquidity events. afterSwap runs the optional Doppler hook's onSwap logic and emits Swap events. afterSwapReturnDelta lets the hook return a delta so currency taken for the Doppler hook is deducted from the swapper.

Security & trust assessment

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

Who controls it: The Airlock owner decides which Doppler hooks are enabled. The asset's timelock or its delegate can attach a different enabled hook, which can set LP fees up to 10% and take swap output via the return delta. The Airlock also controls initialize and exitLiquidity. None of these roles can directly withdraw locked LP principal from this contract.

Risk to user funds: The hook holds the pool's liquidity positions. It holds tokens only transiently, and collected fees sit in the contract until beneficiaries claim them. Traders are exposed to the Doppler hook's onSwap delta being deducted from their swap output. Withdrawal of the bonding-curve liquidity is limited to the Airlock-driven exit path for unlocked pools.

Security findings

  • [medium] Swap output can be reduced by the linked Doppler hook: afterSwap with afterSwapReturnDelta takes the positive delta returned by the Doppler hook's onSwap from the PoolManager and credits it to that hook. The size is controlled by external hook code, not by this contract.
  • [medium] Doppler hook can be swapped by the timelock or its delegate: setDopplerHook lets the asset's timelock or its delegated authority replace the hook on a Locked pool, as long as the new one is enabled by the Airlock owner. This changes the fee and swap-taking behaviour after launch.
  • [low] Dynamic fee capped at 10%: updateDynamicLPFee reverts above MAX_LP_FEE (100,000, which is 10%), but only the pool's linked hook may call it, so traders depend on that hook's logic.
  • [low] Airlock owner controls which hooks are trusted: setDopplerHookState is gated by airlock.owner(), who whitelists Doppler hooks and their flags. The initializer also relies on the Airlock for initialize and exitLiquidity.
  • [info] Locked liquidity cannot be withdrawn by exit: exitLiquidity requires status Initialized, and collectFees requires Locked. LP principal in locked pools stays in the pool, and only fees are collectable.

Contract details

Verified source
Yes (DopplerHookInitializer)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
25,533 bytes
Upgradeable proxy
No
Detected patterns
dynamic-fee, launchpad, moves-currency, return-delta, self-unlock

Pools using DopplerHookInitializer