I am aware of this warning: https://docs.openzeppelin.com/upgrades-plugins/proxies#the-constructor-caveat
But I still want to define immutable
variables and initialize them through the constructor
. The purpose is to reduce the gas when accessing variables
I also learned that when deploying an upgradeable contract using the Upgrades plugin, I can pass constructor arguments.
function deployUUPSProxy(
string memory contractName,
bytes memory initializerData,
Options memory opts
) internal returns (address) {
address impl = deployImplementation(contractName, opts);
return Core.deploy("ERC1967Proxy.sol:ERC1967Proxy", abi.encode(impl, initializerData), opts);
}
In the Options
struct:
/*
* Encoded constructor arguments for the implementation contract.
* Note that these are different from initializer arguments, and will be used in the deployment of the implementation contract itself.
* Can be used to initialize immutable variables.
*/
bytes constructorData;
But when I tested it, I got an error.
Code to reproduce
Options memory opts;
opts.constructorData = abi.encode(addr01, addr02, addr03);
address proxy = Upgrades.deployUUPSProxy(
"MyContract.sol",
abi.encodeCall(MyContract.initialize, ()),
opts
);
[FAIL: revert: Upgrade safety validation failed:
✘ src/MyContract.sol:MyContract
src/MyContract.sol:43: Contract `MyContract` has a constructor
Define an initializer instead
https://zpl.in/upgrades/error-001
FAILED] setUp() (gas: 0)
Encountered a total of 1 failing tests, 0 tests succeeded
Environment
"name": "@openzeppelin/foundry-upgrades",
"version": "0.4.0",
"name": "openzeppelin-solidity",
"description": "Secure Smart Contract library for Solidity",
"version": "5.2.0",
"name": "forge-std",
"version": "1.9.6",