警告!合约执行期间遇到错误[执行已恢复](Base Layer2)

问题描述 投票:0回答:1

我正在尝试在 Node.js 环境中使用 Uniswap V2 SDK 执行交换。 但是,当我运行下面的代码时,我收到以下错误:
“警告!合约执行期间遇到错误[执行已恢复]”

async function createPair() {
  const pairAddress = Pair.getAddress(TOKEN, WETH9[TOKEN.chainId]);

  const pairContract = new ethers.Contract(pairAddress, UniswapV2PoolAbi, provider);

  const reserves = await pairContract['getReserves']();
  const [reserve0, reserve1] = reserves;

  const reserve0Parsed = BigInt(reserve0.toString()).toString();
  const reserve1Parsed = BigInt(reserve1.toString()).toString();

  const tokens = [TOKEN, WETH9[TOKEN.chainId]];
  const [token0, token1] = tokens[0].sortsBefore(tokens[1]) ? tokens : [tokens[1], tokens[0]];

  const pair = new Pair(
    CurrencyAmount.fromRawAmount(token0, reserve0Parsed),
    CurrencyAmount.fromRawAmount(token1, reserve1Parsed)
  );

  return pair;
}

async function swap() {
  const amountIn = ethers.parseEther('0.00001').toString();
  const slippageTolerance = new Percent('50', '10000');
  const to = WALLET_ADDRESS;
  const signer = new ethers.Wallet(WALLET_SECRET);
  const account = signer.connect(provider);
  const command = '0x08';
  const deadline = 2 * 10 ** 10;
  const fromEoa = true;

  const uniswap = new ethers.Contract(
    swapRouterAddress,
    [
      'function execute(bytes calldata commands, bytes[] calldata inputs, uint256 deadline) external payable returns (bytes[] memory outputs)',
    ],
    account
  );

  const pair = await createPair();
  const route = new Route([pair], WETH9[TOKEN.chainId], TOKEN);
  const trade = new Trade(
    route,
    CurrencyAmount.fromRawAmount(WETH9[TOKEN.chainId], amountIn),
    TradeType.EXACT_INPUT
  );

  const amountOutMin = trade.minimumAmountOut(slippageTolerance).toExact();

  const amoutOut = ethers.parseEther(amountOutMin);

  const pathData = ethers.solidityPacked(
    ['address', 'address'],
    [WETH9[ChainId.BASE].address, TOKEN.address]
  );

  const v2Calldata = ethers.AbiCoder.defaultAbiCoder().encode(
    ['address', 'uint256', 'uint256', 'bytes', 'bool'],
    [to, amountIn, amoutOut, pathData, fromEoa]
  );

  const tx = await uniswap.execute(command, [v2Calldata], deadline, {
    value: amountIn,
    gasPrice: ethers.parseUnits('0.15', 'gwei'),
    gasLimit: 100000,
    chainId: ChainId.BASE,
    from: WALLET_ADDRESS,
  });

  console.log(`Transaction hash: ${tx.hash}`);
  const receipt = await tx.wait();

  console.log(`Transaction was mined in block ${receipt.blockNumber}`);
}

*/

以下是代码功能的简要概述:

  1. 导入必要的Uniswap V2 SDK组件和ethers.js。
  2. 使用 QuickNode HTTP 端点设置提供程序。
  3. 定义钱包地址和秘密。
  4. 创建一个 swapRouterAddress 和一个 TOKEN。
  5. 定义一个使用 Uniswap V2 执行交换的交换函数。
  6. 交换功能内部:
  • a.设置 amountIn、滑点容限、收件人地址和签名者。
  • b.创建一个 Uniswap 合约实例。
  • c.调用 createPair() 创建 Uniswap 对。
  • d。计算交易详细信息并对通话数据进行编码。
  • e。使用 Uniswap 的execute()函数执行交换。

我怀疑这个问题可能与我如何编码数据或设置有关 交易。有人可以帮助我理解为什么我会收到此错误 我该如何解决它?

还可以检查我的一些交易: https://basescan.org/tx/0x5a4ccdf8476eac2b41e00927cae6cb5817cff4acfb1c4746244ebd3d22784e9e

谢谢!

javascript ethereum uniswap layer-2
1个回答
0
投票

您发布的交易中的问题是它试图进行 v3 交换,因为您为命令设置了

0x00

v3SwapExactInput(map(recipient), amountIn, amountOutMin, path, payer);

由于路径没有创建现有池所需的值,因此事务失败

computePoolAddress

IUniswapV3Pool(computePoolAddress(tokenIn, tokenOut, fee))

您发布的代码将

08
作为用于 v2 交换的命令,而在您地址列出的最新示例中,您正在使用命令
0b00
,因此在同一阶段失败。

execute
函数倒数第二次失败时,您使用
0x0b08
尝试 v2 调用。但失败于:

(block.timestamp > allowed.expiration) revert AllowanceExpired(allowed.expiration);

看来您必须将其设置为从钱包中获取,因为它需要许可。 通过该阶段的一个解决方案是将付款人设置为

false
,因为您已经转移到并在合同中包装了 eth。

如果我切换该字节中的位

"0x0000000000000000000000001991ac5419991ebd2c11783db5087644b125c912000000000000000000000000000000000000000000000000000009184e72a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004200000000000000000000000000000000000006000000000000000000000000bc45647ea894030a4e9801ec03479739fa2485f0"

它更进一步,失败于:

uint256 balanceBefore = tokenOut.balanceOf(recipient);

因为代币是零地址,因为它试图在零地址上调用余额。这意味着路径周围的调用数据必须格式错误。

如果我模仿成功交易的偏移量:

0x000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000f71635b554633d00000000000000000000000000000000000000000000011c2867721c0a0702db00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000004200000000000000000000000000000000000006000000000000000000000000bc45647ea894030a4e9801ec03479739fa2485f0

我们会因为没油而失败。 加大油门,我们就成功了:

如果您通过您发布的确切代码生成的通话数据交易失败,请更新该代码,然后我将更新答案以说明您的编码方式等。

希望这能有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.