Table of contents
Open Table of contents
一、背景介绍:V4 协议费从哪天开始收
收费时间线
Uniswap 在 2026 年 7 月 27 日 执行了第一批治理提案,正式在以下链上开启 V4 协议费:
- Ethereum
- Arbitrum
- Base
- BNB Chain
- Polygon
- Optimism
- Robinhood Chain
也就是说,从 2026 年 7 月 27 日起,这些链上符合条件的 V4 池就开始收协议费了。
协议费 vs LP 费:不是一回事
交易者付的 swap fee 里,其实拆成了两块:一部分给协议层(Protocol Fee),一部分给流动性提供者(LP Fee)。
V4 core 是先对输入金额收 protocol fee,再对剩余金额收 LP fee,所以合成公式不是简单的相加:
swapFee = protocolFee + lpFee - (protocolFee × lpFee / 1,000,000)
举个数感上的例子:一个 0.30% LP fee + 0.05% protocol fee 的池子,交易 10,000 USDC 时,协议大约拿 5 USDC,LP 大约拿 29.985 USDC,总手续费约 34.985 USDC,换算下来约 0.34985%——比直接 0.35% 略低一点点,因为两种费率是顺序作用的。
V4 的两个特殊点
第一,protocol fee 可以按交易方向分别设置。比如 token0→token1 收 5 bps、token1→token0 收 3 bps,这两个值编码在同一个协议费配置里。当然,V4 core 对单个方向的协议费有上限,MAX_PROTOCOL_FEE 是 1000 pips = 0.1% = 10 bps。
第二,要区分三个容易搞混的概念——LP fee 是 LP 提供流动性的收入,Protocol fee 是协议层抽走的收入,Hook fee 是 Hook 自己额外设计的收费机制。Hook fee 是 V4 的扩展能力,跟 core 层面的 LP fee / protocol fee 不在一个维度。
关键:不是所有池子都收
这次收费有明确的 pool family 限定,不是给所有 V4 池统一打开 fee switch。具体来说,目前开启协议费的是三类:
- Static fee pools / 无 Hook 池:最常见的普通 V4 池,按 LP fee 曲线算协议费
- CCA pools:由 Continuous Clearing Auction 创建的池,含指定的 LBPHook
- Aggregator Hook pools:Hook 整合了外部流动性场所的池
而其他普通 Hook pools 默认不收(除非治理后续把它加进收费名单或单独 override);Dynamic fee Hook pools 也不一定收,要具体看它的 Hook 是否属于收费 family。
对于最常见的无 Hook static pool,协议费大致按这个曲线对应(LP fee → Protocol fee):
0.03 bps → 0.01 bps
0.75 bps → 0.20 bps
1 bps → 0.25 bps
3.75 bps → 1 bps
5 bps → 1.25 bps
25 bps → 4 bps
30 bps → 5 bps(0.05%)
≥83.34 bps → 10 bps(0.10%,封顶)
协议费上限仍是 10 bps。
所以一个很实用的判断:Ethereum 上一个 USDC/ETH、0.30% LP fee、没有 Hook 的普通池,从 7 月 27 日起就要交 0.05% 的协议费,交易者有效手续费约 0.34985%。
二、实操:怎么用 Hook 池规避协议费
核心思路
既然协议费只对”无 Hook 的 static pool”等少数 family 收,那理论上就能这么干:
建池时挂一个几乎什么都不干的 Hook,让池子变成”普通 Hook pool”,就能不进收费范围。
极端对比如下:
Pool A(要收费)
- ETH/USDC,30 bps LP fee,无 Hook → protocol fee 5 bps
Pool B(可能不收)
- ETH/USDC,30 bps LP fee,Hook 是一个
beforeSwap()什么都不做的合约 → 如果这个 Hook family 不在收费名单里 → protocol fee 0
只要 Pool B 的路由、gas、流动性体验和 A 差不多,理性的 LP 和 integrator 就有搬过去的动力。
实操要点:Hook 怎么部署
V4 的 Hook 不是随手部署个合约就能用——Hook 合约地址的低位编码了它启用的权限。要部署一个启用 beforeSwap(权限位 0x4000)的 Hook,部署地址必须满足:
uint160(hookAddress) & 0x3fff == 0x4000
这就是为什么部署 Hook 通常要 CREATE2:靠不断换 salt 提前算出地址,直到找到一个低位满足权限要求的。这跟我之前那篇《如何实现 Uniswap V4 流动性的白名单添加控制》用的是同一套路,只是那边是 beforeAddLiquidity(0x0800),这里换成 beforeSwap(0x4000)。
一个”空 Hook”的最小骨架大概长这样:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract EmptyBeforeSwapHook {
// 部署地址需满足 address & 0x3fff == 0x4000(beforeSwap 权限位)
address public immutable poolManager;
constructor(address poolManager_) {
poolManager = poolManager_;
}
function beforeSwap(
address,
PoolKey calldata,
Pool.SwapParams calldata,
bytes calldata
) external returns (bytes4, int128, int128) {
// 什么都不做,只返回需要的 selector
return (this.beforeSwap.selector, 0, 0);
}
}
(PoolKey、Pool.SwapParams 这些类型定义在 V4 的库里,实际项目直接 import 即可。)
但这不是”稳赚”的终局方案
话说回来,如果”无 Hook 池收费、挂个 Hook 就不收费”这么简单地写死,那确实会产生很强的规避激励。现实的机制其实是:
- 这是一套 V4 Fee Controller / Fee Policy,能按 pool / hook 类型分类收费,治理还能对具体 pool 做 override,而且官方明确说这套 policy 是可替换、可扩展的。
- 换句话说,“短期绕开”完全可能,但治理随时可以把这类 Hook 也纳入收费范围。
从机制设计角度看,这其实就是经典的 tax-base leakage / regulatory arbitrage(税基泄漏 / 规则套利):协议费越高,绕费的 Hook 越值得开发,流动性就越容易迁移,最终实际可征税的基数反而可能变小。所以 Uniswap 得把费率控制在”懒得为这几个 bps 绕路”的程度,或者把收费规则做得足够普适。
还有一层:Hook 不见得非得是”空”的。开发者完全可以挂一个很轻的功能(比如 TWAP 检查、限价逻辑、动态费率),顺手也拿到协议费优势。到时候治理再说”这个 Hook 是假的,我要收费”,分类就开始主观了。
小结
这次 V4 协议费上线,我更倾向于理解为第一阶段 rollout,而不是已经解决机制设计问题的终局方案。它明确只激活了三个 pool family,也保留了以后改分类规则的空间。
- 从 2026 年 7 月 27 日起,普通无 Hook 池开始收费,0.30% LP fee 的池现在是 0.05% protocol fee。
- 想”规避”的项目方,挂个轻量 Hook 让池子变成 Hook pool,短期确实可能不进收费范围。
- 但这是一场持续博弈——治理随时能扩大收费范围,“空 Hook 绕费”的窗口未必一直开着。
跑得快的能吃到这个时间差,但把它当成长期确定性方案,风险不小。
如果你对 PoolManager.swap() 里 protocol fee 具体怎么入账、ProtocolFeeLibrary.calculateSwapFee() 那几行怎么算感兴趣,也可以再展开聊聊。Hook 部署的更多细节,欢迎看我之前的《如何实现 Uniswap V4 流动性的白名单添加控制》,权限位和 CREATE2 的套路是通用的。