GardenHook
EthereumGardenHook is a Uniswap v4 hook on Ethereum. Brand new: its first pool went live today. Still in use: 6 trades in the last week, and 1 new pool this week.
- Contract name
- GardenHook
How this hook works
Trading taxA trading tax hook. It takes a cut of every trade, charges more right after launch and limits trading to stop bots.
Takes a cut of every trade
On top of the normal pool fee, it keeps a share of each trade. The fee can be changed. The fee builds up in the hook until it is collected.
The code that does this (beforeSwap):function _beforeSwap(address, PoolKey calldata, SwapParams calldata params, bytes calldata) internal override returns (bytes4, BeforeSwapDelta, uint24) { if (_isBuy(params.zeroForOne) && params.amountSpecified < 0) { uint256 fee = (uint256(-params.amountSpecified) * currentBuyBps()) / BPS; if (fee > 0) { poolManager.take(Currency.wrap(quote), address(this), fee); emit FeeAccrued(true, fee); return (BaseHook.beforeSwap.selector, toBeforeSwapDelta(int128(int256(fee)), 0), 0); } } return (BaseHook.beforeSwap.selector, toBeforeSwapDelta(0, 0), 0); }Higher at launch
The fee starts higher right after launch and comes down over time, which makes it costly for bots to buy first.
The code that does this (currentBuyBps):function currentBuyBps() public view returns (uint16) { if (launchedAt == 0 || antiSniperSeconds == 0 || antiSniperBps <= buyBps) return buyBps; uint256 elapsed = block.timestamp - launchedAt; if (elapsed >= antiSniperSeconds) return buyBps; return uint16(antiSniperBps - (uint256(antiSniperBps - buyBps) * elapsed) / antiSniperSeconds); }Limits on trading
It limits trading, for example a max buy or wallet size or a wait between trades, to stop bots grabbing the supply before real traders.
The code that does this (currentBuyBps):function currentBuyBps() public view returns (uint16) { if (launchedAt == 0 || antiSniperSeconds == 0 || antiSniperBps <= buyBps) return buyBps; uint256 elapsed = block.timestamp - launchedAt; if (elapsed >= antiSniperSeconds) return buyBps; return uint16(antiSniperBps - (uint256(antiSniperBps - buyBps) * elapsed) / antiSniperSeconds); }Only approved callers create pools
New pools with this hook can only be created by approved callers, for example its own factory or launcher.
The code that does this (beforeInitialize):function _beforeInitialize(address sender, PoolKey calldata key, uint160 sqrtPriceX96) internal override returns (bytes4) { if (Currency.unwrap(key.currency0) != (quoteIsCurrency0 ? quote : token) || Currency.unwrap(key.currency1) != (quoteIsCurrency0 ? token : quote)) revert WrongPool(); if (poolInitialized) revert AlreadyOpened(); if (sender != opener) revert WrongOpener(sender); if (sqrtPriceX96 != openSqrtPriceX96) revert WrongPrice(sqrtPriceX96, openSqrtPriceX96); poolInitialized = true; launchedAt = uint64(block.timestamp); emit PoolOpened(uint64(block.timestamp)); return BaseHook.beforeInitialize.selector; }
Who controls it: The hook developer can change the fee. The hook developer can also call: release. The code cannot be changed.
Based on the hook’s published code.What do these labels mean?
What it can do
Its code executes inside each trade in pools that use it.
It can take or add tokens during a swap. Fees, burns and custom curves work this way, and so do scams.
It runs when a pool is created, often to lock in that pool’s settings.
Hook history
- Took its fee from a trade 6 times
Latest transactions
- 0x71176c22…219b82 block 26,411,374
- 0xf7733af1…c4df39 block 26,411,373
- 0x7e8ab456…854bf4 block 26,411,370
- 0x2f5ed7ac…ae8362 block 26,411,364
- 0x4a007daa…d5f3a7 block 26,411,362
- 0x3b8a1bfa…8960fb block 26,411,361
- Opened a pool 1 time
- Paid out 1 time
Counted from what the hook recorded on-chain across all its pools, for every action in its published code, plus token transfers in and out of it.