Skip to content

Make ValidatorManager contracts compatible with OpenZeppelin upgrades plugins #648

@Nuttymoon

Description

@Nuttymoon

Context and scope
The current implementations of ValidatorManager (PoAValidatorManager, ERC20TokenStakingManager, NativeTokenStakingManger) have multiple incompatibilities with the OpenZeppelin upgrades plugin, making the safety validation fail.

This limits the reusability of the contracts outside of the teleporter / Avalanche CLI context (ofc developers can still disable the safety validation, but this is far from ideal).

The 2 incompatibilities are:

  • The constructor defined in all contracts
  • The external functions present in the ValidatorMessages library

as we can see with these errors raised when trying to deploy a PoAValidatorManager with Upgrades.deployTransparentProxy:

[FAIL: setup failed: revert: Upgrade safety validation failed:
✘  lib/teleporter/contracts/validator-manager/PoAValidatorManager.sol:PoAValidatorManager

      lib/teleporter/contracts/validator-manager/PoAValidatorManager.sol:24: Contract `PoAValidatorManager` has a constructor
          Define an initializer instead
          https://zpl.in/upgrades/error-001
      
      lib/teleporter/contracts/validator-manager/ValidatorMessages.sol: Linking external libraries like `ValidatorMessages` is not yet supported
          Use libraries with internal functions only, or skip this check with the `unsafeAllowLinkedLibraries` flag 
          if you have manually checked that the libraries are upgrade safe
          https://zpl.in/upgrades/error-006

FAILED]

Solving those doesn't seem too complicated:

  1. Remove the constructor
  2. Make the ValidatorMessages functions internal

Discussion and alternatives
This might be a non-issue if you want ALL deployments of such contracts to be done through the Avalanche CLI (and not via Forge).

A workaround for the external libraries check would be to add @custom:oz-upgrades-unsafe-allow external-library-linking to all contracts.

Another alternative is to deploy the contracts more manually (deploy the implementation, then the proxy, etc.) but this is more error-prone.

Open questions

  • What is the impact of removing the constructor that uses ICMInitializable?
  • Is there any downside to making the ValidatorMessages functions internal?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Backlog 🧊

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions