Error when tx is executed in destination chain (Although one or more Error Occurred [execution reverted])

94 Views Asked by At

Im working in a bridge for NFTs in a collection and I'm trying to mint from sepolia to mumbai, I've been trying but I get an execution error in the destination chain. The tx went through in the source chain but it gets an error in the destination one I know this is an error of mine, but I wanted to know why is this happening, as I can't see the internal txs of the tx in the destination chain, I can't see the error, here is my code from CCIPReceiver in mumbai:

`// SPDX-License-Identifier: MIT pragma solidity 0.8.19;

import {CCIPReceiver} from "@chainlink/contracts-ccip/src/v0.8/ccip/applications/CCIPReceiver.sol"; import {Client} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol"; import {EndersComicsMultiTokensTest} from "./EndersComicsTest.sol";

contract DestinationMinterEdited is CCIPReceiver { EndersComicsMultiTokensTest nft;

event MintCallSuccessfull();

constructor(address router, address nftAddress) CCIPReceiver(router) {
    nft = EndersComicsMultiTokensTest(nftAddress);
}

function _ccipReceive(
    Client.Any2EVMMessage memory message
) internal override {
    (bool success, ) = address(nft).call(message.data);
    require(success, "tx failed");
    emit MintCallSuccessfull();
}

}`

This is the code for the Source Minter in sepolia:

`// SPDX-License-Identifier: MIT pragma solidity 0.8.19;

import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/shared/interfaces/LinkTokenInterface.sol"; import {IRouterClient} from "@chainlink/contracts-ccip/src/v0.8/ccip/interfaces/IRouterClient.sol"; import {Client} from "@chainlink/contracts-ccip/src/v0.8/ccip/libraries/Client.sol"; import {Withdraw} from "./utils/Withdraw.sol";

contract SourceMinterEdited is Withdraw { enum PayFeesIn { Native, LINK }

address immutable i_router;
address immutable i_link;

event MessageSent(bytes32 messageId);

constructor(address router, address link) {
    i_router = router;
    i_link = link;
    LinkTokenInterface(i_link).approve(i_router, type(uint256).max);
}

receive() external payable {}

function mint(
    uint64 destinationChainSelector,
    address receiver,
    uint256 id,
    uint256 amount,
    PayFeesIn payFeesIn
) external {
    Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
        receiver: abi.encode(receiver),
        data: abi.encodeWithSignature(
            "mintBatch(address,uint256[],uint256[])",
            msg.sender,
            id,
            amount
        ),
        tokenAmounts: new Client.EVMTokenAmount[](0),
        extraArgs: Client._argsToBytes(
            // Additional arguments, setting gas limit
            Client.EVMExtraArgsV1({gasLimit: 2_000_000})
        ),
        feeToken: payFeesIn == PayFeesIn.LINK ? i_link : address(0)
    });

    uint256 fee = IRouterClient(i_router).getFee(
        destinationChainSelector,
        message
    );

    bytes32 messageId;

    if (payFeesIn == PayFeesIn.LINK) {
        // LinkTokenInterface(i_link).approve(i_router, fee);
        messageId = IRouterClient(i_router).ccipSend(
            destinationChainSelector,
            message
        );
    } else {
        messageId = IRouterClient(i_router).ccipSend{value: fee}(
            destinationChainSelector,
            message
        );
    }

    emit MessageSent(messageId);
}

} `

This is the code of EndersComicsMultiTokensTest contract mintBatch function, as you see is a simple mintBatch: function mintBatch( address _receiver, uint256[] calldata ids, uint256[] calldata amounts ) external { _mintBatch(_receiver, ids, amounts, ""); }

Probably the mistake is in the encodeSignature in the sender contract but is something I can't address. I would really appreciate your help.

Here are some of the txs that failed: https://ccip.chain.link/address/0x65b5df19756925Fe1a799dd65742185f117ca0d3 https://ccip.chain.link/address/0x17f806eFadA3a4cF9B18Fa51382c0937a45d4de7

I have try several things, changing the gas_limit in the encodeWithSignature function, also changing the attributes from mintBatch to be only atomic types (non arrays) but none of that worked

1

There are 1 best solutions below

0
Andrej On

As you correctly assumed, the problem is on the encoding side:

data: abi.encodeWithSignature(
            "mintBatch(address,uint256[],uint256[])",
            msg.sender,
            id,
            amount
      ),

Because both variables id and amount are uint256 while you are expected to encode two uint256 arrays.

The solution will be to:

a) either pass two uint256 arrays instead of id and amount variables like this:

function mint(
    uint64 destinationChainSelector,
    address receiver,
    uint256[] ids,
    uint256[] amounts,
    PayFeesIn payFeesIn
) external {

b) or to create two in-memory arrays containing mentioned variables, like this:

function mint(
    uint64 destinationChainSelector,
    address receiver,
    uint256 id,
    uint256 amount,
    PayFeesIn payFeesIn
) external {
    uint256[] memory ids = new uint[](1);
    ids[0] = id;

    uint256[] memory amounts = new uint[](1);
    amounts[0] = amount;

    
    Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({
        receiver: abi.encode(receiver),
        data: abi.encodeWithSignature(
            "mintBatch(address,uint256[],uint256[])",
            msg.sender,
            ids,
            amounts
        ),
        tokenAmounts: new Client.EVMTokenAmount[](0),
        extraArgs: Client._argsToBytes(
            // Additional arguments, setting gas limit
            Client.EVMExtraArgsV1({gasLimit: 2_000_000})
        ),
        feeToken: payFeesIn == PayFeesIn.LINK ? i_link : address(0)
    });

    // The rest of the function logic...

}