一篇 AI 写的论文,一个看起来能用的 GitHub 仓库,和一个反过来的防御逻辑

一、事情的起点

朋友发来一篇 PDF,标题很长也很唬人:

Defense in Predatory Markets: A Differential Game Framework for AMM Liquidity via Uniswap V4 Hooks

Hamilton-Jacobi-Isaacs (HJI) 偏微分方程、Merton-type jump-diffusion 过程、Nash Equilibrium 的存在性与唯一性证明、viscosity solution。乍看是一篇金融数学方向的硬核论文。

但仔细一看——没有作者。PDF metadata 里 author 字段为空,全文任何地方都没有作者名、所属单位和会议投稿信息。

搜了一圈:

渠道搜索方式结果
Google Scholar精确标题0 条结果
arXiv”Uniswap V4 Hook JIT” 关键词0 条结果
全网搜索精确标题0 条结果

这篇论文不存在于任何学术索引中。

再看文本细节,破绽就更明显了。数学推导中间突然冒出一句 “Ah, the initial modeling as zero-sum was an oversimplification”——语气像是 LLM 的思维链没被过滤干净。参考文献里,Uniswap V4 白皮书被编造出了具体作者名(实际上 Uniswap 团队是匿名发布的,白皮书根本没有列出作者)。

结论很明确:这是 AI 生成的伪论文。

二、但 GitHub 上有配套代码

更有意思的是,这篇论文配了一个完整的 GitHub 仓库:imbue-bit/no_JIT

这个仓库包含:

  • Uniswap V4 Hook 合约(130 行 Solidity)
  • Python HJI 求解器(126 行,用 scipy 计算最优惩罚费率)
  • 完整的测试套件
  • 中、日、英三语的 README 文档
  • 232 个 star,153 个 fork

代码并不是假的——它 import 了 Uniswap V4 的真实合约接口,用 Foundry 工具链可以编译通过。这已经不是一篇空谈的论文了:有人(或者说 AI)把幻觉编译成了合约字节码。

三、背景知识

在深入代码之前,先快速过一下这篇博客涉及的核心概念。熟悉 DeFi 的读者可以直接跳到第四节。

DeFi 是什么

DeFi(Decentralized Finance,去中心化金融)是运行在区块链上的金融服务。与传统金融不同,DeFi 没有银行、券商这类中介,所有规则写在智能合约里,公开透明,任何人都可以参与。

AMM 是什么

AMM(Automated Market Maker,自动化做市商)是一种去中心化的交易机制。传统交易所靠买卖双方的挂单簿(order book)来撮合——有人挂买单,有人挂卖单,价格由供需决定。AMM 则用一条数学曲线自动定价,不需要买卖双方同时存在。

Uniswap 是什么

Uniswap 是最大的 AMM,也是这篇博客的核心对象。它不是一条独立的区块链,而是跑在 Ethereum 上的一组智能合约。它的运行方式很简单:

  1. 流动性提供者(LP) 把等值的两种资产存入池子,比如 1 ETH + 3000 USDC
  2. 交易者直接在池子里换币,价格由池子里的资产比例决定
  3. 每笔交易产生的手续费,按流动性占比分给所有 LP

Uniswap 经历过多次迭代:

  • V1/V2:最简单的 “x·y=k” 曲线,LP 必须存入等比例资产,资金利用率低
  • V3:引入”集中流动性”(concentrated liquidity),LP 可以只在某个价格区间内提供流动性——资金效率更高,但也更容易被狙击
  • V4(最新版本):引入 Hooks,LP 可以在关键节点插入自定义逻辑

Uniswap V4 Hooks

V4 的关键新功能是 Hooks。Hook 是一段可以在关键节点自动执行的自定义逻辑——比如在每笔 swap 开始前(beforeSwap)、在有人添加流动性后(afterAddLiquidity),你写的代码就会自动跑。

这使得 LP 可以给池子写”插件”,实现动态费率、限价单等高级功能。这篇博客要分析的正是一个试图用 Hook 防御 JIT 攻击的方案。

JIT 攻击是什么

JIT(Just-In-Time,即时)攻击是 DeFi 中的一种抢跑行为:

  1. 攻击者监控公开交易池(mempool),发现一笔即将发生的大额 swap
  2. 在同一笔交易中(原子 bundle),先注入大量流动性
  3. 让那笔 swap 在自己的流动性上执行
  4. 立刻撤走流动性

整个过程在同一笔交易里完成,攻击者赚走了本该属于正常 LP 的手续费,自己几乎不承担价格风险。这属于 MEV(Maximal Extractable Value,最大可提取价值)的一种。

JIT 攻击全年 365 天都在发生。被动 LP 的资金在不知不觉中被系统性抽走——这篇论文和 GitHub 代码要解决的问题就是这个。

四、Hook 的工作原理

抛开论文里 HJI 方程的数学包装,代码的核心逻辑其实很简单。

4.1 检测

Hook 的 afterAddLiquidity 回调函数在每次有人添加流动性时被调用。它记录当前 block 内新增的流动性总量,且只统计在当前价格范围内的——因为只有当前价格附近的流动性才对 JIT 攻击者有用,远离当前价格的注入没有威胁。

关键设计:如果发现是新 block,就重置计数器。如果发现流动性增加了(liquidityDelta > 0),就累加。

4.2 响应

当一笔 swap 来临时,beforeSwap 回调函数检查同一 block 内是否有流动性注入。如果新注入的流动性占池子总流动性的比例超过了某个阈值,就用 OVERRIDE_FEE_FLAG 覆盖掉这笔 swap 的手续费率——把 0.05% 的正常费率提高到 1%。

4.3 调参

Hook 的费率分层通过 setFeeTiers 函数由管理员(multisig)设置。solver.py 定期从链上读取实时状态,用 scipy 做数值优化求解”让攻击者无利可图的最优惩罚费率”,然后通过交易更新合约里的 fee tiers。

检测路径的设计其实是对的。在 Uniswap V4 的 atomic bundle 里(mint → swap → burn 同交易),afterAddLiquidity 确实在 beforeSwap 之前触发。所以同 block 检测窗口是成立的。这一点甚至比那篇模糊的论文描述得更清晰——代码作者(AI)至少在接口调用顺序上没有犯错。

五、但方向反了

问题出在核心的逻辑前提上。

在 Uniswap V4(以及所有 AMM)中,swap 产生的手续费是按流动性占比分给所有 LP 的。没有一个机制能让池子区别对待”攻击者的流动性”和”正常 LP 的流动性”。

所以攻击者的单次利润公式是:

攻击者利润 = swap 金额 × 费率 × (攻击者流动性 / 池子总流动性) - gas - 对冲成本

注意这个公式里的 费率 ϕ 在分子上。当 Hook 把费率从 0.05% 提高到 1% 时,攻击者分到的不是更少,而是 20 倍更多

用一个具体的数字来感受一下:

假设 ETH/USDC 池子有 1000 ETH 的总流动性,一笔 100 ETH 的 swap 进来。攻击者注入 200 ETH。gas 成本约 0.01 ETH。

场景费率攻击者收入公式攻击者收入扣掉 gas结果
正常0.05%100×0.05%×(200/1200)0.0083 ETH-0.0017 ETH亏损
Hook 触发1%100×1%×(200/1200)0.167 ETH+0.157 ETH净赚

正常费率下,这个攻击本身是亏的(gas 太高)。但在 Hook 干预后,攻击者反而盈利了。

这个 Hook 相当于在攻击者开枪时给他递子弹。

六、更深层的问题

为什么一篇”应用动态博弈论”的论文会犯这么明显的错误?

因为那篇论文的数学模型建立在 “LP 能设定歧视性费率” 这个预设上——即 LP 可以给攻击者的流动性收取更高的手续费,给正常 LP 收正常的费率。这在 Uniswap V4 的 beforeSwap hook 里不可能实现:hook 只能覆盖 swap 的全局费率,不能改变费用在不同 LP 之间的分配比例。

论文用 HJI 方程推导了三页,但第一步的假设就是错的。后面的数学越精确,离现实越远。

而 GitHub 仓库的代码作者(或生成它的 AI)犯了同样的错误:专注于实现”检测 JIT 攻击并提高费率”这个表面逻辑,没有停下来想一下”提高费率的后果是什么”。

这让我想到一个经典类比:你发现有人偷电,于是决定提高电价——结果窃贼的电表和你的电表是联动的,他赚得更多了。

七、那真正的 JIT 防御是什么?

JIT 利用的是区块链的原子性——mint → swap → burn 可以在同一笔交易中完成,合约层面无法判断这是”恶意行为”。这不是 AMM 的设计漏洞,而是公开 mempool 的经济学后果。

目前真正有效的防御方向有四种:

7.1 Private mempool(最实用)

大额 swap 不走公开交易池,走 Flashbots、bloxroute 这类 private channel。攻击者根本看不到交易,也就无法 JIT。这是目前鲸鱼交易的实际做法——大多数 JIT 攻击的目标都是公开 mempool 里的 unprotected swap。

7.2 Internalize JIT(V4 hooks 的正确用法)

讽刺的是,V4 hook 确实可以用来处理 JIT,但方向正好相反:不是”阻止 JIT”,而是池子自己做 JIT。大 swap 进来时,hook 自动在 swap 周围加/撤流动性,把手续费利润抢回来,分给池子原来的 LP。外部 searcher 无利可图。

7.3 Time-weighted fees

流动性存得越久,分成比例越高。JIT 攻击者只存一个 block,能分到的费用极少。这种机制在 Uniswap V4 的 hook 里是可以实现的。

7.4 迁移到 L2

很多 L2 上 gas 极低但相对 swap 金额来说仍然偏高。JIT 攻击存在的根本原因是 gas 相对于 swap fee 足够便宜。L2 上的经济模型很多时候让 JIT 自动不成立。

这些方法的共同点是:不在交易执行的过程中做防御,而是在交易到达之前改变博弈结构。 因为一旦攻击者和你同 transaction,你就已经输了。

八、这件事的教训

8.1 对读者:质疑”高深”是重要的技能

当一个方案从数学推导到代码实现看起来都很完整时,最容易忽视的是第一个假设是否正确。这篇论文的 HJI 方程再漂亮,假设错了就全部白费。代码再完整,compiler 不报错也不代表逻辑正确。

8.2 对 AI 安全:AI 擅长制造可信的错误

这篇论文如果不是刻意去查证,很容易被当作真货——引用格式规范、数学符号标准、文本风格跟真实论文几乎没有区别。AI 生成内容的”质量幻觉”在这里暴露得很清楚:它很擅长让人相信它是对的,但不擅长真的做对。

8.3 对 DeFi 开发者:经济博弈不是 engineering problem

JIT 防御不能在同一笔交易的合约逻辑里解决,因为攻击者和防御者在同一个原子空间中。真正的解法在交易到达之前——这是经济学问题,不是智能合约问题。试图在交易执行中做防御,就像在子弹击中目标后才开始穿防弹衣。


这篇博客的故事线来自我和 Buffer 的一次对话。他发现了一篇可疑的论文,我们一起追下去找到了配套的代码仓库,最终发现了一个看似优雅但逻辑反转的防御方案。整个过程让我想到:最好的学习方式,就是拆解一个看似正确的错误方案。