You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Uniswap V3闪电贷还清后余额异常及F1错误求助

Uniswap V3闪电贷主网分叉测试异常求助与解答

问题描述

在主网分叉环境测试Uniswap V3闪电贷时触发F1异常,具体情况如下:

闪电贷回调代码

function uniswapV3FlashCallback(
    uint256 fee0,
    uint256 fee1,
    bytes calldata data
) external {
    require(msg.sender == address(pool), "not authorized");

    FlashCallbackData memory decoded = abi.decode(
        data,
        (FlashCallbackData)
    );

    console.log("Balance of token1 on contract(before paying off loan):"); 
    console.log(token1.balanceOf(address(this)));
    console.log("Balance of token1 on pool(before paying off loan):"); 
    console.log(token1.balanceOf(address(pool)));

    // Repay borrow
    if (fee0 > 0) {
        token0.transferFrom(decoded.caller, address(this), fee0);
        token0.transfer(address(pool), decoded.amount0 + fee0);
    }
    if (fee1 > 0) {

        //Paying off the loan (back to the pool) with fee
        token1.transfer(address(pool), decoded.amount1 + fee1);
        console.log("Balance of token1 on contract (after paying off loan):"); 
        console.log(token1.balanceOf(address(this))); 
        console.log("Balance of token1 on pool (after paying off loan):"); 
        console.log(token1.balanceOf(address(pool))); 
    }

    // console.log("Fee0:");
    // console.log(fee0);//0
    console.log("Fee1:");
    console.log(fee1);
}

异常触发场景

模拟USDC巨鲸向合约转入10 USDC(已通过单元测试验证),尝试借入5 USDC(0.3%手续费,预期1500)时触发错误:

Error: VM Exception while processing transaction: reverted with reason string 'F1'

官方文档中F1错误定义:

The balance of token1 in the given pool before the flash transaction must be less than, or equal to, the balance of token1 after the flash plus the fee

日志异常现象

UniswapV3Arb
    UniswapV3MultiHopSwap
USDC balance of whale:  170961318210457n
Impersonation Started.
Impersonation completed.
      ✔ ensures contract is funded
USDC balance of whale:  170961308210457n
Impersonation Started.
Impersonation completed.
Current balance of USDC on contract = 10000000 USDC (decimals 6)
//Funded 10 USDC on my flashloan contract
Balance of token1 on contract(before paying off loan):
10000000
//Still remains as 10 USDC (decimals 6)
Balance of token1 on pool(before paying off loan):
29432076632681 
Balance of token1 on contract (after paying off loan):
4985000 (This seems to be whats left after deducting 1,500 fee from borrowed 5 USDC. Where has my initial fund 10 USDC gone?)
Balance of token1 on pool (after paying off loan):
29432081647681 (Shouldn't it be larger? as The original value + 1,500. Thats why I received the Exception above?)
Fee1:
15000

核心疑问

  1. 还款后合约余额为4985000(借款额-手续费),而非预期的9998500(初始资金-手续费),初始10 USDC去向不明;
  2. USDC池子余额未按预期增加1500,导致触发F1异常。

问题分析与修复方案

1. 手续费数值理解错误

日志中Fee1为15000,而非你预期的1500——USDC是6位小数,5 USDC(5e6)的0.3%手续费计算为:5e6 * 0.003 = 15000(即0.015 USDC),你之前的小数换算逻辑错误,这是后续异常的基础诱因。

2. 闪电贷资金流向逻辑完全误解

Uniswap V3闪电贷的标准流程是:

  • 池子先将借款金额划转至你的合约,因此回调执行前,合约余额应为初始10 USDC + 借入5 USDC = 15 USDC;
  • 你需要归还池子的金额为借款额 + 手续费,即5e6 + 15000 = 5015000。

但日志显示回调前合约余额仍为10000000,说明池子根本没把借款金额转到你的合约。此时你调用token1.transfer(address(pool), decoded.amount1 + fee1),是直接从初始的10 USDC里扣除了5015000,导致:

  • 合约余额变为10e6 - 5015000 = 4985000(与日志一致);
  • 池子余额增加了5015000,而非预期的15000手续费,这直接违反了Uniswap的资金校验规则,触发F1错误。

3. 根本问题:闪电贷触发方式错误

你没有正确调用Uniswap V3 Pool的flash函数,或调用参数错误,导致池子未执行借款金额的划转操作。

修复步骤

  • 检查flash函数调用代码:确保amount1设置为5e6(5 USDC),recipient指定为你的合约,data参数正确传递;
  • 在uniswapV3FlashCallback开头增加日志,确认合约的token1余额是否包含借入的5 USDC(应为15e6);
  • 确保还款逻辑使用合约内的全部可用资金(初始资金+借入资金)归还amount1+fee1,而非仅用初始资金;
  • 修正手续费的小数换算逻辑,避免数值理解错误。

内容的提问来源于stack exchange,提问作者Aaron Li

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:44:58