Hi, I want to test deployment of proxy contract (TransparentUpgradableProxy) with hardhat-upgrades plugin and see how defender takes care of the flow.
I must emphasise that non-proxy contract deployment flow works as expected (defender.deployProxy), problem is when I want to deploy proxy which is described below.
EDIT: It seems defender doesn't like ERC7201 to structure proxy storage, using standard "gap" approach worked as expected. Any solution to this ?
Environment
Hardhat: 2.22.17
metamask: 12.16.0
hardhat-upgrades: 3.9.0
Details
I setup only approval process for my EOA (for account I will sign the approval later in Defender), not upgrade approval process as I am not using it. Also I tested deploying non-proxy contract with similar script and it worked as expected.
Once I execute below script I get correct on terminal message with:
ACTION REQUIRED: Go to https://defender.openzeppelin.com/v2/#/deploy to submit the pending deployment.
The process will continue automatically when the pending deployment is completed.
Waiting for pending deployment of contract TransparentUpgradeableProxy with deployment id ddc725f8-9e8d-4560-a015-fd33a76ffde6...
Problem is when I connect my metamask wallet (for approval) and click "Deploy" in Defender I get big error log:
Sending deploy transaction failed, ensure your EOA is connected and provider operational: cannot estimate gas; transaction may fail or may require manual gas limit [ See: https://links.ethers.org/v5-errors-UNPREDICTABLE_GAS_LIMIT ] (reason="execution reverted", method="estimateGas", transaction=....
My metamask is connected and as I explained it worked when deploying non-proxy contract with defender.deployContract.
Any help would be appreciated.
Code to reproduce
Script:
const TestContract = await ethers.getContractFactory("TestContract");
const testContract = await defender.deployProxy(TestContract, {
kind: "transparent",
});
await testContract.waitForDeployment();
Proxy contract:
contract TestContract is OwnableUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.TestContract
struct TestContractStorage {
string _version;
}
// keccak256(abi.encode(uint256(keccak256("fija.storage.TestContract")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant TestContractStorageLocation =
0xca9ab86016606c0de0fd52d033f885973b1d29b412e722f528ec4c1b4b023800;
function _getTestContractStorage()
private
pure
returns (TestContractStorage storage $)
{
assembly {
$.slot := TestContractStorageLocation
}
}
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize() public initializer {
__Ownable_init(msg.sender);
TestContractStorage storage $ = _getTestContractStorage();
$._version = "V1";
}
function version() external view returns (string memory) {
TestContractStorage storage $ = _getTestContractStorage();
return $._version;
}
}