Fee sharing hook on Ethereum
Uniswap v4 Hook Contract 0x9fe25c916e29336ce0215ef89e9edba69216e0cc on Ethereum · Fee sharing
- Volume (24h)
- $0
- Value locked (TVL)
- $0
- All-time volume
- $0
- Pools using this hook
- 1
- Swaps (24h)
- 38 (16 traders)
- Total swaps
- 38
What it does
This hook charges an owner-adjustable toll on swaps in its pool, bounded by MIN_TOLL and MAX_TOLL, and forwards the collected tolls to a tollKeeper, so traders pay a bit more on every swap.
How it works step by step
- Charges a toll (fee) on swaps in a pool it is initialized for, using a beforeSwap/afterSwap pair with return deltas to take a portion of the swap amount
- Stores the toll parameters in storage: an entry toll and a bounded range between MIN_TOLL and MAX_TOLL expressed in basis points (BPS), set via Tolls(uint16,uint16)
- Accumulates collected tolls as unsentTolls and periodically forwards them through fillTreasure() to a tollKeeper address
- Mints and burns ERC-6909 claim tokens via the pool manager (mint/burn selectors present), so collected currency can be held as claims inside the PoolManager
- Uses unlock/unlockCallback (self-unlock) to settle currency movements with the pool manager, and take(address,address,uint256) to withdraw currency
- Blocks or tracks liquidity add/remove through beforeAddLiquidity, afterAddLiquidity, beforeRemoveLiquidity and afterRemoveLiquidity callbacks, which are present as selectors
- Swap behaviour
- On swaps, beforeSwap and afterSwap both run and afterSwap uses a return delta, so the hook takes a toll from the swap amount. Exact direction (input or output side) and the toll rate applied to specific trades could not be fully determined from decoded bytecode alone; the entry toll and the MIN_TOLL/MAX_TOLL bounds suggest the rate is configurable within limits.
- Liquidity behaviour
- Liquidity add and remove calls are routed through hook callbacks (beforeAddLiquidity, afterAddLiquidity, beforeRemoveLiquidity, afterRemoveLiquidity) which exist as selectors; the exact logic inside them cannot be confirmed from decoded bytecode, but the liquidity-management heuristic and the mint/burn claim selectors suggest the hook may hold ERC-6909 claims on behalf of liquidity flows.
- Fee behaviour
- The hook charges a toll rather than relying only on the pool's static fee. The toll rate is stored in the contract, bounded by MIN_TOLL and MAX_TOLL and expressed in BPS, and is updated by the owner through Tolls(uint16,uint16). Collected tolls accumulate in unsentTolls and are sent to the tollKeeper by fillTreasure().
- Owner & admin controls
- The owner (storage slot 0) can transfer ownership, set the vault (setVault), set the tollKeeper address (setTollKeeper), and change the toll parameters via Tolls(uint16,uint16). Toll bounds are constants (MIN_TOLL, MAX_TOLL), limiting how far the owner can raise the toll. No pause function was identified and no proxy upgrade mechanism was observed.
Enabled Uniswap v4 callbacks
beforeInitialize, beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta
beforeInitialize: records the pool identifier and initialization state for the pool it supports. beforeSwap: runs pre-swap checks and reads toll settings. afterSwap: computes and takes the toll using a return delta. beforeSwapReturnDelta and afterSwapReturnDelta: allow the hook to alter the swap amounts it returns, which is how the toll is collected. Liquidity callbacks are listed in the selectors but are not enabled in the permission flags supplied.
Security & trust assessment
Risk level: medium, estimated (decoded bytecode, medium confidence).
Who controls it: A single owner key can change the toll rate within bounds, redirect the tollKeeper and vault, and transfer ownership, so the owner controls where collected fees go and how much is taken from swaps.
Risk to user funds: The hook can take a share of swap amounts through return deltas and holds collected tolls and ERC-6909 claims before forwarding them to the tollKeeper, so user swap proceeds are directly exposed to the toll; it does not appear able to block swaps outright, based on the observed selectors.
Security findings
- [medium] Hook takes a toll via return deltas: beforeSwapReturnDelta and afterSwapReturnDelta are enabled, so the hook can take a share of every swap. The owner-controlled toll is bounded by MAX_TOLL, which limits but does not remove the extraction risk.
- [medium] Owner can change toll parameters: The Tolls(uint16,uint16) setter is callable by the owner, so the owner can adjust the toll rate up to the MAX_TOLL bound, affecting every swap in the pool.
- [medium] Owner controls the toll keeper and vault: setTollKeeper and setVault are owner-only, so a compromised owner key could redirect accumulated tolls (unsentTolls via fillTreasure) and currency movements to an address they control.
- [info] Currency movement through pool manager: The hook uses unlock, take, mint and burn, so it moves currency and ERC-6909 claims through the PoolManager; correctness of settlement could not be verified without source.
- [info] No verified source: Analysis is based on decoded bytecode only, so internal logic and edge cases could not be confirmed.
Contract details
- Verified source
- No
- Bytecode size
- 8,052 bytes
- Upgradeable proxy
- No
- Detected patterns
- erc6909-claims, liquidity-management, moves-currency, ownable, return-delta, self-unlock, tax