Why is there a restrictive pragma on interfaces in the 5.0.2 release?

I'm wondering why OZ chose to restrict interfaces to pragma solidity ^0.8.20 in the 5.0.2 release? Example of restrictive IERC20. From past releases, the interfaces have always been open to the entire minor compiler version, ex pragma solidity ^0.8.0.

I'm working in a complex codebase with many moving parts, and the locked pragma is making it difficult to upgrade to 5.0.2 because many contracts are using <0.8.20. It's infeasible to upgrade everything in my codebase to 0.8.20+ in a short timeframe, so I can either manually unlock the pragma for specific interfaces (like IERC20) or wait to upgrade our OZ dependancies until I can get all contracts up to 0.8.20+.

Is there anything specific in these locked interfaces that genuinely requires 0.8.20+? I don't see anything, but I wanted to double check. Thank you!

1 Like

I assume OZ had to bump some interfaces to at least ^0.8.4 to allow support for custom errors. But I still don't see any reason to bump all the interfaces to ^0.8.20.

1 Like

Hey @ryanrhall, thanks for reporting.

We needed 0.8.20 to get support for NatSpec in struct members. This is noted in the 0.8.20 release changelog. We needed it because OpenZeppelin's upgrades plugins rely on struct annotations to ensure upgrade safety between versions (see Namespaced Storage Layout).

Note that it's been using 0.8.20 since the 5.0.0 version, so I wonder whether you're upgrading from the 4.x version. Please reconsider if that's the case, since the 4.x and 5.x storage layout are not the same (:warning:)

2 Likes

@ernestognw Thank you for the reply and explanation! We are upgrading from 4.x to 5.x, although everything will be a fresh deploy; we aren't using any on-chain upgradable contracts, so no worries there.

From what I understand, 0.8.20 seemed critical for some OZ contracts, but interfaces like OZ's IERC20 implementation are not using any newer solidity features that mandate it's ^0.8.20 restriction. IERC20 could have stayed unlocked at ^0.8.0 without interfering with OZ's Namespaced Storage Layout, or other contracts needing more advanced features. Is that accurate?

we aren't using any on-chain upgradable contracts, so no worries there.

Thanks for clarifying, just wanted to make sure you were safe :sweat_smile:


The observation about the pragma on interfaces is a really good one. I couldn't find any specific reason to keep it, so you're right. iirc our rationale was that there was no reason to use a lower pragma than in the "logic" contracts.

In this case, I'd suggest unlocking the pragma manually as long as it's for the interfaces, the only error you may get (if any) could be related to language features rather than logical issues. Then migrate to 0.8.20 when possible. Testing thoroughly is of course advised but I'm sure you got it covered :raised_hands:

1 Like

Looking at past releases, I realize now that OZ has always used a single, minimum version across both interfaces and "logic" contracts, so I understand not wanting to break that pattern. In the future, it would be helpful to keep interfaces "as open as possible", but I understand the desire to keep things simple. Thanks again for the feedback and explanations @ernestognw :raised_hands: