Polygon主网Uniswap合约swap交易失败排查求助
解决方案:Hardhat调用FlashLoan合约CALL_EXCEPTION问题排查
1. 核对函数签名与参数匹配
确认firstSwap函数的参数顺序、类型和合约定义完全一致。比如USDC/LINK地址、交易金额、Uniswap V3手续费档位等参数,ethers.js调用时一旦错位或类型不匹配,会直接触发CALL_EXCEPTION。
示例:若合约函数为function firstSwap(address tokenIn, address tokenOut, uint256 amountIn, uint24 fee) external,脚本必须严格按此顺序传参,不能颠倒参数位置。
2. 校验交易发起者权限
检查合约中firstSwap是否有访问控制逻辑(如onlyOwner修饰器):
- Remix调用时若使用的是合约部署者地址,而Hardhat脚本用的是其他测试地址(比如
hardhat accounts生成的非部署者账号),会触发权限校验失败。 - 解决:要么在脚本中切换至部署者地址调用,要么按需修改合约的权限控制逻辑。
3. 修正Polygon主网的链配置与Gas参数
- 确保Hardhat配置文件中Polygon主网的
chainId设置为137,避免链ID不匹配导致交易无效。 - 即便Gas额度充足,Polygon主网Gas价格波动较大,可在脚本中显式设置Gas参数:
await contract.firstSwap( usdcAddress, linkAddress, amountIn, feeTier, { gasLimit: 3000000, maxPriorityFeePerGas: ethers.utils.parseUnits("30", "gwei"), maxFeePerGas: ethers.utils.parseUnits("40", "gwei") } ); - 同时确认Hardhat连接的是Polygon主网节点(如Alchemy/Infura的Polygon端点),而非测试网。
4. 补全USDC授权步骤
虽然合约有USDC余额,但Uniswap V3 Swap需要合约先授权给Uniswap Router。Remix调用时可能手动执行过approve,但Hardhat脚本可能遗漏此步骤:
const usdcContract = await ethers.getContractAt("IERC20", usdcAddress); // 授权Uniswap Router可花费指定额度的USDC await usdcContract.approve(uniswapRouterAddress, amountIn); // 等待授权交易上链后再执行swap await new Promise(resolve => setTimeout(resolve, 5000)); await contract.firstSwap(...);
5. 启用调试定位具体错误
- 在Hardhat脚本中添加调试日志:
ethers.utils.Logger.setLogLevel(ethers.utils.Logger.levels.DEBUG),查看CALL_EXCEPTION的具体revert信息。 - 在合约关键位置导入
hardhat/console.sol并添加console.log,部署带日志的合约后,通过Hardhat脚本调用时输出日志,定位失败环节。
内容的提问来源于stack exchange,提问作者Paucar
相关产品推荐
相关产品推荐

