FxSaveZCHFHook on Ethereum

Uniswap v4 Hook Contract 0xfcac6a3af49695d1a6c5907d702c7287574ceacc on Ethereum · Utility · Verified contract

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

What it does

A single-pool fxSAVE/ZCHF Uniswap v4 hook that pools LP capital into a share token, deploys it as full-range liquidity during swaps, and parks idle ZCHF in the Savings module to earn yield for LPs.

How it works step by step

  • Accepts deposits of fxSAVE and ZCHF in exchange for ERC20 LP shares and lets holders redeem pro-rata.
  • Deploys inventory as full-range JIT liquidity in the pool during each swap and withdraws it afterwards.
  • Charges an extra 0.75 bps fee on swaps via beforeSwap and afterSwap return deltas, credited as protocol claims.
  • Moves idle ZCHF into the Savings module to earn interest and withdraws it when needed for redemptions or swaps.
  • Blocks direct LP add and remove and direct pool initialization so all liquidity goes through the hook's share mechanism.
Swap behaviour
On each swap the hook takes a 0.75 bps fee via return deltas, deploys full-range liquidity from its inventory into the pool, and removes it after the swap, settling token balances with the PoolManager. Swaps revert while paused.
Liquidity behaviour
Direct LP add/remove is blocked (beforeAddLiquidity and beforeRemoveLiquidity revert). Liquidity is provided through the hook's own deposit and redeem functions that mint or burn ERC20 share tokens. The hook deploys full-range JIT liquidity from its inventory into the pool during each swap and removes it afterwards.
Fee behaviour
Pool LP fee is fixed at 5 bps. The hook takes an additional 0.75 bps (15% of the LP fee) via beforeSwap/afterSwap return deltas, minted as ERC-6909 claims credited to the protocol fee recipient. Swaps with negative amountSpecified are charged upfront; exact-output swaps are charged in afterSwap.
Owner & admin controls
Owner (Ownable2Step, renounceOwnership disabled) can initializePool, bootstrap, unpause, setGuardian, proposeProtocolFeeRecipient and restoreSavings. Owner or guardian can pause swaps and emergencyRevokeSavings, which pulls ZCHF back out of the Savings module. No upgrade proxy is present; the contract is non-upgradeable and parameters are immutable except the protocol fee recipient, guardian and pause/savings flags.

Enabled Uniswap v4 callbacks

beforeInitialize, beforeAddLiquidity, beforeRemoveLiquidity, beforeSwap, afterSwap, beforeSwapReturnDelta, afterSwapReturnDelta

beforeInitialize: reverts direct initialization so the pool can only be set up by the owner through initializePool. beforeAddLiquidity and beforeRemoveLiquidity: revert direct LP to force use of the share-based deposit and redeem flow. beforeSwap: enforces pool key, pause status and fee charging, and deploys JIT liquidity. afterSwap: validates partial-fill behaviour, removes JIT liquidity, settles currencies and returns exact-output fee delta. beforeSwapReturnDelta and afterSwapReturnDelta: allow the hook to take its 0.75 bps fee from swap amounts.

Security & trust assessment

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

Who controls it: The owner can unpause swaps, change the guardian, and set the protocol fee recipient after a two-step proposal. The guardian or owner can pause swaps and withdraw Savings positions back to the hook, which halts trading and deposits. The owner cannot directly move user LP funds out of the hook; redemptions are always available to share holders while the pool is not in a JIT operation.

Risk to user funds: The hook holds LP inventory (raw fxSAVE and ZCHF, ERC-6909 claims and Savings deposits) and protocol fee claims. Users deposit assets for shares and can redeem them through the hook while it is not mid-operation; the owner or guardian can pause swaps and revoke Savings, but cannot unilaterally seize user shares.

Security findings

  • [medium] Privileged pause can halt trading: Owner and guardian can set swapsPaused and call emergencyRevokeSavings, which halts all swaps and deposits. Redemption is not blocked by pause, so LP exit remains possible.
  • [medium] Dependence on external Savings module: Funds are held in an external Savings contract via the hook; emergencyRevokeSavings can withdraw them back, but Savings or ZCHF failures could leave deposits temporarily stuck or affect redemption liquidity.
  • [low] Protocol fee recipient is owner-controlled: Protocol fees are minted as ERC-6909 claims to the protocol fee recipient, who can claim them. The recipient can be changed by the owner via a two-step process, redirecting future fee income.
  • [low] Complex accounting and JIT logic: The hook uses transient-storage JIT locks and return deltas and reconciles untracked balances as LP surplus; these paths are intricate and depend on PoolManager behaviour, so they carry implementation risk.
  • [info] Owner cannot renounce: Owner can unpause, bootstrap and set parameters, and renounceOwnership is disabled, so the owner cannot be removed.

Contract details

Verified source
Yes (FxSaveZCHFHook)
Compiler
solc 0.8.26+commit.8a97fa7a
Bytecode size
24,237 bytes
Upgradeable proxy
No
Detected patterns
erc20, moves-currency, ownable, return-delta, self-unlock, tax

Pools using FxSaveZCHFHook