Likely custom pricing hook on Base

Uniswap v4 Hook Contract 0x8d09e3df92c4c994d396e3c7558b4ddb16b21088 on Base · Custom pricing

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

What it does

A Uniswap v4 hook that registers pools on initialization and, on each swap, uses a return delta to take over swap handling, with an owner who can change pool fees and run arbitrary calls.

How it works step by step

  • On pool initialization, it records the pool in internal storage (a mapping plus an array of pool entries), which is exposed through allPools(uint256), getPoolCount() and pools(bytes32).
  • Before each swap it reads the stored pool data and a mapping(address => bool), likely an allowlist or router check, and can return a delta that changes how much the swapper pays or receives.
  • It exposes an unlockCallback(bytes), so it can unlock the PoolManager itself and move tokens during swap handling.
  • The owner can call setPoolFee(bytes32,uint24), which suggests per-pool fee settings that the hook applies itself.
  • The owner can call execute(address,uint256,bytes), an arbitrary external call, and setOwner(address) to transfer ownership.
Swap behaviour
beforeSwap reads per-pool data and an address-to-bool mapping, and it returns a BeforeSwapDelta (beforeSwapReturnDelta is enabled). The hook can therefore take or substitute part of the swap amount instead of leaving it all to the pool's normal pricing. The exact formula cannot be determined from the decoded bytecode. There is no afterSwap permission.
Liquidity behaviour
No liquidity callbacks are enabled. The add/remove liquidity selectors appear in the dispatch table but the hook's permission bits do not enable them.
Fee behaviour
Fees appear to be set per pool by the owner through setPoolFee(bytes32,uint24). The hook probably applies or takes them through the swap return delta. The exact fee destination and calculation are not determinable without source.
Owner & admin controls
An owner stored in slot 0 can transfer ownership (setOwner), change per-pool fees (setPoolFee), and call execute(address,uint256,bytes) to make arbitrary calls from the hook. Other owner-gated functions are unnamed: 0x0aa87769 (address[]), 0x8ec6cd0d (address), 0xbefa61d5 (uint24, which writes a uint24 in slot 0, probably a default fee) and 0xbfd3da96 (address,uint256,bytes, which writes slot 5). I could not confirm what each one does.

Enabled Uniswap v4 callbacks

afterInitialize, beforeSwap, beforeSwapReturnDelta

afterInitialize registers the new pool in the hook's pool list and mapping. beforeSwap runs per-swap logic that checks stored pool data and a boolean mapping. beforeSwapReturnDelta lets the hook adjust the swap's token amounts through the returned delta.

Security & trust assessment

Risk level: high, estimated (decoded bytecode, low confidence).

Who controls it: The owner can change fees and run arbitrary calls from the hook's address. It can also hand ownership to another account at once. Users must trust the owner not to extract value from the hook or misconfigure fees.

Risk to user funds: The hook implements unlockCallback and a swap return delta, so it can move tokens through the PoolManager and may hold balances temporarily or persistently. The owner's execute function could drain anything it holds. A misbehaving beforeSwap could also block or reprice swaps. The exact balances held cannot be determined from bytecode alone.

Security findings

  • [high] Arbitrary call by owner: execute(address,uint256,bytes) is a generic call primitive. The owner can use it to move any tokens or ETH held by the hook or to call any contract as the hook, including approved spenders.
  • [medium] Swap return delta takes value: beforeSwapReturnDelta is enabled, so the hook can capture or redirect part of a swap's input or output. The bounds on this are not visible in the decoded bytecode.
  • [medium] Owner-controlled fees: setPoolFee(bytes32,uint24) lets the owner change per-pool fees at any time. The hook does not appear to enforce a cap, but I could not verify this.
  • [medium] Unverified source: No verified source exists. Behavior is inferred from selectors and storage access, and several functions are unnamed.
  • [info] Single EOA-style owner: Ownership uses a simple setOwner/owner pattern with no visible timelock or two-step transfer.

Contract details

Verified source
No
Bytecode size
14,728 bytes
Upgradeable proxy
No
Detected patterns
return-delta

Pools using Likely custom pricing hook