I have the following code for a Factory that creates instances of a contract that is Upgradeable . I understand that, in order to achieve this, one of the options I have is to use TransparentUpgradeableProxy
(actually, when I first deployed using Hardhat
-and it worked- this is what it was done under the hood):
Code to reproduce
SmartWalletFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "../multiwrap/SmartWallet.sol";
import "../proxy/SmartWalletProxy.sol";
contract SmartWalletFactory {
mapping(uint256 => address) private smartWallets;
SmartWalletProxy immutable proxy;
constructor(address _initialImpl) {
proxy = new SmartWalletProxy(_initialImpl);
}
function createSmartWallet(
uint256 _smartWalletId,
address _defaultAdmin,
string memory _name,
string memory _symbol,
string memory _contractURI,
address[] memory _trustedForwarders,
address _royaltyRecipient,
uint256 _royaltyBps
) public {
TransparentUpgradeableProxy smartWallet = new TransparentUpgradeableProxy(address(proxy), address(0), abi.encodeWithSelector(SmartWallet(payable(address(0))).initialize.selector, _defaultAdmin, _name, _symbol, _contractURI, _trustedForwarders, _royaltyRecipient, _royaltyBps));
smartWallets[_smartWalletId] = address(smartWallet);
}
}
SmartWalletProxy.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
contract SmartWalletProxy is Ownable {
TransparentUpgradeableProxy immutable proxy;
address public smartWalletImplementation;
constructor(address _initialImpl) {
proxy = new TransparentUpgradeableProxy(_initialImpl, address(0), "0x");
smartWalletImplementation = _initialImpl;
transferOwnership(tx.origin);
}
function upgrade(address _newImpl) public onlyOwner {
proxy.upgradeTo(_newImpl);
smartWalletImplementation = _newImpl;
}
}
So I first deploy SmartWallet
as my implementation contract and then I want to deploy the SmartWalletFactory
using the address of SmartWallet
as input.
The problem I am having is that I am getting the following error (using Remix
):
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Internal JSON-RPC error.
{
"code": 3,
"message": "execution reverted: Address: low-level delegate call failed",
"data": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000027416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c656400000000000000000000000000000000000000000000000000"
}
Environment
Remix
Does anybody know what this error could be? Thanks!