diff --git a/contracts/TxPermissionHbbft.sol b/contracts/TxPermissionHbbft.sol index 9b40a34c..4806cb03 100644 --- a/contracts/TxPermissionHbbft.sol +++ b/contracts/TxPermissionHbbft.sol @@ -154,6 +154,10 @@ contract TxPermissionHbbft is Initializable, OwnableUpgradeable, ITxPermission { blockGasLimit = _value; } + function setConnectivityTracker(address _connectivityTracker) external onlyOwner { + connectivityTracker = IConnectivityTrackerHbbft(_connectivityTracker); + } + // =============================================== Getters ======================================================== /// @dev Returns the contract's name recognizable by node's engine. diff --git a/contracts/base/BlockRewardHbbftBase.sol b/contracts/base/BlockRewardHbbftBase.sol index abedaacc..234460b0 100644 --- a/contracts/base/BlockRewardHbbftBase.sol +++ b/contracts/base/BlockRewardHbbftBase.sol @@ -705,5 +705,5 @@ contract BlockRewardHbbftBase is Initializable, OwnableUpgradeable, IBlockReward * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ - uint256[48] private __gap; + uint256[49] private __gap; } diff --git a/scripts/make_spec_hbbft.js b/scripts/make_spec_hbbft.js deleted file mode 100755 index 78245d9e..00000000 --- a/scripts/make_spec_hbbft.js +++ /dev/null @@ -1,405 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const Web3 = require('web3'); -const web3 = new Web3(); -const utils = require('./utils/utils'); -const fp = require('lodash/fp'); -const assert = require('assert'); - -const VALIDATOR_SET_CONTRACT = '0x1000000000000000000000000000000000000001'; -const BLOCK_REWARD_CONTRACT = '0x2000000000000000000000000000000000000001'; -const RANDOM_CONTRACT = '0x3000000000000000000000000000000000000001'; -const STAKING_CONTRACT = '0x1100000000000000000000000000000000000001'; -const PERMISSION_CONTRACT = '0x4000000000000000000000000000000000000001'; -const CERTIFIER_CONTRACT = '0x5000000000000000000000000000000000000001'; -const KEY_GEN_HISTORY_CONTRACT = '0x7000000000000000000000000000000000000001'; - - - -main(); - -async function main() { - let useUpgradeProxy = true; - - const init_data_file = process.argv[2]; - assert(init_data_file, "Path to contract initialization file required as first argument!"); - console.log(`Using init_data_file: ${init_data_file}`); - - if (process.argv[3] !== undefined) { - useUpgradeProxy = process.argv[3] == 'true'; - console.log(`parsed ${process.argv[3]} as ${useUpgradeProxy}`); - } - - const rawdata = fs.readFileSync(init_data_file); - const init_data = JSON.parse(rawdata); - - const networkName = process.env.NETWORK_NAME; - const networkID = process.env.NETWORK_ID; - const owner = process.env.OWNER.trim(); - let initialValidators = init_data.validators; - for (let i = 0; i < initialValidators.length; i++) { - initialValidators[i] = initialValidators[i].trim(); - } - let stakingAddresses = init_data.staking_addresses; - for (let i = 0; i < stakingAddresses.length; i++) { - stakingAddresses[i] = stakingAddresses[i].trim(); - } - const stakingEpochDuration = process.env.STAKING_EPOCH_DURATION; - const stakeWithdrawDisallowPeriod = process.env.STAKE_WITHDRAW_DISALLOW_PERIOD; - const stakingTransitionWindowLength = process.env.STAKING_TRANSITION_WINDOW_LENGTH; - const stakingMinStakeForValidatorString = process.env.STAKING_MIN_STAKE_FOR_VALIDATOR; - const stakingMinStakeForDelegatorString = process.env.STAKING_MIN_STAKE_FOR_DELEGATOR; - - let stakingMinStakeForValidator = web3.utils.toWei('1', 'ether'); - if (stakingMinStakeForValidatorString) { - stakingMinStakeForValidator = web3.utils.toWei(stakingMinStakeForValidatorString, 'ether'); - } - - let stakingMinStakeForDelegator = web3.utils.toWei('1', 'ether'); - if (stakingMinStakeForDelegatorString) { - stakingMinStakeForDelegator = web3.utils.toWei(stakingMinStakeForDelegatorString, 'ether'); - } - - let stakingMaxStakeForValidator = web3.utils.toWei('50000', 'ether'); - - let stakingParams = [stakingMinStakeForDelegator, stakingMinStakeForValidator, stakingMaxStakeForValidator, stakingEpochDuration, stakingTransitionWindowLength, stakeWithdrawDisallowPeriod]; - - let publicKeys = init_data.public_keys; - for (let i = 0; i < publicKeys.length; i++) { - publicKeys[i] = publicKeys[i].trim(); - } - let publicKeysSplit = fp.flatMap(x => [x.substring(0, 66), '0x' + x.substring(66, 130)])(publicKeys); - - let internetAddresses = init_data.ip_addresses; - for (let i = 0; i < internetAddresses.length; i++) { - internetAddresses[i] = internetAddresses[i].trim(); - } - - const contracts = [ - 'AdminUpgradeabilityProxy', - 'BlockRewardHbbft', - 'CertifierHbbft', - 'InitializerHbbft', - 'KeyGenHistory', - 'RandomHbbft', - 'Registry', - 'StakingHbbft', - 'TxPermissionHbbft', - 'ValidatorSetHbbft' - ]; - - let spec = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'templates', 'spec_hbbft.json'), 'UTF-8')); - - spec.name = networkName; - spec.params.networkID = networkID; - - const minimumBlockTime = Number.parseInt(process.env.MINIMUM_BLOCK_TIME); - if (minimumBlockTime > 0) { - spec.engine.hbbft.params.minimumBlockTime = minimumBlockTime; - } - - const maximumBlockTime = Number.parseInt(process.env.MAXIMUM_BLOCK_TIME); - if (maximumBlockTime > 0) { - spec.engine.hbbft.params.maximumBlockTime = maximumBlockTime; - } - - let contractsCompiled = {}; - for (let i = 0; i < contracts.length; i++) { - const contractName = contracts[i]; - let realContractName = contractName; - let dir = 'contracts/'; - - if (contractName == 'AdminUpgradeabilityProxy') { - dir = 'contracts/upgradeability/'; - } - // else if (contractName == 'StakingHbbft' && erc20Restricted) { - // realContractName = 'StakingHbbftCoins'; - // dir = 'contracts/base/'; - // } else if (contractName == 'BlockRewardHbbft' && erc20Restricted) { - // realContractName = 'BlockRewardHbbftCoins'; - // dir = 'contracts/base/'; - // } - - console.log(`Compiling ${contractName}...`); - const compiled = await compile( - path.join(__dirname, '..', dir), - realContractName - ); - contractsCompiled[contractName] = compiled; - } - - const storageProxyCompiled = contractsCompiled['AdminUpgradeabilityProxy']; - let contract = new web3.eth.Contract(storageProxyCompiled.abi); - let deploy; - - if (useUpgradeProxy) { - - // Build ValidatorSetHbbft contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x1000000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - - spec.accounts[VALIDATOR_SET_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - - spec.accounts['0x1000000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['ValidatorSetHbbft'].bytecode - }; - - // Build StakingHbbft contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x1100000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - - spec.accounts[STAKING_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - spec.accounts['0x1100000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['StakingHbbft'].bytecode - }; - - // Build BlockRewardHbbft contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x2000000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - spec.accounts[BLOCK_REWARD_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - - spec.engine.hbbft.params.blockRewardContractAddress = BLOCK_REWARD_CONTRACT; - - // spec.engine.hbbft.params.blockRewardContractTransition = 0; - spec.accounts['0x2000000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['BlockRewardHbbft'].bytecode - }; - - // Build RandomHbbft contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x3000000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - spec.accounts[RANDOM_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - spec.accounts['0x3000000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['RandomHbbft'].bytecode - }; - //spec.engine.hbbft.params.randomnessContractAddress = RANDOM_CONTRACT; - - // Build TxPermission contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x4000000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - spec.accounts[PERMISSION_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - spec.params.transactionPermissionContract = PERMISSION_CONTRACT; - spec.params.transactionPermissionContractTransition = '0x0'; - - spec.accounts['0x4000000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['TxPermissionHbbft'].bytecode - }; - - // Build Certifier contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x5000000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - spec.accounts[CERTIFIER_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - spec.accounts['0x5000000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['CertifierHbbft'].bytecode - }; - - // Build KeyGenHistory contract - deploy = await contract.deploy({data: '0x' + storageProxyCompiled.bytecode, arguments: [ - '0x7000000000000000000000000000000000000000', // implementation address - owner, - [] - ]}); - - spec.accounts[KEY_GEN_HISTORY_CONTRACT] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - - - spec.accounts['0x7000000000000000000000000000000000000000'] = { - balance: '0', - constructor: '0x' + contractsCompiled['KeyGenHistory'].bytecode - }; - - // Build Registry contract - contract = new web3.eth.Contract(contractsCompiled['Registry'].abi); - deploy = await contract.deploy({data: '0x' + contractsCompiled['Registry'].bytecode, arguments: [ - CERTIFIER_CONTRACT, - owner - ]}); - spec.accounts['0x6000000000000000000000000000000000000000'] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - spec.params.registrar = '0x6000000000000000000000000000000000000000'; - - - } - else { // not useUpgradeProxy - - spec.accounts[VALIDATOR_SET_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['ValidatorSetHbbft'].bytecode - }; - - spec.accounts[STAKING_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['StakingHbbft'].bytecode - }; - - spec.accounts[BLOCK_REWARD_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['BlockRewardHbbft'].bytecode - }; - - spec.engine.hbbft.params.blockRewardContractAddress = BLOCK_REWARD_CONTRACT; - - spec.accounts[RANDOM_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['RandomHbbft'].bytecode - }; - - spec.accounts[PERMISSION_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['TxPermissionHbbft'].bytecode - }; - - spec.params.transactionPermissionContract = PERMISSION_CONTRACT; - spec.params.transactionPermissionContractTransition = '0x0'; - - spec.accounts[CERTIFIER_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['CertifierHbbft'].bytecode - }; - - // Build Registry contract - contract = new web3.eth.Contract(contractsCompiled['Registry'].abi); - - deploy = await contract.deploy({data: '0x' + contractsCompiled['Registry'].bytecode, arguments: [ - CERTIFIER_CONTRACT, - owner - ]}); - - spec.accounts['0x6000000000000000000000000000000000000000'] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - spec.params.registrar = '0x6000000000000000000000000000000000000000'; - - spec.accounts[KEY_GEN_HISTORY_CONTRACT] = { - balance: '0', - constructor: '0x' + contractsCompiled['KeyGenHistory'].bytecode - }; - } - - - // console.log(`InitializerHbbft constructor arguments: - // contracts ${[ // _contracts - // VALIDATOR_SET_CONTRACT, - // BLOCK_REWARD_CONTRACT, - // RANDOM_CONTRACT, - // STAKING_CONTRACT, - // PERMISSION_CONTRACT, - // CERTIFIER_CONTRACT, - // KEY_GEN_HISTORY_CONTRACT - // ]}, - // owner ${owner}, - // initialValidators ${initialValidators}, - // stakingAddresses ${stakingAddresses}, - // stakingParams ${stakingParams}, - // publicKeysSplit ${publicKeysSplit}, - // internetAddresses ${internetAddresses}, - // init_data.parts ${init_data.parts}, - // init_data.acks ${init_data.acks}, - // ethToWei ${ethToWei}` - // ); - - - //console.log('const partsRaw = ', JSON.stringify(init_data.parts)); - //console.log('const acks = ', JSON.stringify(init_data.acks)); - - //fixing parts. - //there is a bug in web3-eth-abi handling byte arrays, - //but buffer work fine. - const newParts = []; - init_data.parts.forEach(x => { - newParts.push( Buffer.from(x)); - }); - - init_data.parts = newParts; - - // Build InitializerHbbft contract - contract = new web3.eth.Contract(contractsCompiled['InitializerHbbft'].abi); - deploy = await contract.deploy({data: '0x' + contractsCompiled['InitializerHbbft'].bytecode, arguments: [ - [ // _contracts - VALIDATOR_SET_CONTRACT, - BLOCK_REWARD_CONTRACT, - RANDOM_CONTRACT, - STAKING_CONTRACT, - PERMISSION_CONTRACT, - CERTIFIER_CONTRACT, - KEY_GEN_HISTORY_CONTRACT - ], - owner, // _owner - initialValidators, // _miningAddresses - stakingAddresses, // _stakingAddresses - stakingParams, - publicKeysSplit, - internetAddresses, - init_data.parts, - init_data.acks - ]}); - - spec.accounts['0xFF00000000000000000000000000000000000000'] = { - balance: '0', - constructor: await deploy.encodeABI() - }; - - console.log('Using the following initial validators: ' + initialValidators); - - console.log('Saving spec_hbbft.json file ...'); - fs.writeFileSync(path.join(__dirname, '..', 'spec_hbbft.json'), JSON.stringify(spec, null, ' '), 'UTF-8'); - console.log('Done'); -} - -async function compile(dir, contractName) { - const compiled = await utils.compile(dir, contractName); - const abiFile = `abis/${contractName}.json`; - console.log(`saving abi to ${abiFile}`); - fs.writeFileSync(abiFile, JSON.stringify(compiled.abi, null, 2), 'UTF-8'); - return {abi: compiled.abi, bytecode: compiled.evm.bytecode.object}; -} - -// NETWORK_NAME=DPoSChain NETWORK_ID=101 OWNER=0x1092a1E3A3F2FB2024830Dd12064a4B33fF8EbAe INITIAL_VALIDATORS=0xeE385a1df869A468883107B0C06fA8791b28A04f,0x71385ae87c4b93db96f02f952be1f7a63f6057a6,0x190ec582090ae24284989af812f6b2c93f768ecd STAKING_ADDRESSES=0xe5aa2949ac94896bb2c5c75d9d5a88eb9f7c6b59,0x63a9344ae66c1f26d400b3ea4750a709c3aa6cfa,0xa5f6858d6254329a67cddab2dc04d795c5257709 STAKING_EPOCH_DURATION=120954 STAKE_WITHDRAW_DISALLOW_PERIOD=4320 PUBLIC_KEYS=0x52be8f332b0404dff35dd0b2ba44993a9d3dc8e770b9ce19a849dff948f1e14c57e7c8219d522c1a4cce775adbee5330f222520f0afdabfdb4a4501ceeb8dcee,0x99edf3f524a6f73e7f5d561d0030fc6bcc3e4bd33971715617de7791e12d9bdf6258fa65b74e7161bbbf7ab36161260f56f68336a6f65599dc37e7f2e397f845,0xa255fd7ad199f0ee814ee00cce44ef2b1fa1b52eead5d8013ed85eade03034ae4c246658946c2e1d7ded96394a1247fb4d093c32474317ae388e8d25692a0f56 IP_ADDRESSES=0x11111111111111111111111111111111,0x22222222222222222222222222222222,0x33333333333333333333333333333333 node scripts/make_spec_hbbft.js diff --git a/scripts/make_spec_hbbft_example.sh b/scripts/make_spec_hbbft_example.sh deleted file mode 100755 index 740976e6..00000000 --- a/scripts/make_spec_hbbft_example.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -export NETWORK_NAME="DPoSChain" -export NETWORK_ID="777001" -export OWNER="0x0102Ac5315c1Bd986A1da4F1FE1b4BCA36Fa4667" -export STAKING_EPOCH_DURATION="60" -export STAKING_TRANSITION_WINDOW_LENGTH="15" -export STAKE_WITHDRAW_DISALLOW_PERIOD="30" - -# node ../openethereum/ethcore/engines/hbbft/hbbft_config_generator/keygen_history.json -node scripts/make_spec_hbbft.js ../openethereum/ethcore/engines/hbbft/hbbft_config_generator/keygen_history.json diff --git a/scripts/upgrades/alpha2/2023_10_01_upgrade.ts b/scripts/upgrades/alpha2/2023_10_01_upgrade.ts index f3735130..9153b171 100644 --- a/scripts/upgrades/alpha2/2023_10_01_upgrade.ts +++ b/scripts/upgrades/alpha2/2023_10_01_upgrade.ts @@ -1,19 +1,7 @@ -import { ethers, upgrades } from "hardhat"; +import { ethers } from "hardhat"; +import { upgradeProxy } from "../upgrades"; -export async function upgradeProxy(contractName: string, proxyAddress: string, timeoutSec: number) { - const contractFactory = await ethers.getContractFactory(contractName); - const contract = await upgrades.upgradeProxy(proxyAddress, contractFactory); - - await new Promise((r) => setTimeout(r, timeoutSec * 1000)); - - const newImplementationAddress = await upgrades.erc1967.getImplementationAddress(proxyAddress); - - console.log("Proxy upgraded: ", proxyAddress); - console.log("New implementation address: ", newImplementationAddress); - - return contract; -} async function deploy() { const [deployer] = await ethers.getSigners(); diff --git a/scripts/upgrades/alpha2/2023_10_02_set_staking_transaction_timeframe.ts b/scripts/upgrades/alpha2/2023_10_02_set_staking_transaction_timeframe.ts index 75d0a31c..507c0745 100644 --- a/scripts/upgrades/alpha2/2023_10_02_set_staking_transaction_timeframe.ts +++ b/scripts/upgrades/alpha2/2023_10_02_set_staking_transaction_timeframe.ts @@ -1,4 +1,4 @@ -import { ethers, upgrades } from "hardhat"; +import { ethers } from "hardhat"; // second step of contract upgade: // setStakingTransitionTimeframeLength to 300 seconds. diff --git a/scripts/upgrades/alpha2/2023_12_10_deploy_connectivity_checker.ts b/scripts/upgrades/alpha2/2023_12_10_deploy_connectivity_checker.ts new file mode 100644 index 00000000..01e84fbc --- /dev/null +++ b/scripts/upgrades/alpha2/2023_12_10_deploy_connectivity_checker.ts @@ -0,0 +1,47 @@ +import { ethers, upgrades } from "hardhat"; +import { ConnectivityTrackerHbbft } from "../../../src/types/contracts/ConnectivityTrackerHbbft"; +import { InitialContractsConfiguration } from "../../../tasks/types"; +import { upgradeProxy } from "../upgrades"; + + +async function doUpgrade() { + const [deployer] = await ethers.getSigners(); + const minReportAgeBlocks = 10; + const timeoutSec = 10; + + const contracts = InitialContractsConfiguration.fromFile("initial-contracts.json"); + + console.log("executing from account: ", deployer.address); + + for (const conractName of ["ValidatorSetHbbft", "BlockRewardHbbft", "TxPermissionHbbft"]) { + console.log("upgrading contract ", conractName); + await upgradeProxy(deployer, conractName, contracts.getAddress(conractName)!, timeoutSec); + } + + console.log("deploying ConnectivityTracker contract") + const ConnectivityTrackerHbbftFactory = await ethers.getContractFactory("ConnectivityTrackerHbbft"); + const connectivityTrackerHbbft = await upgrades.deployProxy( + ConnectivityTrackerHbbftFactory, + [ + deployer.address, // address _contractOwner, + contracts.getAddress("ValidatorSetHbbft")!, // address _validatorSetContract, + contracts.getAddress("StakingHbbft")!, // address _stakingContract, + contracts.getAddress("BlockRewardHbbft")!, // address _blockRewardContract, + minReportAgeBlocks, // uint256 _minReportAgeBlocks + ], + { initializer: 'initialize' } + ) as ConnectivityTrackerHbbft; + + await connectivityTrackerHbbft.deployed(); + + for (const contractName of ["BlockRewardHbbft", "TxPermissionHbbft"]) { + console.log("Set ConnectivityTracker address in ", contractName); + + const factory = await ethers.getContractFactory(contractName); + const _contract = factory.attach(contracts.getAddress(contractName)!); + + await _contract.connect(deployer).setConnectivityTracker(connectivityTrackerHbbft.address); + } +} + +doUpgrade(); diff --git a/scripts/upgrades/alpha2/2023_12_6_upgrade.ts b/scripts/upgrades/alpha2/2023_12_6_upgrade.ts index 83bf6802..97d8204d 100644 --- a/scripts/upgrades/alpha2/2023_12_6_upgrade.ts +++ b/scripts/upgrades/alpha2/2023_12_6_upgrade.ts @@ -1,21 +1,9 @@ -import { ethers, upgrades } from "hardhat"; +import { ethers } from "hardhat"; +import { upgradeProxy } from "../upgrades"; -export async function upgradeProxy(contractName: string, proxyAddress: string, timeoutSec: number) { - const contractFactory = await ethers.getContractFactory(contractName); - const contract = await upgrades.upgradeProxy(proxyAddress, contractFactory); - - await new Promise((r) => setTimeout(r, timeoutSec * 1000)); - - const newImplementationAddress = await upgrades.erc1967.getImplementationAddress(proxyAddress); - - console.log("Proxy upgraded: ", proxyAddress); - console.log("New implementation address: ", newImplementationAddress); - - return contract; -} async function deploy() { const [deployer] = await ethers.getSigners(); diff --git a/scripts/upgrades/upgrades.ts b/scripts/upgrades/upgrades.ts new file mode 100644 index 00000000..633e2aa9 --- /dev/null +++ b/scripts/upgrades/upgrades.ts @@ -0,0 +1,18 @@ +import { ethers, upgrades } from "hardhat"; +import { getImplementationAddress } from '@openzeppelin/upgrades-core'; +import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; + +export async function upgradeProxy(caller: SignerWithAddress, contractName: string, proxyAddress: string, timeoutSec: number) { + const contractFactory = await ethers.getContractFactory(contractName, caller); + + const contract = await upgrades.upgradeProxy(proxyAddress, contractFactory); + + await new Promise((r) => setTimeout(r, timeoutSec * 1000)); + + const newImplementationAddress = await getImplementationAddress(ethers.provider, proxyAddress); + + console.log("Proxy upgraded: ", proxyAddress); + console.log("New implementation address: ", newImplementationAddress); + + return contract; +} \ No newline at end of file