摘要:多池夹击的核心不是单个池子的滑点
现代 DeFi 价格操纵风险已经很少停留在“一个池子里前后夹一笔交易”的简单模型。更危险的路径是多池联合夹击(Multi-Pool Sandwich)和闪电贷驱动的多维清算线扭曲:攻击者不需要长期持仓,只要在一个原子交易窗口内同时影响 AMM 池、预言机采样、抵押率计算和清算触发条件,就可能让一个本应安全的仓位短暂落入可清算区域。本文从 Uniswap V2/V3、Curve 稳定交换、TWAP、预言机缓存和借贷协议清算模型出发,建立一个防御性数学框架:把每个池子的局部滑点导数扩展成跨协议价格向量的雅可比矩阵,再用风险值(VaR)和熔断状态机约束异常路径。对 AllSwap 这类跨链交换而言,关键不是预测每一次 MEV,而是避免把被操纵的短时价格当作可执行报价和退款依据。
问题边界:防御性建模,不提供攻击流程
本文讨论的是协议防御、路由风控和清算风险建模,不提供可复用夹击脚本、交易排序模板、目标池筛选方法或真实系统攻击步骤。系统角色包括:AMM 池、借贷协议、预言机、清算者、MEV Builder、搜索者、跨链路由器、用户和风控合约。攻击者能力假设为:可以获得闪电贷或短期流动性,可以在同一执行窗口内提交多笔交易,可以观察公开 mempool 或 Builder 订单流,可以利用协议间价格引用滞后;不假设攻击者能伪造预言机签名、绕过共识规则或修改合约代码。
边界要先划清。单池夹击主要影响用户成交价格;多池联合夹击影响的是“其他协议如何读取价格”。如果一个借贷协议用某个 AMM 派生价格计算健康因子,而另一个衍生品池又用该价格更新保证金,价格向量就不再是独立变量。一个池子的瞬时偏移会通过预言机、TWAP、抵押率、合成资产指数和清算阈值传播,形成跨协议状态冲击。防御目标不是让价格永不波动,而是让异常的、短时的、不可持续的价格不触发不可逆清算或跨链释放。
对跨链交换还要增加一个维度:时间。源链报价、目标链执行、桥确认、退款窗口和预言机更新时间并不同步。某条路线在报价时安全,不代表目标链执行时仍安全;某个 TWAP 在本链足够稳健,不代表跨链等待期间没有过期。AllSwap 的路由风险模型必须把价格冲击、最终性延迟和退款可归因性放在同一个状态机里处理。
多池价格冲击模型
以 Uniswap V2 常数乘积池为例,忽略费用时有:
```text x * y = k p = y / x dp / dx = -y / x^2 - k / x^2 adjusted by reserve path ```
实际实现会加入手续费、输入输出方向和整数取整。重点不是公式细节,而是局部价格对交易量的导数。Uniswap V3 又把流动性集中到 tick 区间,局部价格冲击取决于当前 tick 附近的有效流动性 `L`,而不是全池名义 TVL。Curve 的稳定交换在锚定区间内提供更低滑点,但当池子偏离平衡或放大系数失效时,价格曲线会变得更陡。也就是说,“池子很大”不是充分安全条件,必须看目标价格区间里的实际深度。
把多个池子放在一起,价格状态可以写成向量:
```text P = (p_amm1, p_amm2, p_curve, p_lending_oracle, p_perp_index) Q = (q_1, q_2, ..., q_n) J = dP / dQ ```
`Q` 是在不同池子和协议中的交易或状态变更向量,`J` 是价格敏感度矩阵。单池防御只看某个 `dp/dq`;多池防御要看 `J` 的方向性。如果一个小交易向量能让多个价格分量同向偏移,清算条件就可能被放大。若偏移方向刚好影响抵押品价格下跌、债务资产价格上涨、保证金指数上升,健康因子会出现非线性恶化。
清算条件可以抽象为:
```text H = collateral_value(P) * liquidation_threshold - debt_value(P) liquidatable if H is not positive ```
防御者关心的是 `dH / dQ`。如果某组交易让 `H` 在一个区块内从正值变成非正值,但在几个区块后自然恢复,就说明协议暴露在瞬时价格风险下。真正的风险不只是“被清算”,而是“用不可逆清算结算了一个短时错误价格”。
TWAP 与预言机缓存的滞后风险
TWAP 被广泛用于降低单区块价格操纵风险。Uniswap V2 的累计价格 oracle 要求观察者比较两个时间点的累积价格;Uniswap V3 提供观察窗口和 tick 累积机制。它们的共同思路是把瞬时价格变成时间平均值。但 TWAP 不是魔法,它只是在操纵成本、响应速度和滞后之间做取舍。
窗口越长,单区块操纵成本越高,但协议对真实市场变化反应越慢。窗口越短,反应更快,但对短时冲击更敏感。如果借贷协议、衍生品协议和路由器使用不同窗口,风险会出现在窗口错配处。一个协议认为价格已经恢复,另一个协议仍在读取滞后的高价或低价;一个清算模块用较短窗口触发,抵押评估却用较长窗口确认,状态机会出现语义分裂。
预言机缓存也有类似问题。Chainlink 文档强调数据源选择、市场覆盖、流动性和更新条件;Aave、Maker 等借贷协议则在预言机模块和清算逻辑之间建立自己的安全边界。若消费端只检查“价格是否存在”,却不检查更新时间、偏离阈值、数据源深度和备用路径,就会把 stale price 当作有效状态。闪电贷不会破解预言机签名,但可能利用协议读取价格的时序和缓存策略。
一个防御性价格读取函数不应只返回 `price`,而应返回:
```text price, timestamp, source_set, deviation, liquidity_depth, confidence_state ```
`confidence_state` 可以是 `normal`、`stale`、`thinLiquidity`、`deviated`、`circuitBreaker`。清算、跨链报价和退款估值不应把这些状态抹平为一个数字。价格是输入,价格质量才是风控变量。
多维清算线与风险值约束
单资产清算模型通常看起来很简单:抵押价值下降或债务价值上升,健康因子跌破阈值。但多池联合风险里,抵押品、债务资产、LP token、合成资产和跨链 wrapped asset 可能共享流动性来源或预言机路径。此时风险不再是一条线,而是一个多维曲面:
```text H(P_1, P_2, ..., P_m, t, chain_state) ```
`t` 表示时间窗口,`chain_state` 表示最终性、桥状态和执行延迟。防御方可以对健康因子做一阶近似:
```text Delta H approximately equals gradient(H) dot Delta P ```
若某个价格扰动向量 `Delta P` 在短窗口内让 `Delta H` 接近清算边界,就应触发保护,而不是等待真实清算发生。这里的风险值不是传统金融里直接搬来的 VaR,而是协议级滑点风险值:在当前流动性深度、预言机置信状态和跨链延迟下,某个订单或某组仓位最多能承受多大价格偏移。
防御可以分三层。第一层是交易前限额:当目标路径的 `slippage VaR` 超过阈值时,降低单笔额度或拆单。第二层是清算前延迟:当清算由异常价格状态触发时,要求二次确认、备用 oracle 或延迟窗口。第三层是跨协议熔断:当多个相关资产同时出现异常偏移时,暂停新开仓或大额跨链释放,但保留退款和退出路径。
这类设计有代价。延迟清算可能增加坏账;限制交易可能降低资本效率;多源预言机可能引入治理和运维复杂度。工程判断不能只写“加 TWAP”或“用更安全预言机”,而要明确代价由谁承担,以及异常状态下用户资金如何退出。
预言机消费端的不变量
很多事故并不是预言机本身“报错”,而是消费端把价格当成无上下文数字。一个稳健的消费端至少应维护四类不变量。第一,价格时间不变量:用于清算、报价和退款的价格必须在允许的 freshness 窗口内,且窗口要小于业务动作的不可逆结算窗口。第二,来源一致性不变量:若主源、备用源和 AMM 派生价格出现超过阈值的偏离,协议进入降级状态,而不是选择其中一个继续执行。
第三,深度不变量:价格引用的市场深度必须覆盖当前交易或仓位规模。一个 oracle 可以给出正确的中位数价格,但如果执行路径只能在薄流动性区间成交,该价格对路由没有执行意义。第四,方向性不变量:抵押资产价格下跌和债务资产价格上涨同时发生时,清算风险应被放大处理,因为这通常意味着风险向量正在沿着健康因子最敏感的方向移动。
这些不变量应在链上和链下同时存在。链下路由器负责更复杂的相关性计算和路径选择;链上合约负责最小安全约束,例如更新时间、最大偏离、最大单笔额度和熔断状态。若所有判断都放在链下,用户无法验证风控是否真的生效;若所有判断都放在链上,Gas 和数据可得性会限制模型复杂度。合理边界是:链下计算风险评分,链上强制执行不可绕过的硬阈值。
跨链执行前的价格质量闸门
跨链交换比单链 swap 多一个失败面:报价和执行不在同一个原子上下文里。源链锁定或支付完成后,目标链可能经历桥确认、排队、重组等待和路由再平衡。若目标链执行前不重新检查价格质量,系统就可能用旧报价穿过新的风险状态。这个问题和传统滑点保护不同;滑点保护只检查成交价格,价格质量闸门还要检查该价格是否来自健康市场。
执行前闸门可以按顺序检查五项:目标池有效深度是否仍覆盖订单;短 TWAP 和长 TWAP 是否分叉;外部预言机是否过期;相关资产是否同时异常偏移;桥或目标链是否处于延迟状态。任一项失败时,动作不应直接变成失败交易,而应进入受控分支:重新报价、降低额度、等待下一窗口,或触发退款。这样能避免用户资金被卡在“价格不可信但系统仍尝试执行”的灰区。
退款定价同样需要闸门。若订单因为价格异常未执行,退款不应依赖异常时刻的单点价格。更稳健的做法是记录原始报价上下文、源链支付资产、目标链预期资产、失效原因和可验证时间戳,再根据产品规则选择原路退款、稳定资产退款或等待恢复。关键是把价格异常和用户意图分开,不让短时市场扭曲改变用户本来的资产归属。
检测信号与防御状态机
多池联合风险的检测信号可以分为链上、价格和执行三类。链上信号包括同一区块内多个相关池的方向性交易、短窗口内异常大的 reserve 变化、LP 份额快速进出和借贷仓位健康因子集中贴近阈值。价格信号包括 AMM 价格与外部数据源偏离、短 TWAP 与长 TWAP 分叉、低深度区间价格弹性突增。执行信号包括清算交易密集失败、跨链路线频繁重新报价、目标链执行前后的价格状态不一致。
一个防御状态机可以写成:
```text normal -> elevatedRisk -> guardedExecution -> circuitBreaker -> recovery ```
`normal` 状态正常报价。`elevatedRisk` 降低单笔额度并延长报价有效性检查。`guardedExecution` 要求备用价格源、二次 TWAP 或更高滑点缓冲。`circuitBreaker` 暂停新风险敞口,但保留退款、撤单和低风险退出。`recovery` 则要求价格偏离、流动性深度和预言机更新时间恢复到阈值内,不能只靠管理员手动解除。
跨协议联动熔断的难点是误报。市场真实波动时,过度保守的熔断会伤害用户;攻击窗口中,过度宽松又会把错误价格写入清算和结算。更稳健的做法是分层响应:先限额,再延迟,再切换路径,最后才全局暂停。每一级都应该有可观测条件和自动恢复条件。 恢复条件还必须写入日志,方便事后审计。
AllSwap 相关性:报价、执行和退款要分开看
AllSwap 的核心场景是跨链交换与路由聚合。多池价格风险会影响三件事:报价是否可信、目标链执行是否仍在安全滑点内、失败后退款是否能按可解释价格归因。一个跨链路由如果只在源链报价时读取价格,而不在目标链执行前重新验证价格质量,就可能把短时被扭曲的价格传递给用户。
路由层可以把价格状态拆成几个阶段:`quoteObserved`、`liquidityReserved`、`oracleChecked`、`targetExecutionReady`、`releaseConfirmed`、`refundPriced`。每个阶段都应该记录价格源、更新时间、滑点 VaR、路径深度和链最终性状态。若某个阶段进入 `deviated` 或 `stale`,系统不应继续用同一报价假装确定执行,而应切换到重新报价、限额执行或退款路径。
这也解释了为什么“最低手续费路线”不是唯一目标。低费路线如果穿过薄流动性池、短 TWAP、刚发生大额 LP 迁移的池子,或者依赖目标链滞后 oracle,它的真实风险成本可能高于报价显示。AllSwap 可以把这类风险体现在路径评分中:不需要对用户展示复杂矩阵,但需要把可执行性、退款确定性和价格质量纳入路由选择。
对无托管产品尤其重要的是失败归因。若目标链价格异常导致执行暂停,用户需要知道资金在哪条链、哪个状态、是否可退款、退款按哪个价格口径计算。风控系统的目标不是永远执行成功,而是在不可信价格出现时仍能保持资产状态可验证、可退出、可解释。
未解决问题
第一,多协议价格相关性缺少统一数据结构。每个协议都能描述自己的 oracle 和池子,但很少有标准方式表达“这些价格源在风险上相关”。
第二,TWAP 窗口选择仍然是工程和经济学折中。窗口太短防不住瞬时操纵,窗口太长会错过真实市场变化,跨链场景还要叠加最终性延迟。
第三,链上实时 VaR 计算成本较高。完整计算多池雅可比矩阵和仓位风险曲面会消耗 Gas,实际系统需要近似、缓存和分层阈值。
第四,熔断治理容易被滥用。自动熔断能降低攻击面,但如果恢复条件不透明,也可能成为审查、延迟或选择性执行的工具。
第五,用户界面仍难表达“价格质量”。展示一个价格很容易,展示该价格的深度、时效、偏离和退款含义要困难得多。
参考资料
[1] Uniswap V2 Whitepaper, Hayden Adams et al., 2020, https://app.uniswap.org/whitepaper.pdf
[2] Uniswap V3 Whitepaper, Hayden Adams et al., 2021, https://uniswap.org/whitepaper-v3.pdf
[3] Uniswap V2 Oracles Documentation, Uniswap, https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles
[4] Uniswap V3 Oracle Library Documentation, Uniswap, https://docs.uniswap.org/contracts/v3/reference/core/libraries/Oracle
[5] Curve StableSwap NG Oracle Documentation, Curve Finance, https://docs.curve.finance/stableswap-exchange/stableswap-ng/pools/oracles/
[6] Aave Price Oracle Documentation, Aave, https://aave.com/docs/developers/smart-contracts/oracles
[7] Chainlink Data Feed Selection Documentation, Chainlink, https://docs.chain.link/data-feeds/selecting-data-feeds
[8] Flash Boys 2.0: Frontrunning in Decentralized Exchanges, Daian et al., 2019, https://arxiv.org/abs/1904.05234
[9] Flashot: A Snapshot of Flash Loan Attack on DeFi Ecosystem, Qin et al., 2021, https://arxiv.org/abs/2102.00626
[10] SoK: Decentralized Finance Security and Privacy, 2022, https://arxiv.org/abs/2208.13035
[11] MakerDAO Oracle Module Documentation, MakerDAO, https://docs.makerdao.com/smart-contract-modules/oracle-module
常见问题
多池联合夹击和普通三明治攻击有什么区别?
普通三明治主要影响单个用户在一个池子里的成交价格;多池联合夹击关注多个 AMM、预言机和借贷协议之间的价格传播,可能让短时错误价格触发清算或跨链执行风险。
TWAP 能完全防止闪电贷价格操纵吗?
不能。TWAP 提高了短时操纵成本,但会引入滞后。窗口太短仍可能受冲击,窗口太长会对真实市场变化反应迟缓。消费端还必须检查更新时间、偏离和流动性深度。
什么是滑点 VaR?
这里的滑点 VaR 指在当前流动性、预言机状态和跨链延迟下,某条路线或仓位能承受的最大价格偏移。它不是传统金融 VaR 的直接复制,而是协议级风控近似。
AllSwap 为什么要关注多池价格风险?
跨链交换的报价、目标链执行和退款可能发生在不同时间窗口。若路线依赖薄流动性、滞后 oracle 或异常 TWAP,低费路径也可能带来更高执行失败和退款不确定性。
参考资料
- Uniswap V2 Whitepaper
- Uniswap V3 Whitepaper
- Uniswap V2 Oracles Documentation
- Uniswap V3 Oracle Library Documentation
- Curve StableSwap NG Oracle Documentation
- Aave Price Oracle Documentation
- Chainlink Data Feed Selection Documentation
- Flash Boys 2.0
- Flashot: Flash Loan Attack on DeFi Ecosystem
- SoK: Decentralized Finance Security and Privacy
- MakerDAO Oracle Module Documentation


