Skip to content

Soldeer publish: rewrite internal imports to versioned form (@openzeppelin-contracts-X.Y.Z/...) #232

Description

@thedavidmeister

The OpenZeppelin contracts and contracts-upgradeable packages, as shipped to soldeer.xyz, contain internal import statements that use the unversioned namespace @openzeppelin/contracts/...:

$ grep -rh '^import' dependencies/@openzeppelin-contracts-upgradeable-5.6.1/access/ | head
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
...

When a downstream soldeer consumer adds both @openzeppelin-contracts and @openzeppelin-contracts-upgradeable as deps, the upgradeable package's internal imports do NOT resolve unless the consumer adds a manual remapping:

remappings = [
    "@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.6.1/",
]

That remapping is a compat shim — it papers over the fact that @openzeppelin/contracts/... could mean ANY OZ version. If the consumer ever bumps OZ from 5.6.1 to 5.7.0 and adjusts the soldeer dep version, the remapping silently still points at 5.6.1, with no visible signal in source.

Proposed fix

Publish OZ contracts-upgradeable to soldeer with internal imports rewritten to the versioned form:

import {IAccessControl} from "@openzeppelin-contracts-5.6.1/access/IAccessControl.sol";

That way:

  • Consumers don't need a compat remapping.
  • A version bump in the upgradeable package surfaces a corresponding source-level change in the imports, making the OZ dep version explicit at every call site.
  • Drops a class of "silent stale remap" bugs.

This means the soldeer-side packaging step needs to rewrite imports during publish, or the OZ-contracts-upgradeable project would need a build step that emits a soldeer-friendly version.

Scope

This impacts every soldeer downstream consumer of OZ contracts-upgradeable (5.x line at minimum). Filing here on OZ contracts-upgradeable; happy to point at any active soldeer-publish workflow you're using if helpful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions