Solidity – How to Convert In-Memory Static Array to Calldata Static Array

arrayscalldatacontract-developmentsoliditysolidity-0.8.x

I have a contract called Erc20Recover in which I have the following function:

pragma solidity >=0.8.0;

contract Erc20Recover {
    function _setNonRecoverableTokens(IErc20[] calldata tokens) public {
        // ...
    }
}

I have another contract called HToken which inherits from Erc20Recover and in whose constructor I attempted to call _setNonRecoverableTokens:

pragma solidity >=0.8.0;

contract HToken is Erc20Recover {
    constructor(underlying) {
        IErc20[1] memory nonRecoverableTokens = [underlying];
        _setNonRecoverableTokens(nonRecoverableTokens);
    }
}

But the code does not compile:

Invalid type for argument in function call. Invalid implicit conversion from contract IErc20[1] memory to contract IErc20[] calldata requested.

How can I turn that in-memory static array into a calldata array? Or, more generally, how can I call _setNonRecoverableTokens?

For context: IErc20 is my implementation of the ERC-20 interface.

Best Answer

It's not possible to copy data from memory to calldata. Calldata, being the cheapest type of storage, is read-only and can only be used for data passed in to a function through the transaction input.

From the Solidity documentation:

As already said, the called contract (which can be the same as the caller) will receive a freshly cleared instance of memory and has access to the call payload - which will be provided in a separate area called the calldata.

As you mentioned in the comments, simply using memory instead of calldata for tokens solves the issue. If you're calling the contract through a transaction, this will simply copy the calldata to the memory.

Related Topic