> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# 调试失败的交易

> 了解如何使用 Blocksec Explorer 和 Tenderly 诊断并修复已回滚的链上交易

了解如何使用追踪分析工具调试已回滚的交易。本指南基于真实生产案例，涵盖常见的失败模式及其修复方法。

## 前置条件

在开始之前，你需要：

* 失败交易的**交易哈希**
* 访问一款追踪分析工具

<CardGroup cols={2}>
  <Card title="Blocksec Explorer" icon="magnifying-glass" href="https://app.blocksec.com/explorer">
    查看详细的调用追踪并分析交易
  </Card>

  <Card title="Tenderly Debugger" icon="bug" href="https://tenderly.co/">
    逐步模拟并调试交易
  </Card>
</CardGroup>

***

## 核心调试工作流

按照以下步骤诊断大多数交易失败。

<Steps>
  <Step title="定位回滚位置">
    在 Blocksec 或 Tenderly 中打开交易并识别：

    * **顶层回滚原因**（如果可用）
    * 调用树中的**首次回滚**（这通常是真正的根本原因）
    * **回滚之前的合约或调用**（这是失败的操作）

    <Tip>
      追踪工具有时会显示多个错误。当 UI 摘要与原始追踪冲突时，请以原始追踪为准。
    </Tip>
  </Step>

  <Step title="对失败进行分类">
    大多数回滚可归入以下类别：

    | 类别           | 常见指示                                                     |
    | ------------ | -------------------------------------------------------- |
    | Gas 耗尽       | 追踪突然中断、OOG 错误                                            |
    | 授权额度不足       | `transfer amount exceeds allowance`                      |
    | 余额不足         | `insufficient balance`、`transfer amount exceeds balance` |
    | 缺少 msg.value | 原生代币上出现 `insufficient balance for transfer`              |
    | 超出滑点         | 最小输出检查失败                                                 |
    | 预言机问题        | `StalePrice`、错误的数据源                                      |
    | 截止时间过期       | `EXPIRED`、`Transaction too old`                          |
    | 代币限制         | 转账被阻止、税费、黑名单                                             |

    一旦确定了类别，修复方法就变得清晰了。
  </Step>

  <Step title="对比预期输入与实际输入">
    聚合器和路由器的失败通常源于输入不匹配：

    * 链上的 `gasLimit` 与来自 `/quote` 或 `/stepTransaction` 的 `gasLimit`
    * 授权数量与实际花费数量
    * 发送的 `msg.value` 与所需的 `msg.value`
    * `minAmountOut` 与执行时的实际输出
    * 代币地址或价格数据源 ID 错误
  </Step>

  <Step title="复现并测试">
    使用完全相同的 calldata 和状态模拟失败的调用。然后一次只更改一个变量：

    * 提高 `gasLimit`
    * 添加或调整 `msg.value`
    * 放宽滑点参数

    <Note>
      如果更改某个变量使模拟成功，那么你就找到了根本原因。
    </Note>
  </Step>
</Steps>

***

## 常见失败模式

<AccordionGroup>
  <Accordion title="A) Gas 耗尽" icon="gas-pump">
    ### 症状

    追踪突然中断，或显示 gas 耗尽（OOG）错误。

    ### 如何确认

    1. 检查交易的 `gasLimit`
    2. 在回滚原因中查找 OOG
    3. 使用更高的 `gasLimit` 重新模拟（使用报价 API 中的值）

    ### 根本原因

    交易使用的 `gasLimit` 低于报价推荐值。钱包或中继器有时会覆盖 gas 设置。

    ### 修复

    * 使用报价响应中的**确切 `gasLimit`**
    * 如果你的产品允许，可添加 10–20% 的安全缓冲
    * 确认钱包和中继器不会限制 gas 值

    ### 示例

    API 返回了充足的 `gasLimit`，但链上交易回滚了。使用正确的 `gasLimit` 重新模拟即成功。

    * [失败的交易](https://app.blocksec.com/explorer/tx/base/0xdb8adb7526ab1372f3e252ddc128c3e039bd29bb91567f5f3821b7c665b16dd9?line=302)
    * [成功的模拟](https://app.blocksec.com/explorer/tx/base/0x9c0d91d0f2de0250b75f59276b879b5309f3f4d6eaa688b943fd11c39c418f45?event=simulation\&timestamp=1767602633035\&type=0)
  </Accordion>

  <Accordion title="B) 授权额度不足" icon="ban">
    ### 症状

    回滚消息：`transfer amount exceeds allowance`

    ### 如何确认

    1. 在追踪中找到 `transferFrom(...)` 调用
    2. 确定是哪个 spender 在拉取资金
    3. 检查执行区块处的 `allowance(owner, spender)`

    ### 根本原因

    用户要么没有授权，要么授权给了错误的 spender，要么授权额度少于所需数量。之前的某笔交易可能已经消耗了授权额度。

    ### 修复

    * 提示用户对正确的代币和 spender 进行授权
    * 权衡无限授权与精确授权之间的取舍

    ### 示例

    [交易因授权额度不足而回滚](https://app.blocksec.com/explorer/tx/base/0xa24e8a320ed5c7e9b5daa5d6c5e0616b0b4789cc6e68b2872b24970d0aca733c?line=11)
  </Accordion>

  <Accordion title="C) 缺少 msg.value" icon="coins">
    ### 症状

    诸如以下错误：

    * `insufficient balance for transfer`
    * 原生价值转发失败

    ### 如何确认

    1. 在 Tenderly 中检查交易的 `msg.value`
    2. 在追踪中找到路由器转发 ETH 的位置
    3. 在该处查找余额失败

    ### 根本原因

    路由需要原生代币（用于费用、桥接 gas 或协议支付），但交易发送了 `value=0`。

    ### 修复

    * 包含 API 返回的 `msg.value`
    * 确认中继器和钱包不会丢弃 value 字段

    ### 示例

    尽管 API 返回了非零值，但交易因缺少 `msg.value` 而失败。

    [在 Tenderly 中查看](https://dashboard.tenderly.co/shared/simulation/b444cc7e-5deb-4ac6-a3f4-fdeb8fe7eded/debugger?trace=0.1.2)
  </Accordion>

  <Accordion title="D) 预言机价格过时" icon="clock-rotate-left">
    ### 症状

    回滚消息：`PythErrors.StalePrice()`

    ### 如何确认

    在追踪中查找 `getPriceNoOlderThan(..., age=N)` 回滚。

    ### 根本原因

    预言机数据过旧，或资金池使用了未被更新的错误数据源 ID。

    ### 修复

    联系 [LI.FI 支持](https://lifihelp.zendesk.com/hc/en-us) 报告问题。

    ### 示例

    由于资金池使用了错误的数据源 ID，出现了 `PythErrors.StalePrice()`。

    [在 Tenderly 中查看](https://dashboard.tenderly.co/shared/simulation/05f5aaf2-3946-42ed-b9f6-45fd40b78e2d/debugger?trace=0.4.3.0.2.0.0.1.6.7.1.5.0.1.1.2.2.0.1.0.2)
  </Accordion>

  <Accordion title="E) 代币余额不足" icon="wallet">
    ### 症状

    回滚消息：`insufficient balance` 或 `transfer amount exceeds balance`

    ### 如何确认

    1. 在追踪中找到代币转账
    2. 确定 "from" 地址
    3. 检查执行时的 `balanceOf(from)`

    ### 根本原因

    用户的余额在报价与执行之间发生了变化。转账收费（fee-on-transfer）或变基（rebasing）代币可能导致意料之外的余额变化。

    ### 修复

    * 在发送前立即重新报价并核实余额
    * 对于转账收费代币，联系 LI.FI 支持将该代币加入拒绝列表

    ### 示例

    [交易因余额不足而回滚](https://app.blocksec.com/phalcon/explorer/tx/eth/0xefb4dc79dc72b1df1d13edd2a4727594b1a1a8aff3c5ca6792a0ce1068f87d88?line=6)
  </Accordion>

  <Accordion title="F) 超出滑点" icon="chart-line-down">
    ### 症状

    与最小输出或滑点检查相关的回滚（确切消息因 DEX 而异）。

    ### 如何确认

    找到交换步骤并比较：

    * `amountOutMin` 或 `minReturnAmount`
    * 实际计算出的 `amountOut`

    如果 `amountOut < minReturnAmount`，交易会回滚。

    ### 根本原因

    价格波动、MEV 提取、波动性资金池、低流动性或过时的报价。

    ### 修复

    * 重新报价并在报价后 60–90 秒内执行（最常见原因是报价过时）
    * 如果新报价仍然失败，**仅出于诊断目的**提高滑点容忍度（对波动性或新代币为 15–25%）
    * 对于无法避免的高滑点，使用私有或受 MEV 保护的 RPC 端点

    <Warning>
      不要将高滑点值用作生产环境默认值。这会为[三明治攻击](https://ethereum.org/en/developers/docs/mev/#mev-examples-sandwich-trading)制造较大的窗口，MEV 机器人可借此从用户处提取价值。仅在一次性调试时使用这些值。
    </Warning>

    ### 示例

    * [滑点失败（Tenderly）](https://www.tdly.co/tx/0xd695011e11cdf38e92edf5c872a1bab4f011e90a493b5696e2a0092460268ccc)
    * [滑点失败（Blocksec）](https://app.blocksec.com/phalcon/explorer/tx/eth/0x9b613a583daa4a6a46e4bacbe13bb571d4a7e897a5b0b0ca44b3260856fc2ef4?line=2)
  </Accordion>

  <Accordion title="G) 代币转账限制" icon="triangle-exclamation">
    ### 症状

    最终交换步骤失败，报 `SafeERC20: low-level call failed`。

    ### 如何确认

    在追踪中查找：

    1. 一个回滚的 `transferFrom` 调用
    2. 一个失败的嵌套外部调用（通常调向税费钱包或费用处理器）
    3. 错误以 `SafeERC20: low-level call failed` 形式向上冒泡

    ### 根本原因

    某些代币具有自定义转账逻辑，在特定条件下会失败。例如，带有卖出税的代币可能会调用拒绝 ETH 或意外回滚的外部合约。

    ### 修复

    * 将该代币视为不兼容卖出路由
    * 向 [LI.FI 支持](https://lifihelp.zendesk.com/hc/en-us) 报告，以加入代币拒绝列表

    <Tip>
      使用 [honeypot.is](https://honeypot.is) 或 [GoPlus](https://gopluslabs.io/) 等代币风险扫描工具，检查蜜罐标记、卖出限制或异常税费。
    </Tip>

    ### 示例

    路由器因代币的税费钱包拒绝 ETH 而未能转移代币。

    [在 Blocksec 中查看](https://app.blocksec.com/phalcon/explorer/tx/eth/0xca85cc530034c4fec9b0ee6831607a947fa8032e7919881d5fd3101c1bd5cd92?line=75)
  </Accordion>

  <Accordion title="H) 资金池损坏（数学失败）" icon="infinity">
    ### 症状

    资金池数学计算内部回滚，例如 Curve 的 `get_D` 在 255 次迭代后仍未收敛。

    ### 如何确认

    追踪显示资金池数学函数（`get_D`、不变量计算）中带有 `raise` 语句的回滚。

    ### 根本原因

    资金池已损坏，通常是由于某个被攻陷的代币导致极端失衡或无效状态。

    ### 修复

    联系 [LI.FI 支持](https://lifihelp.zendesk.com/hc/en-us) 将该资金池列入黑名单。

    ### 示例

    某 Curve 资金池的 `get_D` 函数未能收敛。Curve 团队确认该资金池已损坏。

    [在 Tenderly 中查看](https://dashboard.tenderly.co/tx/0x18505dfe414ab0e347d4d174217737c41d5b84db3bd6a6af3af6f0cff37b3367?trace=0.1.1.9.2.0.5.0.9.1.0)
  </Accordion>

  <Accordion title="I) 重入锁（UniswapV2 LOCKED）" icon="lock">
    ### 症状

    回滚消息：`UniswapV2: LOCKED`

    ### 如何确认

    在追踪中：

    1. Uniswap V2 交易对转移某个代币
    2. 该代币的转账逻辑回调进同一个交易对
    3. 交易对的重入锁被触发

    ### 根本原因

    带有回调或费用交换逻辑的代币在转账期间重新进入交易对。这通常发生在配置错误的转账收费代币上。

    ### 修复

    联系 [LI.FI 支持](https://lifihelp.zendesk.com/hc/en-us) 将该资金池列入黑名单。

    ### 示例

    涉及 WeightedIndex 的交换回滚并报 `UniswapV2: LOCKED`。KyberSwap 将受影响的资金池列入了黑名单。

    [在 Tenderly 中查看](https://dashboard.tenderly.co/shared/simulation/c5b100d0-067d-483a-9184-0880f709a382/debugger?trace=0.4.2.0.2.2.0.1.6.7.1.5.3.5.0.0.0.1.2.1.7.3.3.6.1)
  </Accordion>

  <Accordion title="J) 转账收费代币失败" icon="percent">
    ### 症状

    尽管用户最初拥有足够的代币，但路由中途因余额不足而回滚。

    ### 如何确认

    追踪显示：

    1. 较早的一跳收到的代币少于预期
    2. 较晚的一跳试图转移最初计算的数量
    3. 余额检查失败

    ### 根本原因

    转账收费（FoT）或通缩型代币在转账期间收取费用。路由假定为精确数量，但实际收到的数量少于计算值。

    ### 修复

    联系 [LI.FI 支持](https://lifihelp.zendesk.com/hc/en-us) 将该代币加入拒绝列表。

    ### 示例

    fBOMB 因其通缩机制打乱了路由的精确计算，报 `Max20: insufficient balance` 而失败。

    * [在 Tenderly 中查看](https://dashboard.tenderly.co/shared/simulation/0cb72ac2-1565-4d10-9919-11b584f07f4f?trace=0.4.2.0.5.1.0.1.2)
    * [查看代币代码](https://berascan.com/address/0xfab311fe3e3be4bb3fed77257ee294fb22fa888b#code#F1#L133)
  </Accordion>

  <Accordion title="K) DEX 重入保护" icon="shield-halved">
    ### 症状

    由资金池层面的重入锁引起的回滚，尤其是转账收费代币。

    ### 如何确认

    追踪显示资金池处出现回滚，带有重入防护行为，类似于 "LOCKED" 但因协议而异。

    ### 根本原因

    较新的 DEX 增加了重入保护，与转账收费或回调型代币相冲突。

    ### 修复

    联系 [LI.FI 支持](https://lifihelp.zendesk.com/hc/en-us) 将该资金池列入黑名单。

    ### 示例

    Kodiak v2 资金池增加了重入锁，导致转账收费代币回滚。

    [在 Tenderly 中查看](https://dashboard.tenderly.co/shared/simulation/8671ce2c-c34e-436d-8496-3bce168dea08?trace=0.4.2.0.2.8.0.1.6.7.1.7.3.5.0.0.1.2.1.7.3.3.6.1)
  </Accordion>

  <Accordion title="L) 截止时间过期" icon="hourglass-end">
    ### 症状

    诸如以下回滚消息：

    * `Transaction too old`
    * `EXPIRED`
    * `SwapRouter: EXPIRED`

    ### 如何确认

    1. 在 calldata 中找到编码后的截止时间（通常为一个 32 字节的字）
    2. 将十六进制值转换为 Unix 时间
    3. 与交易被打包时的区块时间戳进行比较

    如果 `block_timestamp > deadline`，路由器会拒绝该交易。

    **示例计算：**

    * 截止时间：`0x6951e2e0` = 1,766,974,176
    * 区块时间戳：1,766,975,579
    * 差值：1,403 秒（迟了约 23 分钟）

    [查看 VM 追踪](https://etherscan.io/vmtrace?txhash=0x15735cdc5b7576ff6059a7337c8d48767a56210ac88cce26f6a8d470d2c791b1\&type=gethtrace2)

    ### 根本原因

    由于签名缓慢、内存池拥堵、gas 价格过低或中继器延迟，交易提交得太晚。

    ### 修复

    * 获取新的报价并立即提交
    * 为卡住的交易提高 gas 价格
    * 不要重用旧的 calldata

    <Warning>
      执行过晚通常意味着市场已经变动。即使没有明确的截止时间回滚，过时的报价也常因滑点而失败。请始终重新报价。
    </Warning>
  </Accordion>
</AccordionGroup>

***

## 快速决策清单

调试失败交易时，请遵循以下步骤：

<Steps>
  <Step title="找到首次回滚">
    查看调用树，而不仅仅是 UI 标题。首次回滚通常就是根本原因。
  </Step>

  <Step title="确定类别">
    | 检查        | 操作                             |
    | --------- | ------------------------------ |
    | Gas 耗尽？   | 比较提交的与推荐的 `gasLimit`           |
    | 授权额度？     | 检查 `allowance(owner, spender)` |
    | 余额？       | 检查执行区块处的 `balanceOf`           |
    | 缺少 value？ | 比较交易 value 与所需 value           |
    | 滑点？       | 比较 `minOut` 与实际输出              |
    | 预言机？      | 查找过时价格或错误的数据源 ID               |
    | 代币问题？     | 检查转账回滚或错误返回值                   |
  </Step>

  <Step title="模拟交易">
    使用 Tenderly 或 Blocksec，以完全相同的参数复现失败。
  </Step>

  <Step title="测试单项更改">
    一次只修改一个变量（gas、value、授权、滑点），直到模拟成功。
  </Step>
</Steps>

***

## 快速参考

| 失败       | 关键指示                                | 修复                    |
| -------- | ----------------------------------- | --------------------- |
| Gas 耗尽   | 追踪突然中断、OOG 错误                       | 使用报价中的 `gasLimit`     |
| 授权额度     | `transfer amount exceeds allowance` | 授权正确的 spender         |
| 余额       | `insufficient balance`              | 重新报价并核实余额             |
| 缺少 value | 原生转账失败                              | 包含 API 中的 `msg.value` |
| 滑点       | 最小输出检查失败                            | 先重新报价，再谨慎提高滑点         |
| 预言机过时    | `StalePrice` 错误                     | 报告给 LI.FI 支持          |
| 代币限制     | `SafeERC20: low-level call failed`  | 报告代币以加入拒绝列表           |
| 资金池损坏    | 数学收敛失败                              | 报告资金池以列入黑名单           |
| 重入       | `LOCKED` 错误                         | 报告资金池以列入黑名单           |
| 截止时间过期   | `EXPIRED`                           | 重新报价并快速执行             |

***

## 相关资源

<CardGroup cols={2}>
  <Card title="错误码" icon="circle-exclamation" href="/api-reference/error-codes">
    API 错误码参考
  </Card>

  <Card title="常见问题 FAQ" icon="circle-question" href="/faqs/troubleshooting">
    常见的故障排除问题
  </Card>

  <Card title="状态追踪" icon="clock" href="/introduction/user-flows-and-examples/status-tracking">
    追踪交易状态
  </Card>

  <Card title="滑点与价格影响" icon="chart-mixed" href="/faqs/slippage-price-impact">
    了解滑点设置
  </Card>
</CardGroup>
