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.