I'm playing with a contract that uses an ERC20 token, and I can see basically 2 options to init the token:

  1. Use the interface contract (IERC20)
  2. Use the implemented contract (ERC20)

Interface version:

import "https://github.com/OpenZeppelin/openzeppelincontracts/blob/v3.4.0/contracts/token/ERC20/IERC20.sol";
    contract UseIERC2oToken {
      IERC20 itoken = IERC20(0x5Bd2a79Eb49920C645de715048e0EE571DB505E5);

Implementation version:

import "https://github.com/OpenZeppelin/openzeppelincontracts/blob/v3.4.0/contracts/token/ERC20/ERC20.sol";

contract UseERC2oToken {
    ERC20 token = ERC20(0x5Bd2a79Eb49920C645de715048e0EE571DB505E5);

I have seen that most of the times, developers use the interface but both options get the same result, but I'm not sure what option is more efficient. Any idea?

Thanks too much

1 Answer 1


If you are using the standard functions defined by EIP-20 it doesn't matter either works the same.

There are some differences. For example OpenZeppelin's ERC20 implements increaseAllowance that is not part of the ERC-20 standard. Then to call an address that implements increaseAllowance you can do so only with ERC20.

ERC20 token = ERC20(<address>);
require(token.increaseAllowance(user, 1234), "Can't increase allowance");
  • 2
    Nice, I missed that point and figured out that was a kind of good practice to use the Interface over the Implementation (like in other OOP languages). Commented Mar 23, 2021 at 13:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.