JrnyHook on Ethereum

Uniswap v4 Hook Contract 0x8cec12bc7ea6b92cd330b77e163fe5dbde88c0cc on Ethereum · Dynamic fee · Verified contract

Volume (24h)
$0.59
Value locked (TVL)
$49.24K
All-time volume
$197.51K
Pools using this hook
2
Swaps (24h)
2 (2 traders)
Total swaps
1,128

What it does

JrnyHook charges an extra ETH fee on every swap that pays or receives native ETH, at a rate the owner sets (up to 99.99%) with an optional time-decaying shock fee, and sends the fees to owner-chosen receivers, so buyers and sellers both pay more while the fee is active.

How it works step by step

  • Hook is paired with a pool whose currency0 is native ETH; any other currency0 reverts with ProtocolTokenNotSupported.
  • On a buy (zeroForOne, paying ETH) with exact-input, it takes a fee in ETH from the pool before the swap via beforeSwap return delta and records it as gathered fees.
  • On a sell with exact-output (ETH owed to the seller), it takes the fee via beforeSwap return delta, inflating the required token input.
  • In afterSwap, for buy exact-output and sell exact-input cases, it takes the fee in ETH from the pool and returns it as an afterSwap delta.
  • The fee rate is a compounded sum of protocol receiver percentages, optionally replaced by a time-decaying shock fee up to maxCompoundedFee (capped at 99.99%) during a configured window, filterable by buy/sell direction.
  • Gathered fees are forwarded to fee receivers (ETH transfers) automatically once a minimum threshold is exceeded, or manually via distributeFees; failed transfers are stashed for owner withdrawal.
Swap behaviour
Swaps where currency0 is native ETH and the swap is a buy (ETH in, token out) or a sell (token in, ETH out) pay an extra ETH-denominated fee taken by the hook at the rate returned by getCurrentCompoundedFee for that direction. Buys and sells are both charged while the fee direction flag and the shock window allow it; outside the shock window the normal compounded fee applies. Swaps in pools where currency0 is not native ETH revert.
Liquidity behaviour
No liquidity callbacks.
Fee behaviour
The hook charges a dynamic fee in ETH on swaps: amount multiplied by the compounded fee (basis points out of 10000) for the swap direction. The base compounded fee is the sum of configured receiver percentages; during a configured start/end window it can rise to maxCompoundedFee (default 99%) and decays toward the base as the end timestamp nears. Collected fees are distributed proportionally to receivers. The pool's own static fee is not referenced by this hook.
Owner & admin controls
The Ownable owner can set receivers and their fee percentages, change maxCompoundedFee (up to 99.99%), set the minimum gathered-fee threshold, set shock-fee start/end timestamps and fee direction, grant or revoke operator status, set the sunrise time, withdraw ETH via emergencyWithdraw and the stash via emergencyWithdrawStash, and transfer or renounce ownership. Operators may change fee direction and the shock-fee window only until the sunrise time has passed. There is no pause and no proxy upgrade path on the hook itself; the separate JrnyToken is UUPS upgradeable by its owner.

Enabled Uniswap v4 callbacks

beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta

beforeSwap: takes the fee in ETH for buy exact-input and sell exact-output swaps and sets a beforeSwap return delta to account for it. afterSwap: takes the fee for buy exact-output and sell exact-input swaps and returns it as an afterSwap delta. beforeSwapReturnDelta and afterSwapReturnDelta: allow those hook-returned deltas to alter the amounts the swapper settles.

Security & trust assessment

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

Who controls it: A single owner key (with operator delegates) can raise fees to near 100% on swaps in the pool, redirect fee receivers, drain the hook's ETH balance via emergencyWithdraw, and transfer or renounce ownership with no timelock or pause.

Risk to user funds: Swappers' ETH is affected by the hook's fee on buys and sells, and the hook custodies collected ETH fees until distribution or owner withdrawal, so users are exposed to owner-chosen fee levels and admin withdrawals.

Security findings

  • [high] Owner can set fees up to 99.99%: setMaxCompoundedFee accepts values up to 9999 and setReceiver accepts arbitrary fee weights, so the owner or an operator (before sunrise) can raise the charged ETH fee on every buy and sell to nearly the full swap amount.
  • [medium] Hook takes ETH via return deltas: beforeSwap and afterSwap call poolManager.take and return deltas, so the hook directly moves ETH out of swap settlement; the amount is computed from the swap amount and mutable fee rate, which affects swapper output and pool solvency.
  • [medium] Emergency withdrawals drain ETH to owner: emergencyWithdraw can send any ETH balance held by the hook to the owner, and the stash can be withdrawn too; the hook holds collected fees between distributions, so these functions are a direct custody path.
  • [low] Unbounded fee receivers and forwarding loop: Receiver ETH transfers use low-level calls inside a loop; a reverting receiver is handled by stashing, but a growing receiver set increases gas per distribution and distribution is triggered inside swaps.
  • [info] Trade direction semantics depend on owner config: Fee direction flags and the shock window are owner- and operator-set, so which trades pay the fee can change over time.

Contract details

Verified source
Yes (JrnyHook)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
9,321 bytes
Upgradeable proxy
No
Detected patterns
dynamic-fee, liquidity-management, moves-currency, ownable, return-delta

Pools using JrnyHook