axelarnetwork / support

Your source for support with the Axelar Network
3 stars 1 forks source link

Multichain swap execution reverted #114

Closed dumbled00r closed 2 months ago

dumbled00r commented 2 months ago

I have a problem with the multichain swap example on your github

I'm using SwapRouter02 along with src chain is Base Sepolia, and dest chain is ETH Sepolia (Since Mumbai is deprecated, I cannot run the same code for it)

Here is my contract's code:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import {AxelarExecutable} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/executable/AxelarExecutable.sol";
import {IAxelarGateway} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGateway.sol";
import {IAxelarGasService} from "@axelar-network/axelar-gmp-sdk-solidity/contracts/interfaces/IAxelarGasService.sol";

interface ISwapRouter02 {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    function exactInputSingle(
        ExactInputSingleParams calldata params
    ) external payable returns (uint256 amountOut);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    function exactOutputSingle(
        ExactOutputSingleParams calldata params
    ) external payable returns (uint256 amountIn);
}

contract CrosschainSwap is AxelarExecutable {
    address public wETH = 0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14; // weth on ethereum sepolia
    address public uni = 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984; // wuni on ethereum sepolia

    IAxelarGasService public immutable gasService;

    // ethereum swap router 02
    ISwapRouter02 public immutable swapRouter =
        ISwapRouter02(0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E);

    constructor(
        address _gateway,
        address _gasService
    ) AxelarExecutable(_gateway) {
        gasService = IAxelarGasService(_gasService);
    }

    function interchainSwap(
        string memory _destChain,
        string memory _destContractAddr,
        string memory _symbol,
        uint256 _amount
    ) external payable {
        require(msg.value > 0, "Gas payment required");

        uint24 poolFee = 3000;

        address tokenAddress = gateway.tokenAddresses(_symbol);

        IERC20(tokenAddress).transferFrom(msg.sender, address(this), _amount);
        IERC20(tokenAddress).approve(address(gateway), _amount);

        ISwapRouter02.ExactInputSingleParams memory params = ISwapRouter02
            .ExactInputSingleParams({
                tokenIn: tokenAddress,
                tokenOut: uni,
                fee: poolFee,
                recipient: msg.sender,
                amountIn: _amount,
                amountOutMinimum: 0,
                sqrtPriceLimitX96: 0
            });

        bytes memory encodedSwapPayload = abi.encode(params);

        gasService.payNativeGasForContractCallWithToken{value: msg.value}(
            address(this),
            _destChain,
            _destContractAddr,
            encodedSwapPayload,
            _symbol,
            _amount,
            msg.sender
        );

        gateway.callContractWithToken(
            _destChain,
            _destContractAddr,
            encodedSwapPayload,
            _symbol,
            _amount
        );
    }

    function _executeWithToken(
        string calldata,
        string calldata,
        bytes calldata _payload,
        string calldata,
        uint256 _amount
    ) internal override {
        ISwapRouter02.ExactInputSingleParams memory decodedGmpMessage = abi
            .decode(_payload, (ISwapRouter02.ExactInputSingleParams));

        IERC20(wETH).approve(address(swapRouter), _amount);

        swapRouter.exactInputSingle(decodedGmpMessage);
    }
}

Im trying to execute the swap on Sepolia (WETH -> UNI),

Here is the pool data according GeckoTerminal: Pool

I ran the above contract in hardhat console on Base Sepolia chain with this code, but this always gets reverted before executing on chain (Note that on both chains, I have more than enough ETH and WETH to cover the transaction

 await contract.interchainSwap("ethereum-sepolia", "0x136c5C515750f2c1e182D2D5FB22E10A2cE73CdA", "WETH", "1000000000000000", {value:"100000000000000000"})

Please help me out. thank you so much!

Olanetsoft commented 2 months ago

Hello @dumbled00r, thanks for flagging this. Could you please share a link to the example you are referring to here?

dumbled00r commented 2 months ago

Hello @Olanetsoft, here is the link to the code that I followed along: https://github.com/axelarnetwork/axelar-examples/blob/main/examples/evm/multichain-swap/MultichainSwap.sol Since Polygon Mumbai Testnet is currently deprecated, I have to deploy on other chains, and with SwapRouter02, not SwapRouter01 as the code was using!

benjamin852 commented 2 months ago
  1. Did you approve the token your attempting to swap on the src chain before calling the interchainSwap() function?
  2. If yes, can you try set a gasLimit in your hardhat console?
dumbled00r commented 2 months ago

Thank you @benjamin852, the problem was with the gasLimit, but still, the swap isn't executing on ETH sepolia chain, and also, I cannot access my TX LINK on the scan: https://testnet.axelarscan.io/gmp/0xdd2224aeef8e5f5f2a41b5e035829403604bc2fefe01fad99d8839c8814a0cfb

It keeps loading...

benjamin852 commented 2 months ago

Nice one step closer! It's not appearing on axelarscan because it's reverting on the src chain see here. Did you approve the token on the src chain to allow the contract to use the transferFrom function on the src chain?

dumbled00r commented 2 months ago

I have approved more than enough the amount of WETH 0x24fe7807089e321395172633aA9c4bBa4Ac4a357 on Base Sepolia for the contract to spend though.

dumbled00r commented 2 months ago

Here is the TX btw: https://sepolia.basescan.org/tx/0xe91a85f3378593eff8e335b8783d0ac31ab90b34d5e55f5fc5dd6e67debdb2d5

benjamin852 commented 2 months ago

I believe that your issue is that you're trying to send WETH from Base to Ethereum. If you look at the approved gateway assets on base you'll see WETH is not configured for Base. Based on the doc I linked before the approved assets you can interact with are aUSDC wAXL WMATIC WAVAX WFTM WBNB WDEV. If you try run your logic with one of those tokens your tx should appear on axelarscan. Note for the swap to execute on the dest chain youll still need to make sure youre passing an asset that is compatible with Uniswap on the destination chain. For example WDEV should work to send your tx out of Base but the Uniswap router wont be able to handle it on Eth Sepolia.

dumbled00r commented 2 months ago

Hi @benjamin852 , is there anyway that I can faucet the above tokens on the testnet chains and send to another chain?. Or I have to wrap them manually through this tutorial: https://docs.axelar.dev/resources/tokens/wrapped-tokens and then we can use them to send?

benjamin852 commented 2 months ago

Hey, ya for Gateway tokens (all the above tokens I mentioned before) you would need to use those exact wrapped assets to interact with callContractWithToken(). I think I will revisit this example and try get it up and running on a different blockchain since its reliance on mumbai sort of depracates the example