Error: @openzeppelin/contracts/utils/Address.sol:191: Use of delegatecall is not allowed https://zpl.in/upgrades/error-002

Hi All,

I am trying to debug test code using vscode with uups proxy using hardhat. I get this weird error message, I don't use delegate calls and@openzeppelin/contracts/utils/Address.sol:
Error debug message:

1) SimplicyGovernorUpgradeable
       "before each" hook for "initializer has run":
     Error: Contract `SimplicyTimelockControllerUpgradeable` is not upgrade safe

@openzeppelin/contracts/utils/Address.sol:191: Use of delegatecall is not allowed
    https://zpl.in/upgrades/error-002
      at assertUpgradeSafe (/Users/iamdev/Documents/SIMPLICY.io/repositories/simplicy-contracts-upgradeable/node_modules/@openzeppelin/upgrades-core/src/validate/query.ts:19:11)
      at deployImpl (/Users/iamdev/Documents/SIMPLICY.io/repositories/simplicy-contracts-upgradeable/node_modules/@openzeppelin/hardhat-upgrades/src/utils/deploy-impl.ts:102:20)
      at deployProxyImpl (/Users/iamdev/Documents/SIMPLICY.io/repositories/simplicy-contracts-upgradeable/node_modules/@openzeppelin/hardhat-upgrades/src/utils/deploy-impl.ts:76:10)
      at async Proxy.deployProxy (/Users/iamdev/Documents/SIMPLICY.io/repositories/simplicy-contracts-upgradeable/node_modules/@openzeppelin/hardhat-upgrades/src/deploy-proxy.ts:42:28)
      at async Context.<anonymous> (/Users/iamdev/Documents/SIMPLICY.io/repositories/simplicy-contracts-upgradeable/test/governance/SimplicyGovernorUpgradeable.test.ts:57:31)

Test code:

beforeEach(async function () {
    const [owner, proposer, voter1, voter2, voter3, voter4, delegatee] =
      await ethers.getSigners();
    this.owner = owner;
    this.proposer = proposer;
    this.voter1 = voter1;
    this.voter2 = voter2;
    this.voter3 = voter3;
    this.voter4 = voter4;
    this.delegatee = delegatee;

    const SimplicyTimelockController = await ethers.getContractFactory(
      "SimplicyTimelockControllerUpgradeable",
    );
    this.timelockController = await upgrades.deployProxy(
      SimplicyTimelockController,
      [MINDELAY.toString(), [], [], this.owner.address],
    );
    await this.timelockController.deployed();

    const SimplicyRoot = await ethers.getContractFactory(
      "SimplicyRootUpgradeable",
    );
    this.token = await upgrades.deployProxy(SimplicyRoot, [
      NAME,
      SYMBOL,
      DECIMAL,
      this.owner.address,
      INITIAL_SUPPLY,
      INITIAL_SUPPLY,
      this.timelockController.address,
    ]);
    await this.token.deployed();

    await this.token.connect(this.voter1).delegate(this.voter1.address);
    await this.token.connect(this.voter2).delegate(this.voter2.address);
    await this.token.connect(this.voter3).delegate(this.voter3.address);
    await this.token.connect(this.voter4).delegate(this.voter4.address);

    const SimplicyGovernor = await ethers.getContractFactory(
      "SimplicyGovernorUpgradeable",
    );
    this.governor = await upgrades.deployProxy(
      SimplicyGovernor,
      [
        GOVERNOR_NAME,
        this.token.address,
        VOTING_DELAY,
        VOTING_PERIOD,
        this.timelockController.address,
        QUORUM_NUMERATOR,
        this.owner.address,
      ],
      { kind: "uups" },
    );
    await this.governor.deployed();

    const CallReceiverMock = await ethers.getContractFactory(
      "CallReceiverMock",
    );
    this.receiver = await CallReceiverMock.deploy();
    await this.receiver.deployed();

    this.chainId = await this.token.getChainId();
  });

Code Smart Contract:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.11;

import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/GovernorUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorSettingsUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/compatibility/GovernorCompatibilityBravoUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorVotesQuorumFractionUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/extensions/GovernorTimelockControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradea
le/governance/utils/IVotesUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract SimplicyGovernorUpgradeable is 
    Initializable,
    AccessControlUpgradeable,
    GovernorUpgradeable, 
    GovernorSettingsUpgradeable, 
    GovernorCompatibilityBravoUpgradeable,
    GovernorVotesUpgradeable,
    GovernorVotesQuorumFractionUpgradeable,
    GovernorTimelockControlUpgradeable,
    UUPSUpgradeable 
{
    bool public initializerRan;
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {
        // solhint-disable-previous-line no-empty-blocks
    }
    
    function initialize(
        string memory mName,
        address mToken,
        uint256 mVotingDelay,
        uint256 mVotingPeriod,
        TimelockControllerUpgradeable mTimelock,
        uint256 mQuorumNumerator,
        address mOwner
    )
        public initializer
    {
        __AccessControl_init();
        __ERC165_init();
        __Governor_init(mName);
        __GovernorSettings_init(mVotingDelay, mVotingPeriod, 0);
        __GovernorCompatibilityBravo_init();
        __GovernorVotes_init(IVotesUpgradeable(mToken));
        __GovernorVotesQuorumFraction_init(mQuorumNumerator);
        __GovernorTimelockControl_init(mTimelock);
        __UUPSUpgradeable_init();
        __MoonedgeGovernor_init_unchained(mName, mToken, mVotingDelay, mVotingPeriod, mTimelock, mQuorumNumerator, mOwner);
    }

    // solhint-disable-next-line func-name-mixedcase
    function __MoonedgeGovernor_init_unchained(
        string memory,
        address,
        uint256,
        uint256,
        TimelockControllerUpgradeable,
        uint256,
        address mOwner
    ) internal onlyInitializing {
        _grantRole(UPGRADER_ROLE, _msgSender());
        _grantRole(UPGRADER_ROLE, mOwner);
        initializerRan = true;
    }

    // The following functions are overrides required by Solidity.
    function votingDelay()
        public
        view
        virtual
        override(IGovernorUpgradeable, GovernorSettingsUpgradeable)
        returns (uint256)
    {
        return super.votingDelay();
    }

    function votingPeriod()
        public
        view
        virtual
        override(IGovernorUpgradeable, GovernorSettingsUpgradeable)
        returns (uint256)
    {
        return super.votingPeriod();
    }

    function quorum(uint256 blockNumber)
        public
        view
        virtual
        override(IGovernorUpgradeable, GovernorVotesQuorumFractionUpgradeable)
        returns (uint256)
    {
        return super.quorum(blockNumber);
    }

    function getVotes(address account, uint256 blockNumber)
        public
        view
        virtual
        override(IGovernorUpgradeable, GovernorVotesUpgradeable)
        returns (uint256)
    {
        return super.getVotes(account, blockNumber);
    }

    function state(uint256 proposalId)
        public
        view
        virtual
        override(GovernorUpgradeable, IGovernorUpgradeable, GovernorTimelockControlUpgradeable)
        returns (ProposalState)
    {
        return super.state(proposalId);
    }

    function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description)
        public
        virtual
        override(GovernorUpgradeable, GovernorCompatibilityBravoUpgradeable, IGovernorUpgradeable)
        returns (uint256)
    {
        return super.propose(targets, values, calldatas, description);
    }

    function proposalThreshold()
        public
        view
        virtual
        override(GovernorUpgradeable, GovernorSettingsUpgradeable)
        returns (uint256)
    {
        return super.proposalThreshold();
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(AccessControlUpgradeable, GovernorUpgradeable, IERC165Upgradeable, GovernorTimelockControlUpgradeable)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
        internal
        virtual
        override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
    {
        super._execute(proposalId, targets, values, calldatas, descriptionHash);
    }

    function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
        internal
        virtual
        override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
        returns (uint256)
    {
        return super._cancel(targets, values, calldatas, descriptionHash);
    }

    function _executor()
        internal
        view
        virtual
        override(GovernorUpgradeable, GovernorTimelockControlUpgradeable)
        returns (address)
    {
        return super._executor();
    }

    function _authorizeUpgrade(address newImplementation)
        internal
        virtual
        override
        onlyRole(UPGRADER_ROLE)
    {
        // solhint-disable-previous-line no-empty-blocks
    }
    uint256[50] private __gap;
}

Versions use:

"@nomiclabs/hardhat-ethers": "^2.0.5",
 "@nomiclabs/hardhat-truffle5": "^2.0.4",
"@nomiclabs/hardhat-waffle": "^2.0.2",
 "@nomiclabs/hardhat-web3": "^2.0.0",
"@openzeppelin/contracts-upgradeable": "^4.5.1",
"@openzeppelin/hardhat-upgrades": "^1.14.0",
"@openzeppelin/test-helpers": "^0.5.15",

TimelockController code:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.11;

import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/governance/TimelockControllerUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract SimplicyTimelockControllerUpgradeable is Initializable, AccessControlUpgradeable, TimelockControllerUpgradeable, UUPSUpgradeable {
    bool public initializerRan;
    bytes32 public constant UPGRADER_ROLE = keccak256("UPGRADER_ROLE");

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() initializer {
        // solhint-disable-previous-line no-empty-blocks
    }
    
    function initialize(
        uint256 minDelay,
        address[] memory proposers,
        address[] memory executors,
        address mOwner
    ) public initializer {
        __AccessControl_init();
        __TimelockController_init(minDelay, proposers, executors);
        __UUPSUpgradeable_init();
        __SimplicyTimelockController_init_unchained(minDelay, proposers, executors, mOwner);
    }

    // solhint-disable-next-line func-name-mixedcase
    function __SimplicyTimelockController_init_unchained(uint256, address[] memory, address[] memory, address mOwner) internal onlyInitializing {
        _grantRole(UPGRADER_ROLE, _msgSender());
        _grantRole(UPGRADER_ROLE, mOwner);
        initializerRan = true;
    }

    function version() pure external virtual returns(string memory) {
        return "1.0";
    }

    // The following functions are overrides required by Solidity.
    function _authorizeUpgrade(address newImplementation)
        internal
        onlyRole(UPGRADER_ROLE)
        override
        // solhint-disable-next-line no-empty-blocks
    {}
    uint256[50] private __gap;
}

9 posts were split to a new topic: Spurious issue from non-upgradeable Initializable.sol