axelarnetwork / support

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

Transaction mined but execution failed #59

Closed Olanetsoft closed 10 months ago

Olanetsoft commented 10 months ago

New to Axelar. I'm trying to see if I can make Axelar send aUSDC from Optimism Goerli to Base Goerli. Attached below, I've written two contracts, OPSender.sol and BaseReceiver.sol, and deployed it on Optimism Goerli and Base Goerli, respectively. I tried calling the sendToMany function on OPSender to send the aUSDC from OP Goerli to Base Goerli, however I got the error Transaction mined but execution failed I am running everything on Remix IDE.

Here are the parameters I put into sendToMany

{
    "string _destChain": "Base",
    "string _destContractAddr": "0x291b1B6EB9DE79f0cb181bCF68Ae1ea70d9B8760",
    "address[] _destinationAddrs": [
        "0xD1872508B5A49eD6Ea5EefD93e643623c0F83a78"
    ],
    "string _symbol": "aUSDC",
    "uint256 _amount": "100"
}

val    10000000000000000 wei

tx : https://goerli-optimism.etherscan.io/tx/0xa8cf2c170326dc27905f6a88c50db0e67630ce97345cb0a4d319e5fe4998b6ae

I put the tx into tenderly to try and debug and it gave me an arthimetic error (arthimetic overflow / underflow), however I'm not dealing with much math here.

Putting both contracts code on another message.

Here's the OPSender.sol source code. (Btw you can check out the past transactions here : https://goerli-optimism.etherscan.io/address/0x6Fc5AAf72c7288721C4b148C8b1A0E9f496b8020. Not verified, so i'm putting the code below) :

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

import { IERC20 } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IERC20.sol';
import { IAxelarGateway } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarExecutable.sol';
import { IAxelarGasService } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarGasService.sol';

contract OPSender {
    IAxelarGasService gasReceiver;
    IAxelarGateway gateway;

    constructor (
        address _gateway,
        address _gasReceiver
    ) {
        gateway = IAxelarGateway(_gateway);
        gasReceiver = IAxelarGasService(_gasReceiver);
    }

    function sendToMany(
        string memory _destChain,
        string memory _destContractAddr,
        address[] calldata _destinationAddrs,
        string memory _symbol,
        uint256 _amount
    ) external payable {
        require(msg.value > 0, "Gas payment required");

        // get token address from symbol
        address tokenAddress = gateway.tokenAddresses(_symbol);

        // send funds to this contract
        IERC20(tokenAddress).transferFrom(msg.sender, address(this), _amount);

        // approve gateway to spend funds
        IERC20(tokenAddress).approve(address(gateway), _amount);

        // encode recipient addresses tx on destination chain
        bytes memory _payload = abi.encode(_destinationAddrs);

        //pay gas from source chain
        gasReceiver.payNativeGasForContractCallWithToken{value: msg.value} (
            address(this),
            _destChain,
            _destContractAddr,
            _payload,
            _symbol,
            _amount,
            msg.sender
        );

        // send token and execute call
        gateway.callContractWithToken(
            _destChain,
            _destContractAddr,
            _payload,
            _symbol,
            _amount
        );
    }
}

BaseReceiver.sol (https://goerli.basescan.org/address/0x291b1B6EB9DE79f0cb181bCF68Ae1ea70d9B8760. Not verified so im putting the contract code below):

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

import { IERC20 } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IERC20.sol';
import { IAxelarExecutable } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarExecutable.sol';
import { IAxelarGasService } from '@axelar-network/axelar-cgp-solidity/contracts/interfaces/IAxelarGasService.sol';

contract BaseReceiver is IAxelarExecutable {
    IAxelarGasService public immutable gasService;

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

    event Executed();

    function _executeWithToken(
        string memory,
        string memory,
        bytes calldata _payload,
        string memory _tokenSymbol,
        uint256 _amount
    ) internal override {
        // decode recipients
        address[] memory recipients = abi.decode(_payload, (address[]));

        // get token addr
        address tokenAddress = gateway.tokenAddresses(_tokenSymbol);

        // get first address
        address recipient = recipients[0];

        // transfer to recipient  
        IERC20(tokenAddress).transfer(recipient, _amount);

        emit Executed();
    }
}

any help would be appreciated, thanks!

Olanetsoft commented 10 months ago

So sorry you are getting this error. I think the missing step here is approval, you need to approve the amount to be spent spent by the contract before calling the sendToMany function.

Check this guide: https://axelar.network/blog/cross-chain-airdrop-dapp-tutorial scroll to the Implementing smart-contract write functionality section to see how the approval is done on the frontend before calling the sendToMany function.

Or you can approve directly on the aUSDC contract in Optimism Goerli https://goerli-optimism.etherscan.io/address/0x254d06f33bDc5b8ee05b2ea472107E300226659A#writeContract