Hey everyone!
I may be missing something simple, but I'm having some trouble finding both documentation and methodology on the best way to implement a Transparent Proxy with upgradeAndCall
using OZ upgrades.
Context: I implemented an ERC721
using upgrades.deployProxy
, that roughly starts like:
contract Box is ERC721EnumerableUpgradeable {
function initialize(
uint16 royaltyBeeps_
) public initializer {
// Ensures ERC721
__ERC721_init("Box", "Box");
// Ensures ERC2981 standard (royalties)
_registerInterface(_INTERFACE_ID_ERC2981);
royaltyBeeps = royaltyBeeps_;
}
}
I now have a need to upgrade the contact and to add ownership capabilities:
contract BoxV2 is OwnableUpgradeable, Box {
function upgradeToV2(address owner_) external {
require(owner() == address(0), "upgradeToV2::Owner already set");
_transferOwnership(owner_);
}
}
As (from what I can tell) there is no simple mechanism to using OZ Upgrades with upgradeAndCall
, I define the following upgrade script:
export const deployUpgradeToken = async (hre: HardhatRuntimeEnvironment) => {
// Move the deployment back to the proper spot
cpOzDeployment(hre, "Box");
const boxV2 = await deployNonUpgradeableContract(hre, "BoxV2");
console.log("BoxV2 Implementation:", boxV2.address);
const data = (await hre.ethers.getContractFactory("BoxV2")).interface.encodeFunctionData(
"upgradeToV2",
[await boxV2.signer.getAddress()]
);
const { address: oldAddress } = getDeployment(hre.network.name, "Box");
const proxy = await hre.upgrades.admin.getInstance();
const c = await (await proxy.upgradeAndCall(oldAddress, boxV2.address, data)).wait();
console.log("Upgraded 'Box' to 'BoxV2'");
return c;
};
For context, cpOzDeployment
simple places the original output of upgrades.deployProxy
back in .openzeppelin
, and getDeployment
fetches the address of the original deployment for Box
.
However, after running everything through, boxv2.name()
and boxv2.symbol()
return an empty string, while, strangely, royaltyBeeps
(also defined in the original initialize
function) is defined.
Any thoughts on potential problems with my current pattern? Is there a recommended way to do this?
Thanks!