Solidity – Is Type Casting Address Variables to Contract Types More Expensive?

gasoptimizationsolidity

Let's say we have two options for defining a token as a storage variable:

A:

address token = 0xc0ffee...;
...
for(...) {
  IERC20(token).transfer(...);
}

B:

IERC20 token = IERC20(0xc0ffee...);
...
for(...) {
  token.transfer(...);
}

From both options above, what would be the more gas-efficient option for accessing and interacting with the token contract? And why?

Best Answer

From both options above, what would be the more gas-efficient option for accessing and interacting with the token contract? And why?

They are exactly the same.

There is no difference between address and any interface or contract for that matter. The true underlying type is always address. IERC20 or anything else is just a way to interpret an address as being the identifier of a specific type of contract.

See the following example :

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

interface iToken {
        function transfer() external view; 
}

contract Token is iToken {
        function transfer() public override view {
                return;
        }
}

contract Test1 {

        address token;

        constructor(address _token) {
                token = _token;
        }

        function test() public view {
                iToken(token).transfer();             
        }
}

contract Test2 {

        iToken token;

        constructor(iToken _token) {
                token = _token;
        }

        function test() public view {
                token.transfer();
        }
}

contract Test3 {

        Token token;

        constructor(Token _token) {
                token = _token;
        }

        function test() public view {
                token.transfer();
        }
}

Calling the test function on Test1, Test2 or Test3 cost 26277 gas in all cases (Remix - default settings).

You could also check storage slot 0 of all TestX contract's and see that they all have the very same value : the address of the Token contract. There is no difference at the lower levels.

Related Topic