AntiMevTaxHook
RobinhoodAntiMevTaxHook is a Uniswap v4 hook on Robinhood Chain. Brand new: its first pool went live today. Still in use: 2 trades in the last week, and 1 new pool this week.
- Contract name
- AntiMevTaxHook
How this hook works
Anti-MEV taxThis hook punishes MEV bots, programs that trade right before and after others to skim profit. A trade that reverses the pool's last trade direction within two blocks pays a 49% tax, which is given to liquidity providers.
49% tax on quick reversals
If a trade goes the opposite way to the pool's previous trade within two blocks, it pays 49% of its output as a tax. Normal trades pay only the usual pool fee.
The code that does this (_recordAndMeasureTax):function _recordAndMeasureTax(PoolKey calldata key, SwapParams calldata params, BalanceDelta delta) private returns (uint256 amountOut, uint256 tax) { PoolId pid = key.toId(); LastSwap memory last = lastSwapOf[pid]; bool mev = _isMevSwap(last, params.zeroForOne); // !MEV if (!mev) { lastSwapOf[pid] = LastSwap({blockNumber: uint64(_blockNumber()), zeroForOne: params.zeroForOne}); return (0, 0); } if (params.amountSpecified >= 0) { int128 payer = params.zeroForOne ? _amount0(delta) : _amount1(delta); if (payer >= 0) return (0, 0); amountOut = uint256(params.amountSpecified); tax = (uint256(-int256(payer)) * MEV_TAX_PIPS) / PIPS; } else { int128 unspecified = params.zeroForOne ? _amount1(delta) : _amount0(delta); if (unspecified <= 0) return (0, 0); amountOut = uint256(uint128(unspecified)); tax = (amountOut * MEV_TAX_PIPS) / PIPS; } if (tax > uint256(uint128(type(int128).max))) return (0, 0); }Tax goes to liquidity providers
The tax is added to the pool's fees, so it goes to liquidity providers.
The code that does this (_handleAfterSwap):function _handleAfterSwap( address sender, PoolKey calldata key, SwapParams calldata params, BalanceDelta delta ) private returns (bytes4, int128) { (uint256 amountOut, uint256 tax) = _recordAndMeasureTax(key, params, delta); if (tax == 0) return (IHooks.afterSwap.selector, 0); // donate debits this hook and the returned delta credits it back, so the // tax ends up in feeGrowthGlobal and the hook's own balance stays zero. bool taxInToken0 = params.amountSpecified < 0 ? !params.zeroForOne : params.zeroForOne; bool donated; try manager.donate(key, taxInToken0 ? tax : 0, taxInToken0 ? 0 : tax, "") returns (BalanceDelta) { donated = true; } catch {} if (!donated) return (IHooks.afterSwap.selector, 0); emit MevTaxDonated(PoolId.unwrap(key.toId()), sender, params.zeroForOne, amountOut, tax); return (IHooks.afterSwap.selector, int128(uint128(tax))); }Only approved addresses add liquidity
Adding liquidity is limited to addresses on an approved list.
The code that does this (beforeAddLiquidity):function beforeAddLiquidity(address sender, PoolKey calldata, ModifyLiquidityParams calldata, bytes calldata) external view onlyManager returns (bytes4) { if (!liquidityAdder[tx.origin]) revert NotLiquidityOrigin(sender, tx.origin); return IHooks.beforeAddLiquidity.selector; }
Who controls it: The hook developer can choose who is allowed to add liquidity. The tax rate and block window are fixed, and the code cannot be upgraded.
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 checks every deposit before it goes in.
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.