Hello!
Please forgive me if I have missed something basic! I've created an upgradable ERC20 using the Wizard, which I have tested extensively on Rinkeby including upgrading, and so I have now deployed to the Ethereum mainnet.
However, on deploy (using the exact same code as used on Rinkeby) the Implementation was deployed and a ProxyAdmin. I was expecting an Implementation and a TransparentUpgradeableProxy to be deployed. The deploy also hasn't initialized my implementation of the first deploy. On Rinkeby I would run the deploy script, run the script to verify the implementation, then verify the TransparentUpgradeableProxy in etherscan.
How do I deploy a TransparentUpgradeableProxy for the implementation, or how to initialize, or have I missed a step?
Thank you kindly for your future responses!
Code to reproduce
// echo.sol
// SPDX-License-Identifier: agpl-3.0
pragma solidity ^0.8.2;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20BurnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
contract Echo is Initializable, ERC20Upgradeable, ERC20BurnableUpgradeable, PausableUpgradeable, OwnableUpgradeable, UUPSUpgradeable {
function initialize() initializer public {
__ERC20_init("Echo", "ECHO");
__ERC20Burnable_init();
__Pausable_init();
__Ownable_init();
__UUPSUpgradeable_init();
_mint(msg.sender, 1000000000 * 10 ** decimals());
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
function version() pure virtual public returns (string memory) {
return "1.0.0";
}
function _beforeTokenTransfer(address from, address to, uint256 amount)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(from, to, amount);
}
function _authorizeUpgrade(address newImplementation)
internal
onlyOwner
override
{}
}
// deploy-echo.js
const { ethers, upgrades } = require('hardhat');
async function main () {
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with the account:", deployer.address);
const gasBefore = await deployer.getBalance();
console.log("Account balance:", ethers.utils.formatEther(gasBefore));
const Echo = await ethers.getContractFactory('Echo');
console.log('Deploying Echo...');
const echo = await upgrades.deployProxy(Echo, { initializer: 'initialize' });
await echo.deployed();
console.log('Echo Proxy deployed to:', echo.address);
const implementationAddress = await upgrades.erc1967.getImplementationAddress(echo.address);
console.log('Echo Implementation deployed to:', implementationAddress);
const gasAfter = await deployer.getBalance();
console.log("Account balance:", ethers.utils.formatEther(gasAfter));
console.log("Gas cost:", ethers.utils.formatEther(gasBefore - gasAfter));
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Environment
Deployed by calling:
npx hardhat run scripts/deploy-echo.js --network mainnet