Is IERC20Upgradeable removed from contracts-upgradeable?

Hi there,

I'm working on an upgradeable contract and I just installed contracts 5.0 and contracts-upgradeable 5.0. I noticed that IERC20Upgradeable.sol is no longer in the library. Would the following code be considered the same?

//old
using SafeERC20Upgradeable for IERC20Upgradeable;

//vs

//new
using SafeERC20 for ERC20Upgradeable;

Thank you! :slight_smile:

Hey @mtzrW3, quoting our v5.0 release notes:

  • Upgradeable contracts no longer transpile interfaces and libraries. (#4628)

The upgradeable version of the library now uses the vanilla @openzeppelin/contracts libraries and interfaces. You can solve by importing them from the vanilla repository

- import from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
- import from "@openzeppelin/contracts-upgradeable/interfaces/IERC20Upgradeable.sol";
+ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
+ import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20".sol";

- using SafeERC20Upgradeable for IERC20Upgradeable
+ using SafeERC20 for IERC20;

The reason why we removed interfaces and libraries from Upgradeable contracts is that the distinction between IERC20Upgradeable and IERC20 is unnecessary and having both causes a declaration conflict.

For example:

interface IMyContract is IERC721 {}

// TypeError: Derived contract must override function "safeTransferFrom". Two or more base classes define function with same name and parameter types.
contract MyContract is IMyContract, ERC721Upgradeable {}

In the example above, MyContract needs to override both IERC712 and IERC721Upgradeable so that an override specifier is needed when both interfaces are the same.

Also generally it doesn't make sense to have upgradeable variants of stateless contracts because the upgradeable variants apply changes that are related to storage usage.

3 Likes