前置条件
在开始之前,你需要:- 失败交易的交易哈希
- 访问一款追踪分析工具
Blocksec Explorer
查看详细的调用追踪并分析交易
Tenderly Debugger
逐步模拟并调试交易
核心调试工作流
按照以下步骤诊断大多数交易失败。1
定位回滚位置
在 Blocksec 或 Tenderly 中打开交易并识别:
- 顶层回滚原因(如果可用)
- 调用树中的首次回滚(这通常是真正的根本原因)
- 回滚之前的合约或调用(这是失败的操作)
2
对失败进行分类
大多数回滚可归入以下类别:
一旦确定了类别,修复方法就变得清晰了。
3
对比预期输入与实际输入
聚合器和路由器的失败通常源于输入不匹配:
- 链上的
gasLimit与来自/quote或/stepTransaction的gasLimit - 授权数量与实际花费数量
- 发送的
msg.value与所需的msg.value minAmountOut与执行时的实际输出- 代币地址或价格数据源 ID 错误
4
复现并测试
使用完全相同的 calldata 和状态模拟失败的调用。然后一次只更改一个变量:
- 提高
gasLimit - 添加或调整
msg.value - 放宽滑点参数
如果更改某个变量使模拟成功,那么你就找到了根本原因。
常见失败模式
A) Gas 耗尽
A) Gas 耗尽
B) 授权额度不足
B) 授权额度不足
C) 缺少 msg.value
C) 缺少 msg.value
D) 预言机价格过时
D) 预言机价格过时
E) 代币余额不足
E) 代币余额不足
症状
回滚消息:insufficient balance 或 transfer amount exceeds balance如何确认
- 在追踪中找到代币转账
- 确定 “from” 地址
- 检查执行时的
balanceOf(from)
根本原因
用户的余额在报价与执行之间发生了变化。转账收费(fee-on-transfer)或变基(rebasing)代币可能导致意料之外的余额变化。修复
- 在发送前立即重新报价并核实余额
- 对于转账收费代币,请比较当前税率行为与报价金额。如果新路由仍然失败,请联系 LI.FI 支持;动态、按池变化或未检测到的税可能需要将受影响的代币或资金池加入拒绝列表。
示例
交易因余额不足而回滚F) 超出滑点
F) 超出滑点
症状
与最小输出或滑点检查相关的回滚(确切消息因 DEX 而异)。如何确认
找到交换步骤并比较:amountOutMin或minReturnAmount- 实际计算出的
amountOut
amountOut < minReturnAmount,交易会回滚。根本原因
价格波动、MEV 提取、波动性资金池、低流动性或过时的报价。修复
- 重新报价并在报价后 60–90 秒内执行(最常见原因是报价过时)
- 如果新报价仍然失败,仅出于诊断目的提高滑点容忍度(对波动性或新代币为 15–25%)
- 对于无法避免的高滑点,使用私有或受 MEV 保护的 RPC 端点
示例
G) 代币转账限制
G) 代币转账限制
症状
最终交换步骤失败,报SafeERC20: low-level call failed。如何确认
在追踪中查找:- 一个回滚的
transferFrom调用 - 一个失败的嵌套外部调用(通常调向税费钱包或费用处理器)
- 错误以
SafeERC20: low-level call failed形式向上冒泡
根本原因
某些代币具有自定义转账逻辑,在特定条件下会失败。例如,带有卖出税的代币可能会调用拒绝 ETH 或意外回滚的外部合约。修复
- 将该代币视为不兼容卖出路由
- 向 LI.FI 支持 报告,以加入代币拒绝列表
示例
路由器因代币的税费钱包拒绝 ETH 而未能转移代币。在 Blocksec 中查看H) 资金池损坏(数学失败)
H) 资金池损坏(数学失败)
I) 重入锁(UniswapV2 LOCKED)
I) 重入锁(UniswapV2 LOCKED)
J) 转账收费代币失败
J) 转账收费代币失败
症状
尽管用户最初拥有足够的代币,但路由中途因余额不足而回滚。如何确认
追踪显示:- 较早的一跳收到的代币少于预期
- 较晚的一跳试图转移最初计算的数量
- 余额检查失败
根本原因
转账收费(FoT)或通缩型代币会在转账期间收取费用。当实际税率与报价调整不一致、随资金池变化或未被检测到时,后续步骤收到的数量可能少于计算值,从而导致失败。修复
请先重新报价,并比较当前税率行为与返回金额。如果新路由仍然失败,请联系 LI.FI 支持;受影响的代币或资金池可能需要加入拒绝列表。示例
fBOMB 因其通缩机制打乱了路由的精确计算,报Max20: insufficient balance 而失败。K) DEX 重入保护
K) DEX 重入保护
L) 截止时间过期
L) 截止时间过期
症状
诸如以下回滚消息:Transaction too oldEXPIREDSwapRouter: EXPIRED
如何确认
- 在 calldata 中找到编码后的截止时间(通常为一个 32 字节的字)
- 将十六进制值转换为 Unix 时间
- 与交易被打包时的区块时间戳进行比较
block_timestamp > deadline,路由器会拒绝该交易。示例计算:- 截止时间:
0x6951e2e0= 1,766,974,176 - 区块时间戳:1,766,975,579
- 差值:1,403 秒(迟了约 23 分钟)
根本原因
由于签名缓慢、内存池拥堵、gas 价格过低或中继器延迟,交易提交得太晚。修复
- 获取新的报价并立即提交
- 为卡住的交易提高 gas 价格
- 不要重用旧的 calldata
快速决策清单
调试失败交易时,请遵循以下步骤:1
找到首次回滚
查看调用树,而不仅仅是 UI 标题。首次回滚通常就是根本原因。
2
确定类别
3
模拟交易
使用 Tenderly 或 Blocksec,以完全相同的参数复现失败。
4
测试单项更改
一次只修改一个变量(gas、value、授权、滑点),直到模拟成功。
快速参考
相关资源
错误码
API 错误码参考
常见问题 FAQ
常见的故障排除问题
状态追踪
追踪交易状态
滑点与价格影响
了解滑点设置

