Search code examples
javascriptethereumuniswaplayer-2

Warning! Error encountered during contract execution [execution reverted] (Base Layer2)


I'm trying to execute a swap using Uniswap V2 SDK in a Node.js environment. However, when I run the code below, I receive the following error:
"Warning! Error encountered during contract execution [execution reverted]"

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}`);
}

*/

Here's a brief overview of what the code does:

  1. Imports necessary Uniswap V2 SDK components and ethers.js.
  2. Sets up provider with a QuickNode HTTP endpoint.
  3. Defines wallet address and secret.
  4. Creates a swapRouterAddress and a TOKEN.
  5. Defines a swap function that executes a swap using Uniswap V2.
  6. Inside the swap function:
  • a. Sets up amountIn, slippage tolerance, recipient address, and signer.
  • b. Creates a Uniswap contract instance.
  • c. Calls createPair() to create a Uniswap pair.
  • d. Calculates trade details and encodes calldata.
  • e. Executes the swap with Uniswap's execute() function.

I suspect the issue might be related to how I'm encoding the data or setting up the transaction. Can someone help me understand why I'm getting this error and how I can resolve it?

Also check some of my transactions: https://basescan.org/tx/0x5a4ccdf8476eac2b41e00927cae6cb5817cff4acfb1c4746244ebd3d22784e9e tenderly analyzer

Thanks!


Updated question: Here is my current code :

async function swap() {
const swapRouterAddress = '0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad';
const TOKEN = new Token(ChainId.BASE, '0xBC45647eA894030a4E9801Ec03479739FA2485F0', 18);
const amountIn = ethers.parseEther('0.00001').toString();
  const to = WALLET_ADDRESS;
  const signer = new ethers.Wallet(WALLET_SECRET);
  const account = signer.connect(provider);
  const command = '0x0b08';
  const deadline = 2 * 10 ** 10;
  const fromEoa = false;
  const FEE = 500;

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

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

  const wrap_calldata = ethers.AbiCoder.defaultAbiCoder().encode(
    ['address', 'uint256'],
    [swapRouterAddress, amountIn]
  );

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

  const tx = await uniswap.execute(command, [wrap_calldata, v2Calldata], {
    value: amountIn,
    gasPrice: ethers.parseUnits('0.15', 'gwei'),
    gasLimit: 150000,
    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}`);
}

Also I'm getting the error in the path as Maka mentioned in his answer :

https://basescan.org/tx/0xb661d0eb3fb7d4d6580424ce9c2462cdfa7735f256332c422187506f57a700f7

enter image description here


Solution

  • After some adjustments to the code, I managed to resolve the issue with the execution error. Here's the updated swap() function that works correctly:

    async function swap() {
      const swapRouterAddress = '0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad';
      const TOKEN = new Token(ChainId.BASE, '0xBC45647eA894030a4E9801Ec03479739FA2485F0', 18);
      const amountIn = ethers.parseEther('0.00001').toString();
      const to = WALLET_ADDRESS;
      const signer = new ethers.Wallet(WALLET_SECRET);
      const account = signer.connect(provider);
      const command = '0x0b08';
      const deadline = 2 * 10 ** 10;
      const fromEoa = false;
      const FEE = 500;
    
      const uniswap = new ethers.Contract(
        swapRouterAddress,
        [
          'function execute(bytes calldata commands, bytes[] calldata inputs) external payable returns (bytes[] memory outputs)',
        ],
        account
      );
    
      const pathData = ethers.AbiCoder.defaultAbiCoder().encode(
        ['address', 'address'],
        [WETH9[ChainId.BASE].address, TOKEN.address]
      );
    
      const wrap_calldata = ethers.AbiCoder.defaultAbiCoder().encode(
        ['address', 'uint256'],
        [swapRouterAddress, amountIn]
      );
    
      const v2Calldata = ethers.AbiCoder.defaultAbiCoder().encode(
        ['address', 'uint256', 'uint256', 'address[]', 'bool'],
        [to, amountIn, 0, [WETH9[ChainId.BASE].address, TOKEN.address], fromEoa]
      );
    
      const tx = await uniswap.execute(command, [wrap_calldata, v2Calldata], {
        value: amountIn,
        gasPrice: ethers.parseUnits('0.15', 'gwei'),
        gasLimit: 200000,
        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}`);
    }