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

使用ethers.js在Uniswap V3兑换时遇RPC执行回滚错误求助

问题:Uniswap V3 Router兑换无MetaMask弹窗且执行回滚(Polygon网络+ethers.js)

问题现象

  • USDC授权已在MetaMask确认成功,但兑换步骤无签名弹窗
  • 控制台报错:
    inpage.js:1 MetaMask - RPC Error: Internal JSON-RPC error. code: -32603 data: code: -32000 message: "execution reverted"
    

代码片段

const provider = new ethers.providers.Web3Provider(window.ethereum);

const send_account = await provider.getSigner().getAddress();  //my address

//Swap from USDC to MTS or any other token

addressOfUSDC='0x2791bca1f2de4661ed88a30c99a7a9449aa84174' // Address of USDC in Polygon
const ERC20Contract = new ethers.Contract(addressOfUSDC, ERC20ABI, provider);
swapRouterAddress="0xe592427a0aece92de3edee1f18e0157c05861564"; //Uniswap v3 router
indadr="0x440416D85E5D51424da371297E3d7Ef28312BF62"; //Any token address to which I want to swap

approvalAmount=12; //12 USDC

await ERC20Contract
    .connect(provider.getSigner())
    .approve(swapRouterAddress, approvalAmount*1000000)

//After this step we see confirmation to spend 12$ in metamask

bn=ethers.BigNumber.from(approvalAmount*1000000); //BigNumber from approvalAmount


const params = {
    tokenIn: addressOfUSDC,
    tokenOut: indadr, 
    fee: ethers.BigNumber.from(3000),  
    recipient: send_account,
    deadline: ethers.BigNumber.from(Math.floor(Date.now() / 1000) + (60 * 10)),
    amountIn: bn,
    amountOutMinimum: ethers.BigNumber.from(0),
    sqrtPriceLimitX96: ethers.BigNumber.from(0),
}

const UniswapContract= new ethers.Contract(swapRouterAddress, ERC20ABI2, provider);

dd=await UniswapContract
    .connect(provider.getSigner())
    .exactInputSingle(params)

console.log(dd);

已排查操作

  • 更换过ABI文件
  • 验证过Uniswap Router地址正确性
  • 尝试过Uniswap V2的swapExactTokensForTokens函数,问题依旧

核心修复点

1. 替换Uniswap Router的ABI(最关键)

你用ERC20ABI2初始化Uniswap V3 Router合约是错误的——Router的ABI和ERC20完全不同,错误的ABI会导致合约调用直接回滚,甚至不触发MetaMask签名请求。

  • 解决:从PolygonScan导出0xe592427a0aece92de3edee1f18e0157c05861564的官方ABI,或使用Uniswap SDK提供的Router ABI。

2. 修正参数格式

  • fee参数无需用ethers.BigNumber.from转换,直接传入数字3000(对应0.3%手续费,是Uniswap V3的合法档位)
  • 金额计算建议用ethers.utils.parseUnits避免浮点数精度问题:
    // 替代原来的bn=ethers.BigNumber.from(approvalAmount*1000000)
    const amountIn = ethers.utils.parseUnits(approvalAmount.toString(), 6); // USDC是6位小数
    
  • deadline直接计算为数字即可,ethers会自动处理为BigNumber:
    deadline: Math.floor(Date.now() / 1000) + 600 // 10分钟有效期
    

3. 检查授权与网络

  • 确认授权金额足够:调用ERC20Contract.allowance(send_account, swapRouterAddress)查看剩余授权额度,确保≥兑换金额
  • 确认MetaMask当前网络为Polygon(ChainID 137),避免跨网络调用

修复后示例代码片段

const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const send_account = await signer.getAddress();

// 常量定义
const addressOfUSDC = '0x2791bca1f2de4661ed88a30c99a7a9449aa84174';
const swapRouterAddress = '0xe592427a0aece92de3edee1f18e0157c05861564';
const indadr = '0x440416D85E5D51424da371297E3d7Ef28312BF62';
const approvalAmount = 12;

// USDC授权
const ERC20Contract = new ethers.Contract(addressOfUSDC, ERC20ABI, signer);
const approveTx = await ERC20Contract.approve(swapRouterAddress, ethers.utils.parseUnits(approvalAmount.toString(), 6));
await approveTx.wait();
console.log("授权完成");

// 初始化Uniswap Router合约(使用正确ABI)
const UNISWAP_V3_ROUTER_ABI = [/* 填入正确的Router ABI */];
const UniswapContract = new ethers.Contract(swapRouterAddress, UNISWAP_V3_ROUTER_ABI, signer);

// 兑换参数
const params = {
    tokenIn: addressOfUSDC,
    tokenOut: indadr, 
    fee: 3000,
    recipient: send_account,
    deadline: Math.floor(Date.now() / 1000) + 600,
    amountIn: ethers.utils.parseUnits(approvalAmount.toString(), 6),
    amountOutMinimum: ethers.BigNumber.from(0),
    sqrtPriceLimitX96: ethers.BigNumber.from(0),
};

// 执行兑换
const swapTx = await UniswapContract.exactInputSingle(params);
await swapTx.wait();
console.log("兑换完成,交易哈希:", swapTx.hash);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 21:05:20