AstraHook
EthereumAstraHook is a Uniswap v4 hook on Ethereum. Runs code on every swap. Can take tokens from swaps. Runs at pool creation.
- Contract name
- AstraHook
How this hook works
Trading taxA trading tax hook. It takes a tax on trades, buys back the token and limits trading at launch.
Takes a tax on trades
On top of the normal pool fee, it keeps part of each trade as a tax. Buys and sells can be taxed differently.
The code that does this (beforeSwap):function beforeSwap(address sender, PoolKey calldata, SwapParams calldata params, bytes calldata) external onlyPoolManager returns (bytes4, BeforeSwapDelta, uint24) { if (!tradingEnabled) revert TradingNotEnabled(); if (bypassed) return (IHooks.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); bool isBuy = params.zeroForOne; bool exactIn = params.amountSpecified < 0; if (exactIn != isBuy || isExempt[sender]) { return (IHooks.beforeSwap.selector, BeforeSwapDeltaLibrary.ZERO_DELTA, 0); } _enter(); uint256 amount = exactIn ? uint256(-params.amountSpecified) : uint256(params.amountSpecified); uint256 fee = _collect(sender, amount, isBuy, exactIn); if (fee != 0) _expectedEth = exactIn ? amount - fee : amount + fee; _exit(); return (IHooks.beforeSwap.selector, toBeforeSwapDelta(fee.toInt128(), 0), 0); }Buys back the token
It uses what it collects to buy the token back.
The code that does this (executeBuyback):function _executeBuyback(uint256 amount) internal returns (uint256 astraOut) { uint160 limit = _buybackPriceLimit(); (uint160 sqrtP,,,) = poolManager.getSlot0(poolId); if (sqrtP <= limit) return 0; pendingBurn -= uint128(amount); BalanceDelta delta = poolManager.swap( poolKey(), SwapParams({zeroForOne: true, amountSpecified: -int256(amount), sqrtPriceLimitX96: limit}), "" ); uint256 ethOwed = uint128(-delta.amount0()); astraOut = uint128(delta.amount1()); poolManager.sync(ETH); poolManager.settle{value: ethOwed}(); if (astraOut != 0) poolManager.take(astra, DEAD, astraOut); if (ethOwed < amount) pendingBurn += uint128(amount - ethOwed); }Launch protection
It limits trading, for example a max buy or wallet size or a cooldown, to stop bots grabbing the supply before real traders.
The code that does this (buybackPriceLimit):function _buybackPriceLimit() internal returns (uint160) { if (block.number != _buybackBlock) { (_buybackRefSqrtP,,,) = poolManager.getSlot0(poolId); _buybackBlock = uint64(block.number); } uint160 sqrtP = _buybackRefSqrtP; uint256 limit = uint256(sqrtP) * Math.sqrt((10_000 - uint256(maxBuybackImpactBps)) * 1e28) / 1e16; return limit <= TickMath.MIN_SQRT_PRICE ? TickMath.MIN_SQRT_PRICE + 1 : uint160(limit); }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) external view onlyPoolManager returns (bytes4) { if (sender != owner()) revert NotInitializer(); if (PoolId.unwrap(key.toId()) != PoolId.unwrap(poolId)) revert WrongPool(); return IHooks.beforeInitialize.selector; }Anyone can trigger payouts
Anyone can pay out what it has collected, send the collected fees on to where they go and trigger a buyback, so nobody has to wait on the hook developer.
The code that does this (distribute):function distribute() external locked { uint256 t = pendingTreasury; if (t != 0) { pendingTreasury = 0; if (!_forward(Bucket.TREASURY, config.treasury, t, gasleft())) pendingTreasury = uint128(t); } uint256 r = pendingReserve; if (r != 0) { pendingReserve = 0; address bridger_ = bridger; if (_forward(Bucket.RESERVE, bridger_, r, gasleft())) _pokeBridger(bridger_); else pendingReserve = uint128(r); } }
Who controls it: The code itself can’t be changed. The hook developer can change: trading, bypass, buy tax, sell tax, destinations, exempt and 3 more. The hook developer can also call: buyback now, release burn bucket.
Based on the hook’s published code.
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
Nothing recorded yet.
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.