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;
}