Likely custom pricing hook on Arbitrum

Uniswap v4 Hook Contract 0x98febc1ee98a2a7264409ffbb558369e146a0088 on Arbitrum · Custom pricing

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

What it does

A pool-registry hook on Arbitrum that takes over swap pricing through beforeSwap return deltas, with an owner who can set per-pool fees and run arbitrary calls from the hook.

How it works step by step

  • Keeps a list of pools (allPools, getPoolCount, pools(bytes32)) and a mapping from pool id to an address, probably a per-pool handler or token. The exact meaning is not clear from the bytecode.
  • Runs beforeSwap with return-delta permission, so it can change the swap amounts and take or supply tokens during a swap.
  • Reads a mapping(address => bool) in beforeSwap, probably an allowlist or whitelist check on the caller or sender. This is inferred from storage access and not confirmed.
  • Lets the owner set a fee for a pool with setPoolFee(bytes32,uint24), and has a separate setter for a default fee (selector 0xbefa61d5, uint24).
  • Exposes owner-only execute(address,uint256,bytes) for arbitrary external calls, and setOwner(address) for ownership transfer.
  • Has an unlockCallback, so it interacts directly with the PoolManager (for example to settle or take tokens).
Swap behaviour
beforeSwap is active and can return a delta, so the hook can override or partly fill the swap by taking or giving tokens itself. It reads the pool mapping and a boolean address mapping, which suggests per-pool routing and a caller check. The exact pricing logic cannot be determined from the decoded bytecode.
Liquidity behaviour
No liquidity callbacks are enabled. The decoded stubs for add and remove liquidity are not active permissions.
Fee behaviour
The owner can set a fee per pool (setPoolFee with bytes32 and uint24) and a default fee value (uint24 setter). How the fee is applied or collected in beforeSwap, for example through the return delta, is not visible from the decoded bytecode.
Owner & admin controls
A single owner (storage slot 0) can transfer ownership with setOwner, set per-pool fees with setPoolFee, change a default fee value, call 0x0aa87769 (address[] argument, which writes the pool mapping and list), call 0x8ec6cd0d (address argument, purpose unknown), set the address in slot 5 through 0xbfd3da96 (address,uint256,bytes), and run arbitrary calls with execute(address,uint256,bytes). Whether execute and 0xbfd3da96 are strictly owner-gated was not directly confirmed, though the owner slot is read by both.

Enabled Uniswap v4 callbacks

beforeSwap, beforeSwapReturnDelta

beforeSwap is used to intercept swaps, look up the pool configuration and apply custom pricing or fee logic. beforeSwapReturnDelta lets the hook change the swap amounts by taking or crediting tokens.

Security & trust assessment

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

Who controls it: The owner can change pool fees, modify the pool registry, replace the owner, and run arbitrary calls from the hook contract. This gives it full control over anything the hook holds or is approved for, and strong influence over swap pricing.

Risk to user funds: The hook uses unlockCallback and beforeSwap return deltas, so it can take and settle tokens with the PoolManager during swaps. Funds held by the hook can be moved by the owner through execute. A misconfigured or malicious fee or delta could cost swappers value, and a revert in beforeSwap could block swaps. LP positions are not directly controlled because no liquidity callbacks are enabled.

Security findings

  • [high] Arbitrary call execution by owner: execute(address,uint256,bytes) reads the owner slot and lets the owner call any target with any value and calldata from the hook. Any tokens or approvals held by the hook can be moved.
  • [medium] Return delta on swaps: beforeSwapReturnDelta is enabled, so the hook can take or redirect part of swap amounts. Traders depend on the hook's unseen pricing and accounting logic.
  • [medium] Owner-controlled per-pool fees: setPoolFee(bytes32,uint24) and a default-fee setter let the owner change fees at any time. Whether the fee is capped could not be determined from the decoded bytecode.
  • [low] Single-key ownership transfer: setOwner(address) takes one address with no visible two-step process or timelock, so a compromised key gives full control.
  • [info] Unverified source: No source is available. Behaviour is inferred from selectors and storage access, and the purposes of several unnamed selectors are unknown.

Contract details

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

Pools using Likely custom pricing hook