UNPKG

@gooddollar/goodprotocol

Version:
854 lines (791 loc) 30.1 kB
/** * Mainnet: * 0. deploy nameService * 1. deploy votingmachine + reputation * 2. deploy Reserve, MarketMaker * 3. deploy FundManager * 4. deploy ubi staking contracts */ import { network, ethers, upgrades, run } from "hardhat"; import { isFunction, get, omitBy } from "lodash"; import { getImplementationAddress } from "@openzeppelin/upgrades-core"; import pressAnyKey from "press-any-key"; import { AaveStakingFactory, CompoundStakingFactory, ProxyFactory1967 } from "../../types"; import SchemeRegistrarABI from "@gooddollar/goodcontracts/build/contracts/SchemeRegistrar.json"; import releaser from "../releaser"; import { GReputation, SchemeRegistrar, CompoundVotingMachine, ProtocolUpgrade, ProtocolUpgradeFuse, NameService } from "../../types"; import { getFounders } from "../getFounders"; import OldDAO from "../../releases/olddao.json"; import ProtocolSettings from "../../releases/deploy-settings.json"; import { keccak256 } from "ethers/lib/utils"; let GAS_SETTINGS: any = { maxPriorityFeePerGas: ethers.utils.parseUnits("1", "gwei"), maxFeePerGas: ethers.utils.parseUnits("50", "gwei"), gasLimit: 30000000 }; let totalGas = 0; const gasUsage = {}; const countTotalGas = async (tx, name) => { let res = tx; if (tx.deployTransaction) tx = tx.deployTransaction; if (tx.wait) res = await tx.wait(); if (res.gasUsed) { totalGas += parseInt(res.gasUsed); gasUsage[name] = gasUsage[name] || 0; gasUsage[name] += parseInt(res.gasUsed); } else console.log("no gas data", { res, tx }); }; console.log({ network: network.name, upgrade: process.env.UPGRADE }); const { name } = network; export const main = async (networkName = name, isPerformUpgrade = true, olddao?): Promise<{ [key: string]: any }> => { const isProduction = networkName.startsWith("production"); if (isProduction && networkName.includes("mainnet")) { GAS_SETTINGS.gasLimit = 6000000; GAS_SETTINGS.maxFeePerGas = ethers.utils.parseUnits("80", "gwei"); } else if (network.config.chainId === 122) { //case we are on fusefuse GAS_SETTINGS = { gasLimit: 6000000, gasPrice: ethers.utils.parseUnits("1", "gwei") }; } else if (network.config.chainId === 3 || network.config.chainId === 42) { GAS_SETTINGS = { maxPriorityFeePerGas: ethers.utils.parseUnits("1", "gwei"), maxFeePerGas: ethers.utils.parseUnits("10", "gwei"), gasLimit: 6000000 }; } const isDappTest = networkName.startsWith("dapptest"); const isTest = network.name === "hardhat" || isDappTest; const isCoverage = process.env.CODE_COVERAGE; const isDevelop = !isProduction; const isMainnet = networkName.includes("mainnet"); let protocolSettings = { ...ProtocolSettings["default"], ...ProtocolSettings[networkName] }; console.log(`networkName ${networkName}`, { isTest, isDappTest, isCoverage, isMainnet, isDevelop }); const dao = olddao || OldDAO[networkName]; const fse = require("fs-extra"); const ProtocolAddresses = await fse.readJson("releases/deployment.json"); const newfusedao = await ProtocolAddresses[networkName.replace(/\-mainnet/, "")]; const newdao = ProtocolAddresses[networkName] || {}; let [root, proxyDeployer] = await ethers.getSigners(); let avatar = dao.Avatar; let controller = dao.Controller; let repStateId = isMainnet ? "fuse" : "rootState"; const founders = await getFounders(networkName); console.log(`root: ${root.address} founders: ${founders.map(_ => _.address)}`); const compoundTokens = [ { name: "cdai", address: (protocolSettings.compound != undefined && protocolSettings.compound.cdai) || dao.cDAI, usdOracle: (protocolSettings.compound != undefined && protocolSettings.compound.daiUsdOracle) || dao.DAIUsdOracle, compUsdOracle: (protocolSettings.compound != undefined && protocolSettings.compound.compUsdOracle) || dao.COMPUsdOracle, swapPath: [] } ]; const aaveTokens = [ { name: "usdc", address: protocolSettings.aave.usdc || dao.USDC, usdOracle: protocolSettings.aave.usdcUsdOracle || dao.USDCUsdOracle, aaveUsdOracle: protocolSettings.aave.aaveUsdOracle || dao.AAVEUsdOracle, swapPath: [get(protocolSettings, "aave.usdc", dao.USDC), get(protocolSettings, "compound.dai", dao.DAI)] } ]; let release: { [key: string]: any } = newdao; const toDeployUpgradable = [ { network: "mainnet", name: "NameService", args: [ controller, [ "CONTROLLER", "AVATAR", "IDENTITY", "GOODDOLLAR", "CONTRIBUTION_CALCULATION", "BANCOR_FORMULA", "DAI", "CDAI", "COMP", "BRIDGE_CONTRACT", "UNISWAP_ROUTER", "GAS_PRICE_ORACLE", "DAI_ETH_ORACLE", "ETH_USD_ORACLE" ].map(_ => ethers.utils.keccak256(ethers.utils.toUtf8Bytes(_))), [ controller, avatar, dao.Identity, dao.GoodDollar, dao.Contribution, protocolSettings.bancor || dao.BancorFormula, get(protocolSettings, "compound.dai", dao.DAI), get(protocolSettings, "compound.cdai", dao.cDAI), get(protocolSettings, "compound.comp", dao.COMP), dao.ForeignBridge, protocolSettings.uniswapRouter || dao.UniswapRouter, !isMainnet || dao.GasPriceOracle || protocolSettings.chainlink.gasPrice, //should fail if missing only on mainnet !isMainnet || dao.DAIEthOracle || protocolSettings.chainlink.dai_eth, !isMainnet || dao.ETHUsdOracle || protocolSettings.chainlink.eth_usd ] ] }, { network: "fuse", name: "NameService", args: [ controller, ["CONTROLLER", "AVATAR", "IDENTITY", "GOODDOLLAR", "BRIDGE_CONTRACT"].map(_ => ethers.utils.keccak256(ethers.utils.toUtf8Bytes(_)) ), [controller, avatar, dao.Identity, dao.GoodDollar, dao.HomeBridge] ] }, { network: "both", name: "GReputation", initializer: "initialize(address, string, bytes32, uint256)", args: [ () => get(release, "NameService", newdao.NameService), repStateId, protocolSettings.governance.gdaoAirdrop, //should fail on real deploy if not set protocolSettings.governance.gdaoTotalSupply //should fail on real deploy if not set ] }, { network: "both", name: "CompoundVotingMachine", args: [ () => get(release, "NameService", newdao.NameService), protocolSettings.governance.proposalVotingPeriod, protocolSettings.governance.guardian || root.address, () => get(release, "GReputation", newdao.GReputation) ] }, { network: "mainnet", name: "GoodMarketMaker", args: [ () => get(release, "NameService", newdao.NameService), protocolSettings.expansionRatio.nom, protocolSettings.expansionRatio.denom ] }, { network: "mainnet", name: "GoodReserveCDai", initializer: "initialize(address, bytes32)", args: [() => get(release, "NameService", newdao.NameService), protocolSettings.gdxAirdrop] }, { network: "mainnet", name: "ExchangeHelper", initializer: "initialize(address)", args: [() => get(release, "NameService", newdao.NameService)] }, { network: "mainnet", name: "GoodFundManager", args: [() => get(release, "NameService", newdao.NameService)] }, { network: "mainnet", name: "StakersDistribution", args: [() => get(release, "NameService", newdao.NameService)] }, { network: "fuse", name: "ClaimersDistribution", args: [() => get(release, "NameService", newdao.NameService)] }, { network: "fuse", name: "GovernanceStaking", args: [() => get(release, "NameService", newdao.NameService)], isUpgradable: false }, { network: "fuse", name: "UBIScheme", initializer: "initialize(address, address, uint256)", args: [() => get(release, "NameService", newdao.NameService), dao.FirstClaimPool, 14] }, { network: "mainnet", name: "ProtocolUpgrade", args: [dao.Controller, root.address], isUpgradable: false, initializer: null }, { network: "fuse", name: "ProtocolUpgradeFuse", args: [dao.Controller, root.address], isUpgradable: false }, { network: "mainnet", name: "UniswapV2SwapHelper", args: [], isUpgradable: false }, { network: "mainnet", name: "CompoundStakingFactory", args: [], isUpgradable: false, libraries: ["UniswapV2SwapHelper"] }, { network: "mainnet", name: "AaveStakingFactory", args: [], isUpgradable: false, libraries: ["UniswapV2SwapHelper"] } ]; let proxyFactory: ProxyFactory1967; const getProxyFactory = async () => { if (isDevelop === false && newdao.ProxyFactory) { return (proxyFactory = (await ethers.getContractAt( "ProxyFactory1967", newdao.ProxyFactory )) as unknown as ProxyFactory1967); } else { console.info("deploying ProxyFactory1967", isDevelop, newdao.ProxyFactory); // await pressAnyKey(); const pf = await (await ethers.getContractFactory("ProxyFactory1967", root)).deploy(GAS_SETTINGS); await pf.deployed(); await releaser({ ProxyFactory: pf.address }, networkName, "deployment", false); return (proxyFactory = pf.connect(root) as unknown as ProxyFactory1967); } }; const deployDeterministic = async (contract, args: any[], factoryOpts = {}) => { try { const Contract = await ethers.getContractFactory(contract.name, factoryOpts); const salt = ethers.BigNumber.from(keccak256(ethers.utils.toUtf8Bytes(contract.name))); if (contract.isUpgradable !== false) { if (isCoverage) { console.log("Deploying:", contract.name, "using proxy"); //coverage has large contracts doesnt work with proxy factory const tx = await upgrades.deployProxy(Contract, args, { initializer: contract.initializer, kind: "uups", unsafeAllowLinkedLibraries: true }); await countTotalGas(tx, contract.name); return tx; } console.log("Deploying:", contract.name, "using proxyfactory"); const encoded = Contract.interface.encodeFunctionData(contract.initializer || "initialize", args); const tx = await Contract.deploy(GAS_SETTINGS); const impl = await tx.deployed(); await countTotalGas(tx, contract.name); const tx2 = await proxyFactory.deployProxy(salt, impl.address, encoded, GAS_SETTINGS); await countTotalGas(tx2, contract.name); const deployTx = await tx2.wait().catch(e => console.error("failed to deploy proxy, assuming it exists...", e)); return ethers.getContractAt( contract.name, await proxyFactory["getDeploymentAddress(uint256,address)"](salt, root.address) ); } else { //for some reason deploying with link library via proxy doesnt work on hardhat test env if (isTest === false) { console.log("Deploying:", contract.name, "using proxyfactory code"); const constructor = Contract.interface.encodeDeploy(args); const bytecode = ethers.utils.solidityPack(["bytes", "bytes"], [Contract.bytecode, constructor]); const deployTx = await (await proxyFactory.deployCode(salt, bytecode, GAS_SETTINGS)).wait(); return ethers.getContractAt( contract.name, await proxyFactory["getDeploymentAddress(uint256,address,bytes32)"](salt, root.address, keccak256(bytecode)) ); } else { console.log("Deploying:", contract.name, "using regular"); const tx = await Contract.deploy(...args, GAS_SETTINGS); await countTotalGas(tx, contract.name); const impl = await tx.deployed(); return impl; } } } catch (e) { console.log("Failed deploying contract:", { contract }); throw e; } }; const deployContracts = async () => { console.log({ dao, newdao, protocolSettings }); await getProxyFactory(); console.info("got proxyfactory at:", proxyFactory.address); for (let contract of toDeployUpgradable) { if (contract.network !== "both" && (contract.network === "mainnet") !== isMainnet) { console.log(contract, " Skipping non mainnet/sidechain contract:", contract.network, contract.name); continue; } if (isDevelop === false && newdao[contract.name]) { console.log( contract.name, " Skipping deployed contract at:", newdao[contract.name], "upgrading:", !!process.env.UPGRADE ); continue; } const args = await Promise.all(contract.args.map(async _ => await (isFunction(_) ? _() : _))); console.log(`deploying contract upgrade ${contract.name}`, { args // release // pf: ProxyFactory.factory.address }); // await pressAnyKey(); let opts = {}; if (contract.libraries) { let libraries = {}; contract.libraries.forEach(l => (libraries[l] = release[l])); opts = { libraries }; } const Contract = await ethers.getContractFactory(contract.name, opts); let deployed = await deployDeterministic(contract, args, opts); console.log(`${contract.name} deployed to: ${deployed.address}`); release[contract.name] = deployed.address; await releaser(release, networkName, "deployment", false); } if (!isProduction || get(release, "StakingContracts", []).length == 0) { const { DonationsStaking, StakingContracts } = isMainnet && (await deployStakingContracts(release)); release["StakingContracts"] = StakingContracts; release["DonationsStaking"] = DonationsStaking; console.log("staking contracts result:", { StakingContracts, DonationsStaking }); } release["network"] = networkName; release["networkId"] = network.config.chainId || 4447; if (!isMainnet) { release["HomeBridge"] = dao.HomeBridge; release["SignupBonus"] = dao.SignupBonus; release["OneTimePayments"] = dao.OneTimePayments; release["Invites"] = dao.Invites; release["AdminWallet"] = dao.AdminWallet; } else { release["ForeignBridge"] = dao.ForeignBridge; release["Contribution"] = dao.Contribution; } release["Identity"] = dao.Identity; release["GoodDollar"] = dao.GoodDollar; release["Controller"] = dao.Controller; release["Avatar"] = avatar; release["FirstClaimPool"] = dao.FirstClaimPool; release["ProxyAdmin"] = dao.ProxyAdmin; release["BancorFormula"] = protocolSettings.bancor || dao.BancorFormula; release["DAI"] = get(protocolSettings, "compound.dai", dao.DAI); release["cDAI"] = get(protocolSettings, "compound.cdai", dao.cDAI); release["COMP"] = get(protocolSettings, "compound.comp", dao.COMP); release = omitBy(release, _ => _ === undefined); let res = Object.assign(newdao, release); await releaser(release, networkName); return release; }; // const proveNewRep = async () => { // console.log("prooving new rep..."); // if (networkName.includes("production") === false) { // const proofs = [ // [ // "0x23d8bd1cdfa398986bb91927d3011fb1ded1425b6ae3ff794e497235481fe57f", // "0xe4ac4e67088f036e8dc535fee10a3ad42065e444d2b0bd3668e0df21e1590db3", // ], // ["0x4c01c2c86a047dc65fc8ff0a1d9ac11842597af9a363711e4db7dcabcfda307b"], // [ // "0x235dc3126b01e763befb96ead059e3f19d0380e65e477e6ebb95c1d9fc90e0b7", // "0xe4ac4e67088f036e8dc535fee10a3ad42065e444d2b0bd3668e0df21e1590db3", // ], // ]; // let proofResults = await Promise.all( // founders.map((f, idx) => // grep // .connect(f) // .proveBalanceOfAtBlockchain(repStateId, f.address, 100, proofs[idx]) // .then((_) => _.wait()) // ) // ); // console.log( // "proofs:", // proofResults.map((_) => _.events) // ); // } else { // //prove foundation multi sig account // const proof = []; // const foundationAddress = protocolSettings.governance.foundationAddress; // let proofResult = await grep // .proveBalanceOfAtBlockchain( // repStateId, // foundationAddress, // 12000000, // proof // ) // .then((_) => _.wait()); // console.log("proofs:", proofResult.events); // } // }; const performUpgrade = async release => { const isKovan = networkName.includes("kovan"); const upgrade: ProtocolUpgrade = (await ethers.getContractAt( "ProtocolUpgrade", release.ProtocolUpgrade )) as unknown as ProtocolUpgrade; console.log("performing protocol v2 upgrade on Mainnet...", { release, dao }); console.log("upgrading nameservice + staking rewards..."); let tx; tx = await ( await upgrade.upgradeBasic( release.NameService, [ ethers.utils.keccak256(ethers.utils.toUtf8Bytes("RESERVE")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("MARKET_MAKER")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("FUND_MANAGER")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("REPUTATION")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("GDAO_STAKERS")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("BRIDGE_CONTRACT")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("UBI_RECIPIENT")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("EXCHANGE_HELPER")) ], [ release.GoodReserveCDai, release.GoodMarketMaker, release.GoodFundManager, release.GReputation, release.StakersDistribution, dao.ForeignBridge, isKovan ? root.address : newfusedao.UBIScheme, //fake for kovan release.ExchangeHelper ], release.StakingContracts.map((_: any) => _[0]), release.StakingContracts.map((_: any) => _[1]) ) ).wait(); await countTotalGas(tx, "call upgrade basic"); console.log("upgrading reserve...", { params: [release.NameService, dao.Reserve, dao.MarketMaker, dao.FundManager, release.COMP] }); tx = await upgrade.upgradeReserve( release.NameService, dao.Reserve, dao.MarketMaker, dao.FundManager, release.COMP, GAS_SETTINGS ); await countTotalGas(tx, "call upgrade reserve"); console.log("upgrading donationstaking...", { params: [ release.NameService, dao.DonationsStaking, //old release.DonationsStaking ] }); tx = await upgrade.upgradeDonationStaking( release.NameService, dao.DonationsStaking, //old release.DonationsStaking, //new dao.DAIStaking, GAS_SETTINGS ); await countTotalGas(tx, "call upgrade donations"); console.log("Donation staking upgraded"); //extract just the addresses without the rewards // release.StakingContracts = release.StakingContracts.map((_) => _[0]); if (isProduction) { console.log("SKIPPING GOVERNANCE UPGRADE FOR PRODUCTION. RUN IT MANUALLY"); } else { console.log("upgrading governance..."); tx = await upgrade.upgradeGovernance(dao.SchemeRegistrar, dao.UpgradeScheme, release.CompoundVotingMachine); await countTotalGas(tx, "call upgrade gov"); } }; const performUpgradeFuse = async release => { const upgrade: ProtocolUpgradeFuse = (await ethers.getContractAt( "ProtocolUpgradeFuse", release.ProtocolUpgradeFuse )) as unknown as ProtocolUpgradeFuse; console.log("performing protocol v2 upgrade on Fuse...", { release, dao }); await upgrade .upgrade( release.NameService, //old contracts [dao.SchemeRegistrar || ethers.constants.AddressZero, dao.UpgradeScheme, dao.UBIScheme, dao.FirstClaimPool], release.UBIScheme, [ ethers.utils.keccak256(ethers.utils.toUtf8Bytes("REPUTATION")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("BRIDGE_CONTRACT")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("UBISCHEME")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("GDAO_STAKING")), ethers.utils.keccak256(ethers.utils.toUtf8Bytes("GDAO_CLAIMERS")) ], [ release.GReputation, dao.HomeBridge, release.UBIScheme, release.GovernanceStaking, release.ClaimersDistribution ], GAS_SETTINGS ) .then(_ => countTotalGas(_, "fuse basic upgrade")); if (isProduction) { console.log("SKIPPING GOVERNANCE UPGRADE FOR PRODUCTION. RUN IT MANUALLY"); } else { console.log("upgrading governance..."); await upgrade.upgradeGovernance( dao.SchemeRegistrar, dao.UpgradeScheme, release.CompoundVotingMachine, GAS_SETTINGS ); } }; //give Avatar permissions to the upgrade process contract const voteProtocolUpgrade = async release => { const Upgrade = release.ProtocolUpgrade || release.ProtocolUpgradeFuse; console.log("approve upgrade scheme in dao...", Upgrade, dao.SchemeRegistrar); const schemeRegistrar: SchemeRegistrar = (await ethers.getContractAt( "SchemeRegistrar", dao.SchemeRegistrar )) as unknown as SchemeRegistrar; console.log("proprosing scheme ..."); const proposal = await ( await schemeRegistrar.proposeScheme( avatar, Upgrade, ethers.constants.HashZero, "0x0000001F", ethers.utils.keccak256(ethers.utils.toUtf8Bytes("ProtocolUpgrade")) ) ).wait(); await countTotalGas(proposal, "propose upgrade"); console.log("proposal tx:", proposal.transactionHash); let proposalId = proposal.events.find(_ => _.event === "NewSchemeProposal").args._proposalId; console.log("proposal", { scheme: Upgrade, proposalId }); console.log("voting..."); const absoluteVote = await ethers.getContractAt( ["function vote(bytes32,uint,uint,address) returns (bool)"], dao.AbsoluteVote ); console.log("voteUpgradeScheme", { absoluteVote: dao.AbsoluteVote, founders }); await Promise.all( founders.slice(1).map(f => absoluteVote .connect(f) .vote(proposalId, 1, 0, f.address, { ...GAS_SETTINGS, gasLimit: 300000 }) .then(_ => countTotalGas(_.wait(), "vote")) .catch(e => console.log("founder vote failed:", f.address, e.message)) ) ); }; const deployStakingContracts = async release => { const isRopsten = networkName === "fuse-mainnet" || networkName === "staging-mainnet"; console.log("deployStakingContracts", { factory: release.CompoundStakingFactory, ns: release.NameService }); const compfactory = await ethers.getContractAt("CompoundStakingFactory", release.CompoundStakingFactory); const aavefactory = await ethers.getContractAt("AaveStakingFactory", release.AaveStakingFactory); const compps = compoundTokens.map(async token => { let rewardsPerBlock = protocolSettings.staking.rewardsPerBlock; console.log("deployStakingContracts", { token, settings: protocolSettings.staking, rewardsPerBlock, factory: compfactory.address, params: [ token.address, release.NameService, protocolSettings.staking.fullRewardsThreshold, //blocks before switching for 0.5x rewards to 1x multiplier token.usdOracle, token.compUsdOracle ] }); const tx = await ( await compfactory["cloneAndInit(address,address,uint64,address,address,address[])"]( token.address, release.NameService, protocolSettings.staking.fullRewardsThreshold, //blocks before switching for 0.5x rewards to 1x multiplier token.usdOracle, token.compUsdOracle, token.swapPath, GAS_SETTINGS ) ).wait(); await countTotalGas(tx, "deploy comp staking"); const log = tx.events.find(_ => _.event === "Deployed"); if (!log.args.proxy) throw new Error(`staking contract deploy failed ${token}`); return [log.args.proxy, rewardsPerBlock]; }); await Promise.all(compps); // const compps = [ // Promise.resolve(["0x9999c40c8b88c740076b15d2e708db6a7a071b53", 13888]) // ]; let deployed; if (!isDappTest && (!isRopsten || isTest)) { const aaveps = aaveTokens.map(async token => { let rewardsPerBlock = (protocolSettings.staking.rewardsPerBlock / 2) //aave gets half of the rewards .toFixed(0); console.log("deployStakingContracts aave", { token, settings: protocolSettings.staking, rewardsPerBlock, params: [ token.address, get(protocolSettings, "aave.lendingPool", dao.AaveLendingPool), release.NameService, protocolSettings.staking.fullRewardsThreshold, //blocks before switching for 0.5x rewards to 1x multiplier token.usdOracle, get(protocolSettings, "aave.incentiveController", dao.AaveIncentiveController), token.aaveUsdOracle, token.swapPath, GAS_SETTINGS ] }); const tx = await ( await aavefactory["cloneAndInit(address,address,address,uint64,address,address,address,address[])"]( token.address, get(protocolSettings, "aave.lendingPool", dao.AaveLendingPool), release.NameService, protocolSettings.staking.fullRewardsThreshold, //blocks before switching for 0.5x rewards to 1x multiplier token.usdOracle, get(protocolSettings, "aave.incentiveController", dao.AaveIncentiveController), token.aaveUsdOracle, token.swapPath, GAS_SETTINGS ) ).wait(); await countTotalGas(tx, "deploy aave staking"); const log = tx.events.find(_ => _.event === "Deployed"); if (!log.args.proxy) throw new Error(`staking contract deploy failed ${token}`); return [log.args.proxy, rewardsPerBlock]; }); // const aaveps = [ // Promise.resolve(["0x8f0c4f59b4c593193e5b5e0224d848ac803ad1a2", 13888 / 2]) // ]; await Promise.all(aaveps); deployed = await Promise.all(compps.concat(aaveps)); } else { deployed = await Promise.all(compps); } console.log("deploying donation staking"); console.log(`release ${release}`); const deployedDonationsStaking = await deployDeterministic( { network: "mainnet", name: "DonationsStaking", isUpgradable: true }, [ release.NameService, deployed[0][0], ["0x0000000000000000000000000000000000000000", get(protocolSettings, "compound.dai", dao.DAI)], [get(protocolSettings, "compound.dai", dao.DAI), "0x0000000000000000000000000000000000000000"] ], { libraries: { UniswapV2SwapHelper: release["UniswapV2SwapHelper"] } } ); // await countTotalGas(deployedDonationsStaking); console.log(`DonationsStaking deployed to: ${deployedDonationsStaking.address}`); return { DonationsStaking: deployedDonationsStaking.address, StakingContracts: deployed }; }; const verifyContracts = async release => { for (let contract of toDeployUpgradable) { if (contract.network !== "both" && (contract.network === "mainnet") !== isMainnet) { console.log( contract, " Skipping verification non mainnet/sidechain contract:", contract.network, contract.name ); continue; } console.log("Running contract verification:", { contract }, release[contract.name]); if (contract.isUpgradable !== false) { const implementationAddress = await getImplementationAddress(network.provider, release[contract.name]); try { await run("verify:verify", { address: implementationAddress }); } catch (err) { console.log("err", err); } } else { try { await run("verify:verify", { address: release[contract.name], constructorArguments: contract.args, libraries: { UniswapV2SwapHelper: release["UniswapV2SwapHelper"] } }); } catch (err) { console.log("err", err); } } } }; await deployContracts(); if (isPerformUpgrade) { console.log("deployed contracts", { totalGas, dao, release }); if (isTest === false) await pressAnyKey(); await voteProtocolUpgrade(release); if (isTest === false) await pressAnyKey(); console.log("voted contracts", { totalGas }); isMainnet && (await performUpgrade(release)); !isMainnet && (await performUpgradeFuse(release)); console.log("upgraded contracts", { totalGas }); } if (isMainnet && !isTest && !isCoverage) { await verifyContracts(release); } await releaser(release, networkName); return release; // await proveNewRep(); }; if (network.name !== "hardhat" && process.argv[1].includes("upgradeToV2.ts")) { main(name, false) .catch(e => { console.log(e); throw e; }) .finally(() => { console.log({ totalGas, gasUsage }); }); }