diff --git a/tasks/deploy/deployAPTeamMultiSig.ts b/tasks/deploy/deployAPTeamMultiSig.ts index b3086d85f..58bd6105e 100644 --- a/tasks/deploy/deployAPTeamMultiSig.ts +++ b/tasks/deploy/deployAPTeamMultiSig.ts @@ -1,5 +1,6 @@ import {deployAPTeamMultiSig} from "contracts/multisigs/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; type TaskArgs = { @@ -12,7 +13,12 @@ type TaskArgs = { task("deploy:APTeamMultiSig", "Will deploy APTeamMultiSig contract") .addFlag("skipVerify", "Skip contract verification") .addFlag("yes", "Automatic yes to prompt.") - .addOptionalParam("admin", "override for proxy admin wallet, default: proxyAdminMultisig") + .addOptionalParam( + "admin", + "override for proxy admin wallet, default: proxyAdminMultisig", + undefined, + cliTypes.address + ) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." diff --git a/tasks/deploy/deployAccountsDiamond.ts b/tasks/deploy/deployAccountsDiamond.ts index e804b5e14..0f299730b 100644 --- a/tasks/deploy/deployAccountsDiamond.ts +++ b/tasks/deploy/deployAccountsDiamond.ts @@ -1,5 +1,6 @@ import {deployAccountsDiamond} from "contracts/core/accounts/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; type TaskArgs = { @@ -14,11 +15,15 @@ type TaskArgs = { task("deploy:accounts", "It will deploy accounts diamond contracts") .addOptionalParam( "apTeamMultisig", - "APTeamMultiSig contract address. Will do a local lookup from contract-address.json if none is provided." + "APTeamMultiSig contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "registrar", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/deploy/deployCharityApplications.ts b/tasks/deploy/deployCharityApplications.ts index b3bde3890..770970b57 100644 --- a/tasks/deploy/deployCharityApplications.ts +++ b/tasks/deploy/deployCharityApplications.ts @@ -1,5 +1,6 @@ import {deployCharityApplications} from "contracts/multisigs/scripts/deployCharityApplications"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; type TaskArgs = { @@ -13,7 +14,9 @@ type TaskArgs = { task("deploy:CharityApplications", "Will deploy CharityApplication contract") .addOptionalParam( "accountsDiamond", - "Accounts Diamond contract address. Will do a local lookup from contract-address.json if none is provided." + "Accounts Diamond contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/deploy/deployGiftcard.ts b/tasks/deploy/deployGiftcard.ts index 6c291b18e..7f9d8fa31 100644 --- a/tasks/deploy/deployGiftcard.ts +++ b/tasks/deploy/deployGiftcard.ts @@ -1,10 +1,11 @@ import {CONFIG} from "config"; import {deployGiftCard} from "contracts/accessory/gift-cards/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {getAddresses, isLocalNetwork, logger} from "utils"; type TaskArgs = { - keeper: string; + keeper?: string; registrar?: string; skipVerify: boolean; }; @@ -16,7 +17,9 @@ task("deploy:GiftCard", "Will deploy GiftCardContracts contract") ) .addOptionalParam( "registrar", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addFlag("skipVerify", "Skip contract verification") .setAction(async (taskArgs: TaskArgs, hre) => { diff --git a/tasks/deploy/deployHaloImplementation.ts b/tasks/deploy/deployHaloImplementation.ts index 8c06046b9..3aaa59ab6 100644 --- a/tasks/deploy/deployHaloImplementation.ts +++ b/tasks/deploy/deployHaloImplementation.ts @@ -10,12 +10,15 @@ import {deployCommunity} from "contracts/halo/community/scripts/deploy"; import {deployGov} from "contracts/halo/gov/scripts/deploy"; import {deployStaking} from "contracts/halo/staking/scripts/deploy"; import {deployVesting} from "contracts/halo/vesting/scripts/deploy"; +import {cliTypes} from "tasks/types"; task("deploy:HaloImplementation", "Will deploy HaloImplementation contract") .addFlag("skipVerify", "Skip contract verification") .addOptionalParam( "registrar", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .setAction(async (taskArgs, hre) => { try { diff --git a/tasks/deploy/deployIndexFund.ts b/tasks/deploy/deployIndexFund.ts index da8e72b6e..a6c9d6c15 100644 --- a/tasks/deploy/deployIndexFund.ts +++ b/tasks/deploy/deployIndexFund.ts @@ -1,5 +1,6 @@ import {deployIndexFund} from "contracts/core/index-fund/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; type TaskArgs = { @@ -13,11 +14,15 @@ type TaskArgs = { task("deploy:IndexFund", "Will deploy IndexFund contract") .addOptionalParam( "owner", - "Address of the owner. By default set to AP team multisig proxy saved in contract-address.json." + "Address of the owner. By default set to AP team multisig proxy saved in contract-address.json.", + undefined, + cliTypes.address ) .addOptionalParam( "registrar", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/deploy/deployLocalRegistrar.ts b/tasks/deploy/deployLocalRegistrar.ts index 9c3eb816e..21962ddc5 100644 --- a/tasks/deploy/deployLocalRegistrar.ts +++ b/tasks/deploy/deployLocalRegistrar.ts @@ -1,6 +1,7 @@ import {deployLocalRegistrar} from "contracts/core/registrar/scripts/deploy"; import {deployRouter} from "contracts/core/router/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {LocalRegistrarLib} from "typechain-types/contracts/core/registrar/LocalRegistrar"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; @@ -12,7 +13,12 @@ type TaskArgs = { }; task("deploy:LocalRegistrarAndRouter", "Will deploy the Local Registrar contract and Router.") - .addOptionalParam("owner", "The owner wallet for both router and registrar") + .addOptionalParam( + "owner", + "The owner wallet for both router and registrar. By default set to AP team multisig proxy saved in contract-address.json.", + undefined, + cliTypes.address + ) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." diff --git a/tasks/deploy/deployRegistrar.ts b/tasks/deploy/deployRegistrar.ts index ea15103cb..3c171d39f 100644 --- a/tasks/deploy/deployRegistrar.ts +++ b/tasks/deploy/deployRegistrar.ts @@ -1,6 +1,7 @@ import {CONFIG} from "config"; import {deployRegistrar} from "contracts/core/registrar/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; type TaskArgs = { @@ -17,11 +18,15 @@ task( ) .addOptionalParam( "apTeamMultisig", - "APTeamMultiSig contract address. Will do a local lookup from contract-address.json if none is provided." + "APTeamMultiSig contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "router", - "Router contract address. Will do a local lookup from contract-address.json if none is provided." + "Router contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/deploy/deployRouter.ts b/tasks/deploy/deployRouter.ts index 6b5d6cad5..a06f83c99 100644 --- a/tasks/deploy/deployRouter.ts +++ b/tasks/deploy/deployRouter.ts @@ -1,5 +1,6 @@ import {deployRouter} from "contracts/core/router/scripts/deploy"; import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {confirmAction, getAddresses, getSigners, isLocalNetwork, logger, verify} from "utils"; type TaskArgs = { @@ -12,7 +13,9 @@ type TaskArgs = { task("deploy:Router", "Will deploy Router contract") .addOptionalParam( "registrar", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/deploy/integrations/dummyIntegration.ts b/tasks/deploy/integrations/dummyIntegration.ts index 12d18970f..81cdcbfc7 100644 --- a/tasks/deploy/integrations/dummyIntegration.ts +++ b/tasks/deploy/integrations/dummyIntegration.ts @@ -1,5 +1,12 @@ +import {allStrategyConfigs} from "contracts/integrations/stratConfig"; import {task} from "hardhat/config"; -import {APVault_V1__factory, VaultEmitter__factory, DummyERC20__factory, GoerliDummy__factory} from "typechain-types"; +import {cliTypes} from "tasks/types"; +import { + APVault_V1__factory, + DummyERC20__factory, + GoerliDummy__factory, + VaultEmitter__factory, +} from "typechain-types"; import {VaultType} from "types"; import { StratConfig, @@ -8,25 +15,22 @@ import { getSigners, logger, writeStrategyAddresses, - getVaultAddress, - getStrategyAddress, - getAPTeamOwner } from "utils"; -import {allStrategyConfigs} from "../../../contracts/integrations/stratConfig"; -import {submitMultiSigTx} from "tasks/helpers"; type TaskArgs = { - name: string; + stratConfig: StratConfig; admin: string; skipVerify: boolean; }; task("Deploy:dummyIntegration", "Will deploy a set of vaults and a dummy strategy") .addParam( - "name", + "stratConfig", `The name of the strategy according to StratConfig, possible values: ${Object.keys( allStrategyConfigs - ).join(", ")}` + ).join(", ")}`, + undefined, + cliTypes.stratConfig ) .addOptionalParam( "admin", @@ -35,7 +39,10 @@ task("Deploy:dummyIntegration", "Will deploy a set of vaults and a dummy strateg .addFlag("skipVerify", "Skip contract verification") .setAction(async (taskArgs: TaskArgs, hre) => { try { - const config: StratConfig = allStrategyConfigs[taskArgs.name]; + logger.divider(); + logger.out("Deploying a set of vaults and a dummy strategy..."); + + const config: StratConfig = taskArgs.stratConfig; const {deployer} = await getSigners(hre); let network = await hre.ethers.provider.getNetwork(); if (network.chainId != config.chainId) { @@ -86,36 +93,29 @@ task("Deploy:dummyIntegration", "Will deploy a set of vaults and a dummy strateg }; let liqVault = await Vault.deploy(liquidConfig, addresses.vaultEmitter.proxy, admin); logger.pad(30, "Liquid Vault deployed to", liqVault.address); - - const emitter = VaultEmitter__factory.connect(addresses.vaultEmitter.proxy, deployer); - await emitter.vaultCreated( - lockVault.address, - { - vaultType: VaultType.LOCKED, - strategyId: config.id, - strategy: strategy.address, - registrar: addresses.registrar.proxy, - baseToken: addresses.tokens.usdc, - yieldToken: yieldToken.address, - apTokenName: "LockedTestVault", - apTokenSymbol: "LockTV", - } - ) - await emitter.vaultCreated( - liqVault.address, - { - vaultType: VaultType.LIQUID, - strategyId: config.id, - strategy: strategy.address, - registrar: addresses.registrar.proxy, - baseToken: addresses.tokens.usdc, - yieldToken: "0x2811747e3336aa28caf71c51454766e1b95f56e8", - apTokenName: "LiquidTestVault", - apTokenSymbol: "LiqTV", + const emitter = VaultEmitter__factory.connect(addresses.vaultEmitter.proxy, deployer); - } - ) + await emitter.vaultCreated(lockVault.address, { + vaultType: VaultType.LOCKED, + strategyId: config.id, + strategy: strategy.address, + registrar: addresses.registrar.proxy, + baseToken: addresses.tokens.usdc, + yieldToken: yieldToken.address, + apTokenName: "LockedTestVault", + apTokenSymbol: "LockTV", + }); + await emitter.vaultCreated(liqVault.address, { + vaultType: VaultType.LIQUID, + strategyId: config.id, + strategy: strategy.address, + registrar: addresses.registrar.proxy, + baseToken: addresses.tokens.usdc, + yieldToken: "0x2811747e3336aa28caf71c51454766e1b95f56e8", + apTokenName: "LiquidTestVault", + apTokenSymbol: "LiqTV", + }); const data: StrategyObject = { strategy: strategy.address, @@ -123,7 +123,7 @@ task("Deploy:dummyIntegration", "Will deploy a set of vaults and a dummy strateg liquid: liqVault.address, }; - writeStrategyAddresses(taskArgs.name, data); + writeStrategyAddresses(taskArgs.stratConfig.name, data); } catch (error) { logger.out(error, logger.Level.Error); } diff --git a/tasks/manage/accounts/updateConfig.ts b/tasks/manage/accounts/updateConfig.ts index 413a620e2..ee4314881 100644 --- a/tasks/manage/accounts/updateConfig.ts +++ b/tasks/manage/accounts/updateConfig.ts @@ -1,5 +1,6 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {AccountsQueryEndowments__factory, AccountsUpdate__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger, structToObject} from "utils"; @@ -12,7 +13,9 @@ type TaskArgs = { task("manage:accounts:updateConfig", "Will update Accounts Diamond config") .addOptionalParam( "registrarContract", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/accounts/updateOwner.ts b/tasks/manage/accounts/updateOwner.ts index 67ebaf421..11ae5ac06 100644 --- a/tasks/manage/accounts/updateOwner.ts +++ b/tasks/manage/accounts/updateOwner.ts @@ -1,5 +1,6 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {AccountsQueryEndowments__factory, AccountsUpdate__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; @@ -8,7 +9,9 @@ type TaskArgs = {to: string; apTeamSignerPkey?: string; yes: boolean}; task("manage:AccountsDiamond:updateOwner", "Will update the owner of the Accounts Diamond") .addOptionalParam( "to", - "Address of the new owner. Ensure at least one of `apTeamMultisigOwners` is the controller of this address. Will default to `contract-address.json > multiSig.apTeam.proxy` if none is provided." + "Address of the new owner. Ensure at least one of `apTeamMultisigOwners` is the controller of this address. Will default to `contract-address.json > multiSig.apTeam.proxy` if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/addMultisigOwners.ts b/tasks/manage/addMultisigOwners.ts index ace2822dc..f4510f9e9 100644 --- a/tasks/manage/addMultisigOwners.ts +++ b/tasks/manage/addMultisigOwners.ts @@ -1,5 +1,6 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {MultiSigGeneric__factory} from "typechain-types"; import {confirmAction, connectSignerFromPkey, logger} from "utils"; @@ -11,27 +12,25 @@ type TaskArgs = { }; task("manage:addMultisigOwners", "Will add the specified address to the multisig as an owner") - .addParam("multisig", "Address of multisig") - .addVariadicPositionalParam("owners", "Addresses of new owners") + .addParam("multisig", "Address of multisig", undefined, cliTypes.address) + .addParam("owners", "Addresses of new owners", undefined, cliTypes.array.address) .addParam("multisigOwnerPkey", "Private Key for a valid Multisig Owner.") .addFlag("yes", "Automatic yes to prompt.") .setAction(async (taskArguments: TaskArgs, hre) => { try { logger.divider(); + logger.out(`Adding new owners to ${taskArguments.multisig}:`); + logger.out(taskArguments.owners); - const msOwner = await connectSignerFromPkey(taskArguments.multisigOwnerPkey, hre); - - const isConfirmed = - taskArguments.yes || - (await confirmAction(`Adding new owner: ${await msOwner.getAddress()}`)); + const isConfirmed = taskArguments.yes || (await confirmAction()); if (!isConfirmed) { return logger.out("Confirmation denied.", logger.Level.Warn); } + const msOwner = await connectSignerFromPkey(taskArguments.multisigOwnerPkey, hre); + const multisig = MultiSigGeneric__factory.connect(taskArguments.multisig, msOwner); - logger.out("Adding new owners:"); - logger.out(taskArguments.owners); const addOwnerData = multisig.interface.encodeFunctionData("addOwners", [ taskArguments.owners, ]); diff --git a/tasks/manage/changeProxyAdmin.ts b/tasks/manage/changeProxyAdmin.ts index ebeae0775..8ecc2f037 100644 --- a/tasks/manage/changeProxyAdmin.ts +++ b/tasks/manage/changeProxyAdmin.ts @@ -2,6 +2,7 @@ import {task} from "hardhat/config"; import {ITransparentUpgradeableProxy__factory, ProxyContract__factory} from "typechain-types"; import {confirmAction, getAddresses, getProxyAdminOwner, logger} from "utils"; import {submitMultiSigTx} from "../helpers"; +import {cliTypes} from "tasks/types"; type TaskArgs = { to?: string; @@ -13,9 +14,16 @@ type TaskArgs = { task("manage:changeProxyAdmin", "Will update the proxy admin the target proxy contract") .addOptionalParam( "to", - "New proxy admin address. Make sure to use an address of an account you control. Will do a local lookup from contract-address.json if none is provided." + "New proxy admin address. Make sure to use an address of an account you control. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address + ) + .addParam( + "proxy", + "Target Proxy Contract. Must be owned by the ProxyAdminMultiSig.", + undefined, + cliTypes.address ) - .addParam("proxy", "Target Proxy Contract. Must be owned by the ProxyAdminMultiSig.") .addOptionalParam( "proxyAdminPkey", "The pkey for one of the current ProxyAdminMultiSig's owners." diff --git a/tasks/manage/changeProxyAdminForAll.ts b/tasks/manage/changeProxyAdminForAll.ts index 7ac3d8106..f0964c7b1 100644 --- a/tasks/manage/changeProxyAdminForAll.ts +++ b/tasks/manage/changeProxyAdminForAll.ts @@ -1,6 +1,7 @@ import {Signer} from "ethers"; import {task} from "hardhat/config"; import {HardhatRuntimeEnvironment} from "hardhat/types"; +import {cliTypes} from "tasks/types"; import {OwnershipFacet__factory} from "typechain-types"; import {AddressObj, confirmAction, getAddresses, getProxyAdminOwner, logger} from "utils"; import {submitMultiSigTx} from "../helpers"; @@ -15,7 +16,9 @@ type TaskArgs = { task("manage:changeProxyAdminForAll", "Will update the proxy admin for all proxy contracts") .addOptionalParam( "to", - "New proxy admin address. Make sure to use an address of an account you control. Will do a local lookup from contract-address.json if none is provided." + "New proxy admin address. Make sure to use an address of an account you control. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "proxyAdminPkey", diff --git a/tasks/manage/charityApplications/updateConfig.ts b/tasks/manage/charityApplications/updateConfig.ts index cd8aefe56..50b0163e2 100644 --- a/tasks/manage/charityApplications/updateConfig.ts +++ b/tasks/manage/charityApplications/updateConfig.ts @@ -1,5 +1,6 @@ import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {CharityApplications__factory} from "typechain-types"; import { confirmAction, @@ -23,11 +24,13 @@ type TaskArgs = { task("manage:CharityApplications:updateConfig", "Will update CharityApplications config") .addOptionalParam( "accountsDiamond", - "Accounts Diamond contract address. Will do a local lookup from contract-address.json if none is provided." + "Accounts Diamond contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam("gasAmount", "Amount of gas to be sent.", undefined, types.int) .addOptionalParam("expiry", "Expiry time for proposals.", undefined, types.int) - .addOptionalParam("seedAsset", "Address of seed asset.") + .addOptionalParam("seedAsset", "Address of seed asset.", undefined, cliTypes.address) .addOptionalParam("seedAmount", "Amount of seed asset to be sent.", undefined, types.int) .addOptionalParam( "seedSplitToLiquid", diff --git a/tasks/manage/createEndowment.ts b/tasks/manage/createEndowment.ts index 18db0e5fd..f3e6ed281 100644 --- a/tasks/manage/createEndowment.ts +++ b/tasks/manage/createEndowment.ts @@ -1,16 +1,29 @@ -import {task, types} from "hardhat/config"; +import {task} from "hardhat/config"; import {proposeCharityApplication} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {AccountsCreateEndowment__factory, AccountsQueryEndowments__factory} from "typechain-types"; import {AccountMessages} from "typechain-types/contracts/multisigs/CharityApplications"; -import {getAddresses, getCharityApplicationsOwner, logger, structToObject} from "utils"; +import {EndowmentType} from "types"; +import { + getAddresses, + getCharityApplicationsOwner, + getEnumValuesAsString, + logger, + structToObject, +} from "utils"; type TaskArgs = { appsSignerPkey?: string; - endowType: 0 | 1; + endowType: EndowmentType; }; task("manage:createEndowment", "Will create a new endowment") - .addParam("endowType", "0 - charity, 1 - ast, 2 - daf ", 0, types.int) + .addParam( + "endowType", + getEnumValuesAsString(EndowmentType), + EndowmentType.Charity, + cliTypes.enums(EndowmentType, "EndowmentType") + ) .addOptionalParam( "appsSignerPkey", "If running on prod, provide a pkey for a valid CharityApplications Multisig Owner." @@ -54,7 +67,7 @@ task("manage:createEndowment", "Will create a new endowment") sdgs: [1], referralId: 0, tier: 0, - endowType: taskArgs.endowType, // Charity + endowType: taskArgs.endowType, logo: "", image: "", members: [await appsSigner.getAddress()], @@ -95,7 +108,7 @@ task("manage:createEndowment", "Will create a new endowment") }, }; - if (taskArgs.endowType == 0) { + if (taskArgs.endowType == EndowmentType.Charity) { await proposeCharityApplication( addresses.multiSig.charityApplications.proxy, appsSigner, diff --git a/tasks/manage/endowmentMultiSigFactory/updateProxyAdmin/updateProxyAdmin.ts b/tasks/manage/endowmentMultiSigFactory/updateProxyAdmin/updateProxyAdmin.ts index bfb31d74c..ddf7a127d 100644 --- a/tasks/manage/endowmentMultiSigFactory/updateProxyAdmin/updateProxyAdmin.ts +++ b/tasks/manage/endowmentMultiSigFactory/updateProxyAdmin/updateProxyAdmin.ts @@ -2,6 +2,7 @@ import {task} from "hardhat/config"; import {confirmAction, getAddresses, logger} from "utils"; import updateEndowmentMultiSigFactory from "./updateEndowmentMultiSigFactory"; import updateEndowmentProxiesAdmin from "./updateEndowmentProxiesAdmin"; +import {cliTypes} from "tasks/types"; type TaskArgs = { to?: string; @@ -16,7 +17,9 @@ task( ) .addOptionalParam( "to", - "New proxy admin address. Make sure to use an address of an account you control. Will do a local lookup from contract-address.json if none is provided." + "New proxy admin address. Make sure to use an address of an account you control. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/endowmentMultiSigFactory/updateRegistrar.ts b/tasks/manage/endowmentMultiSigFactory/updateRegistrar.ts index 8ff3b9f94..e536b852a 100644 --- a/tasks/manage/endowmentMultiSigFactory/updateRegistrar.ts +++ b/tasks/manage/endowmentMultiSigFactory/updateRegistrar.ts @@ -1,5 +1,6 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {IEndowmentMultiSigFactory__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; @@ -15,7 +16,9 @@ task( ) .addOptionalParam( "registrar", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided." + "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/gasFwdFactory/updateRegistrar.ts b/tasks/manage/gasFwdFactory/updateRegistrar.ts index fff889c64..63c1b9abd 100644 --- a/tasks/manage/gasFwdFactory/updateRegistrar.ts +++ b/tasks/manage/gasFwdFactory/updateRegistrar.ts @@ -1,9 +1,10 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {GasFwdFactory__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; -type TaskArgs = {newRegistrar: string; apTeamSignerPkey?: string; yes: boolean}; +type TaskArgs = {newRegistrar?: string; apTeamSignerPkey?: string; yes: boolean}; task( "manage:GasFwdFactory:updateRegistrar", @@ -11,7 +12,9 @@ task( ) .addOptionalParam( "newRegistrar", - "Address of the new registrar. Will default to `contract-address.json > registrar.proxy` if none is provided." + "Address of the new registrar. Will default to `contract-address.json > registrar.proxy` if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/indexFund/transferOwnership.ts b/tasks/manage/indexFund/transferOwnership.ts index e9a487ceb..2dd785a74 100644 --- a/tasks/manage/indexFund/transferOwnership.ts +++ b/tasks/manage/indexFund/transferOwnership.ts @@ -1,5 +1,6 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {IndexFund__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; @@ -12,7 +13,9 @@ type TaskArgs = { task("manage:IndexFund:transferOwnership", "Will update the owner of the IndexFund") .addOptionalParam( "to", - "Address of the new owner. Ensure at least one of `apTeamMultisigOwners` is the controller of this address. Will default to `contract-address.json > multiSig.apTeam.proxy` if none is provided." + "Address of the new owner. Ensure at least one of `apTeamMultisigOwners` is the controller of this address. Will default to `contract-address.json > multiSig.apTeam.proxy` if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/indexFund/updateConfig.ts b/tasks/manage/indexFund/updateConfig.ts index 8efd5dc3a..a1f675013 100644 --- a/tasks/manage/indexFund/updateConfig.ts +++ b/tasks/manage/indexFund/updateConfig.ts @@ -1,12 +1,13 @@ import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {IndexFund__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger, structToObject} from "utils"; type TaskArgs = { - registrarContract: string; - fundingGoal: number; - fundRotation: number; + registrarContract?: string; + fundingGoal?: number; + fundRotation?: number; apTeamSignerPkey?: string; yes: boolean; }; @@ -14,7 +15,9 @@ type TaskArgs = { task("manage:IndexFund:updateConfig", "Will update the config of the IndexFund") .addOptionalParam( "registrarContract", - "New Registrar contract. Will do a local lookup from contract-address.json if none is provided.funding rotation blocks & funding goal amount." + "New Registrar contract. Will do a local lookup from contract-address.json if none is provided.funding rotation blocks & funding goal amount.", + undefined, + cliTypes.address ) .addOptionalParam("fundingGoal", "Funding rotation blocks.", undefined, types.int) .addOptionalParam("fundRotation", "Funding goal amount.", undefined, types.int) @@ -25,9 +28,11 @@ task("manage:IndexFund:updateConfig", "Will update the config of the IndexFund") .addFlag("yes", "Automatic yes to prompt.") .setAction(async (taskArgs: TaskArgs, hre) => { try { + logger.divider(); + logger.out("Updating IndexFund config..."); + const {yes, apTeamSignerPkey, ...newConfig} = taskArgs; - logger.divider(); const addresses = await getAddresses(hre); const apTeamOwner = await getAPTeamOwner(hre, apTeamSignerPkey); @@ -40,9 +45,7 @@ task("manage:IndexFund:updateConfig", "Will update the config of the IndexFund") logger.out("Config data to update:"); logger.out(newConfig); - const isConfirmed = - taskArgs.yes || - (await confirmAction(`Update Registrar address to: ${newConfig.registrarContract}`)); + const isConfirmed = taskArgs.yes || (await confirmAction()); if (!isConfirmed) { return logger.out("Confirmation denied.", logger.Level.Warn); } diff --git a/tasks/manage/queryEndowments.ts b/tasks/manage/queryEndowments.ts index a081b27f9..ca5da3cd0 100644 --- a/tasks/manage/queryEndowments.ts +++ b/tasks/manage/queryEndowments.ts @@ -5,7 +5,7 @@ import {getAddresses, getSigners, logger, structToObject} from "utils"; type TaskArgs = {id: number}; task("manage:queryEndowments", "Will query an Endowment's details") - .addParam("id", "the endowment id", 0, types.int) + .addParam("id", "the endowment id", undefined, types.int) .setAction(async (taskArgs: TaskArgs, hre) => { try { const {apTeam1} = await getSigners(hre); diff --git a/tasks/manage/registrar/setAccountsChainAndAddress.ts b/tasks/manage/registrar/setAccountsChainAndAddress.ts index 7d3fbae6a..6eae1e7d1 100644 --- a/tasks/manage/registrar/setAccountsChainAndAddress.ts +++ b/tasks/manage/registrar/setAccountsChainAndAddress.ts @@ -1,18 +1,36 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; -import {getAPTeamOwner, getAddresses, logger} from "utils"; +import {AXELAR_NETWORKS, getAPTeamOwner, getAddresses, logger} from "utils"; type TaskArgs = {accountsDiamond: string; chainName: string; apTeamSignerPkey?: string}; task("manage:registrar:setAccountsChainAndAddress") - .addParam("accountsDiamond", "Address of the accounts contract on target Axelar blockchain") - .addParam("chainName", "The Axelar blockchain name of the accounts contract") + .addParam( + "accountsDiamond", + "Address of the accounts contract on target Axelar blockchain", + undefined, + cliTypes.address + ) + .addParam( + "chainName", + `The Axelar blockchain name of the accounts contract, possible values: ${AXELAR_NETWORKS.values() + .filter((chain, i, arr) => arr.indexOf(chain) === i) // filter unique values + .join(", ")}` + ) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." ) .setAction(async function (taskArguments: TaskArgs, hre) { + if (!AXELAR_NETWORKS.revGet(taskArguments.chainName)) { + return logger.out( + `Chain '${taskArguments.chainName}' is not one of the supported Axelar networks`, + logger.Level.Error + ); + } + logger.divider(); logger.out("Connecting to registrar on specified network..."); const addresses = await getAddresses(hre); diff --git a/tasks/manage/registrar/setAllFeeSettings.ts b/tasks/manage/registrar/setAllFeeSettings.ts index ad0a5e850..86ee3f38b 100644 --- a/tasks/manage/registrar/setAllFeeSettings.ts +++ b/tasks/manage/registrar/setAllFeeSettings.ts @@ -1,16 +1,17 @@ import {CONFIG, FEES} from "config"; -import {task, types} from "hardhat/config"; +import {task} from "hardhat/config"; +import {cliTypes} from "tasks/types"; import {ChainID} from "types"; import {getAddresses, getChainId, getKeysTyped} from "utils"; -type TaskArgs = {payoutAddress?: string; bps?: number; apTeamSignerPkey?: string}; +type TaskArgs = {payoutAddress?: string; apTeamSignerPkey?: string}; task("manage:registrar:setAllFeeSettings") .addOptionalParam( "payoutAddress", "Override address of fee recipient -- will do a config lookup or assign to AP Team", - "", - types.string + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/registrar/setFeeSetting.ts b/tasks/manage/registrar/setFeeSetting.ts index 1b0f267fe..39f55afb8 100644 --- a/tasks/manage/registrar/setFeeSetting.ts +++ b/tasks/manage/registrar/setFeeSetting.ts @@ -1,31 +1,30 @@ import {FEES} from "config"; import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {FeeTypes} from "types"; -import {getAPTeamOwner, getAddresses, getEnumKeys, logger} from "utils"; +import {getAPTeamOwner, getAddresses, getEnumValuesAsString, logger} from "utils"; type TaskArgs = {feeType: number; payoutAddress?: string; bps?: number; apTeamSignerPkey?: string}; task("manage:registrar:setFeeSettings") .addParam( "feeType", - `The enum of the fee, possible values: ${getEnumKeys(FeeTypes) - .map((key) => `${key} - ${FeeTypes[key]}`) - .join(", ")}`, - 0, - types.int + `The enum of the fee, possible values:\n${getEnumValuesAsString(FeeTypes)}`, + FeeTypes.Default, + cliTypes.enums(FeeTypes, "FeeTypes") ) .addOptionalParam( "payoutAddress", "Address of fee recipient -- will do a config lookup if not provided", - "", - types.string + undefined, + cliTypes.address ) .addOptionalParam( "bps", "basis points to be applied for this fee -- will do a config lookup if not provided", - 0, + undefined, types.int ) .addOptionalParam( diff --git a/tasks/manage/registrar/setGasByToken.ts b/tasks/manage/registrar/setGasByToken.ts index 1b155091c..1ad1dcdb5 100644 --- a/tasks/manage/registrar/setGasByToken.ts +++ b/tasks/manage/registrar/setGasByToken.ts @@ -1,17 +1,18 @@ import {BigNumber} from "ethers"; import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {getAPTeamOwner, getAddresses, logger} from "utils"; type TaskArgs = {gas: number; tokenAddress: string; apTeamSignerPkey?: string}; task("manage:registrar:setGasByToken") - .addParam("tokenAddress", "Address of the token", "", types.string) + .addParam("tokenAddress", "Address of the token", undefined, cliTypes.address) .addParam( "gas", "Qty of tokens fwd'd to pay for gas. Make sure to use the correct number of decimals!", - 0, + undefined, types.int ) .addOptionalParam( @@ -21,6 +22,7 @@ task("manage:registrar:setGasByToken") .setAction(async function (taskArguments: TaskArgs, hre) { logger.divider(); logger.out("Connecting to registrar on specified network..."); + const addresses = await getAddresses(hre); const registrarAddress = addresses["registrar"]["proxy"]; diff --git a/tasks/manage/registrar/setStratApproval.ts b/tasks/manage/registrar/setStratApproval.ts index 33d1f243e..6d1aeff2f 100644 --- a/tasks/manage/registrar/setStratApproval.ts +++ b/tasks/manage/registrar/setStratApproval.ts @@ -1,30 +1,31 @@ import {allStrategyConfigs} from "contracts/integrations/stratConfig"; -import {task, types} from "hardhat/config"; +import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {StrategyApprovalState} from "types"; -import {StratConfig, getAPTeamOwner, getAddresses, getEnumKeys, logger} from "utils"; +import {StratConfig, getAPTeamOwner, getAddresses, getEnumValuesAsString, logger} from "utils"; -type TaskArgs = {name: string; approvalState: number; apTeamSignerPkey?: string}; +type TaskArgs = { + stratConfig: StratConfig; + approvalState: StrategyApprovalState; + apTeamSignerPkey?: string; +}; task("manage:registrar:setStratApproval") .addParam( - "name", + "stratConfig", `The name of the strategy according to StratConfig, possible values: ${Object.keys( allStrategyConfigs ).join(", ")}`, - "", - types.string + undefined, + cliTypes.stratConfig ) .addParam( "approvalState", - `Whether the strategy is currently approved or not, possible values: ${getEnumKeys( - StrategyApprovalState - ) - .map((key) => `${key} - ${StrategyApprovalState[key]}`) - .join(", ")}`, - 0, - types.int + getEnumValuesAsString(StrategyApprovalState), + StrategyApprovalState.NOT_APPROVED, + cliTypes.enums(StrategyApprovalState, "StrategyApprovalState") ) .addOptionalParam( "apTeamSignerPkey", @@ -43,8 +44,7 @@ task("manage:registrar:setStratApproval") logger.divider(); logger.out("Checking current strategy approval state"); - const config: StratConfig = allStrategyConfigs[taskArguments.name]; - let currentStratParams = await registrar.getStrategyParamsById(config.id); + let currentStratParams = await registrar.getStrategyParamsById(taskArguments.stratConfig.id); if (currentStratParams.approvalState == taskArguments.approvalState) { logger.out("Strategy approval state already matches desired state"); return; @@ -58,7 +58,7 @@ task("manage:registrar:setStratApproval") StrategyApprovalState[taskArguments.approvalState] ); const updateData = registrar.interface.encodeFunctionData("setStrategyApprovalState", [ - config.id, + taskArguments.stratConfig.id, taskArguments.approvalState, ]); await submitMultiSigTx( diff --git a/tasks/manage/registrar/setStratParams.ts b/tasks/manage/registrar/setStratParams.ts index 0aa4beaee..1ee7b62bd 100644 --- a/tasks/manage/registrar/setStratParams.ts +++ b/tasks/manage/registrar/setStratParams.ts @@ -7,19 +7,19 @@ import {ChainID} from "types"; import {StratConfig, getAPTeamOwner, getAddressesByNetworkId, isProdNetwork, logger} from "utils"; type TaskArgs = { - name: string; + stratConfig: StratConfig; modifyExisting: boolean; apTeamSignerPkey?: string; }; task("manage:registrar:setStratParams") .addParam( - "name", + "stratConfig", `The name of the strategy according to StratConfig, possible values: ${Object.keys( allStrategyConfigs ).join(", ")}`, - "", - types.string + undefined, + cliTypes.stratConfig ) .addFlag("modifyExisting", "Whether to modify an existing strategy") .addOptionalParam( @@ -27,7 +27,6 @@ task("manage:registrar:setStratParams") "If running on prod, provide a pkey for a valid APTeam Multisig Owner." ) .setAction(async function (taskArguments: TaskArgs, hre) { - const config: StratConfig = allStrategyConfigs[taskArguments.name]; if (await isProdNetwork(hre)) { await hre.run("manage:registrar:setStratParams:on-network", { ...taskArguments, @@ -35,7 +34,7 @@ task("manage:registrar:setStratParams") }); await hre.run("manage:registrar:setStratParams:on-network", { ...taskArguments, - chainId: config.chainId, + chainId: taskArguments.stratConfig.chainId, }); } else { await hre.run("manage:registrar:setStratParams:on-network", { @@ -44,7 +43,7 @@ task("manage:registrar:setStratParams") }); await hre.run("manage:registrar:setStratParams:on-network", { ...taskArguments, - chainId: config.chainId, + chainId: taskArguments.stratConfig.chainId, }); } }); @@ -54,12 +53,12 @@ subtask( "Updates strat params on the network specified by the 'chainId' param" ) .addParam( - "name", + "stratConfig", `The name of the strategy according to StratConfig, possible values: ${Object.keys( allStrategyConfigs ).join(", ")}`, - "", - types.string + undefined, + cliTypes.stratConfig ) .addParam( "chainId", @@ -86,7 +85,7 @@ subtask( logger.divider(); logger.out("Checking current strategy params at specified selector"); - const config: StratConfig = allStrategyConfigs[taskArguments.name]; + const config: StratConfig = taskArguments.stratConfig; let currentStratParams = await registrar.getStrategyParamsById(config.id); if ( currentStratParams.liquidVaultAddr == hre.ethers.constants.AddressZero && diff --git a/tasks/manage/registrar/setTokenAccepted.ts b/tasks/manage/registrar/setTokenAccepted.ts index 9e8dd45ac..9986b8b20 100644 --- a/tasks/manage/registrar/setTokenAccepted.ts +++ b/tasks/manage/registrar/setTokenAccepted.ts @@ -1,12 +1,13 @@ import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {getAPTeamOwner, getAddresses, logger} from "utils"; type TaskArgs = {acceptanceState: boolean; tokenAddress: string; apTeamSignerPkey?: string}; task("manage:registrar:setTokenAccepted") - .addParam("tokenAddress", "Address of the token", "", types.string) + .addParam("tokenAddress", "Address of the token", undefined, cliTypes.address) .addParam("acceptanceState", "Boolean for acceptance state", false, types.boolean) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/registrar/setVaultEmitterAddress.ts b/tasks/manage/registrar/setVaultEmitterAddress.ts index a4262bd73..e3cfb8164 100644 --- a/tasks/manage/registrar/setVaultEmitterAddress.ts +++ b/tasks/manage/registrar/setVaultEmitterAddress.ts @@ -1,12 +1,13 @@ -import {task, types} from "hardhat/config"; +import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; type TaskArgs = {to: string; apTeamSignerPkey?: string; yes: boolean}; task("manage:registrar:setVaultEmitterAddress") - .addParam("to", "Address of the VaultEmitter contract", undefined, types.string) + .addParam("to", "Address of the VaultEmitter contract", undefined, cliTypes.address) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." diff --git a/tasks/manage/registrar/setVaultOperatorStatus.ts b/tasks/manage/registrar/setVaultOperatorStatus.ts index 676e6615b..2e4dae6c7 100644 --- a/tasks/manage/registrar/setVaultOperatorStatus.ts +++ b/tasks/manage/registrar/setVaultOperatorStatus.ts @@ -1,13 +1,14 @@ -import {task} from "hardhat/config"; +import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {getAPTeamOwner, getAddresses, logger} from "utils"; -type TaskArgs = {operator: string; status: boolean; apTeamSignerPkey?: string}; +type TaskArgs = {operator: string; approved: boolean; apTeamSignerPkey?: string}; task("manage:registrar:setVaultOperatorStatus") - .addParam("operator", "Address of the vault operator") - .addParam("status", "The state to set the operator to") + .addParam("operator", "Address of the vault operator", undefined, cliTypes.address) + .addParam("approved", "The new approval state of the operator", undefined, types.boolean) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." @@ -23,11 +24,11 @@ task("manage:registrar:setVaultOperatorStatus") logger.pad(50, "Connected to Registrar at: ", registrar.address); logger.divider(); - logger.pad(30, "Setting orpeator status for: ", taskArguments.operator); - logger.pad(30, "to: ", taskArguments.status); + logger.pad(30, "Setting operator approval state for: ", taskArguments.operator); + logger.pad(30, "to: ", taskArguments.approved); const updateData = registrar.interface.encodeFunctionData("setVaultOperatorApproved", [ taskArguments.operator, - taskArguments.status, + taskArguments.approved, ]); await submitMultiSigTx( addresses.multiSig.apTeam.proxy, diff --git a/tasks/manage/registrar/transferOwnership.ts b/tasks/manage/registrar/transferOwnership.ts index 39ee481e9..4f54eebee 100644 --- a/tasks/manage/registrar/transferOwnership.ts +++ b/tasks/manage/registrar/transferOwnership.ts @@ -1,14 +1,17 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; -type TaskArgs = {to: string; apTeamSignerPkey?: string; yes: boolean}; +type TaskArgs = {to?: string; apTeamSignerPkey?: string; yes: boolean}; task("manage:registrar:transferOwnership") .addOptionalParam( "to", - "Address of the new owner. Ensure at least one of `apTeamMultisigOwners` is the controller of this address. Will default to `contract-address.json > multiSig.apTeam.proxy` if none is provided." + "Address of the new owner. Ensure at least one of `apTeamMultisigOwners` is the controller of this address. Will default to `contract-address.json > multiSig.apTeam.proxy` if none is provided.", + undefined, + cliTypes.address ) .addOptionalParam( "apTeamSignerPkey", diff --git a/tasks/manage/registrar/updateConfig.ts b/tasks/manage/registrar/updateConfig.ts index f458560be..eb9ddb318 100644 --- a/tasks/manage/registrar/updateConfig.ts +++ b/tasks/manage/registrar/updateConfig.ts @@ -1,5 +1,6 @@ -import {task, types} from "hardhat/config"; +import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {RegistrarMessages} from "typechain-types/contracts/core/registrar/Registrar"; import { @@ -16,98 +17,37 @@ type TaskArgs = Partial & { yes: boolean; }; -// TODO: update param descriptions task("manage:registrar:updateConfig", "Will update Accounts Diamond config") - .addOptionalParam( - "accountsContract", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "indexFundContract", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "govContract", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "treasury", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "haloToken", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "fundraisingContract", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "uniswapRouter", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "uniswapFactory", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) + .addOptionalParam("accountsContract", "Accounts Diamond address.", undefined, cliTypes.address) + .addOptionalParam("indexFundContract", "IndexFund address.", undefined, cliTypes.address) + .addOptionalParam("govContract", "Gov address.", undefined, cliTypes.address) + .addOptionalParam("treasury", "Treasury wallet address.", undefined, cliTypes.address) + .addOptionalParam("haloToken", "Halo address.", undefined, cliTypes.address) + .addOptionalParam("fundraisingContract", "Fundraising address.", undefined, cliTypes.address) + .addOptionalParam("uniswapRouter", "Uniswap's SwapRouter address.", undefined, cliTypes.address) + .addOptionalParam("uniswapFactory", "UniswapFactory address.", undefined, cliTypes.address) .addOptionalParam( "multisigFactory", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + "EndowmentMultiSigFactory address.", undefined, - types.string + cliTypes.address ) .addOptionalParam( "multisigEmitter", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + "EndowmentMultiSigEmitter address.", undefined, - types.string + cliTypes.address ) .addOptionalParam( "charityApplications", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "proxyAdmin", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "usdcAddress", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "wMaticAddress", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", - undefined, - types.string - ) - .addOptionalParam( - "gasFwdFactory", - "Registrar contract address. Will do a local lookup from contract-address.json if none is provided.", + "CharityApplications address.", undefined, - types.string + cliTypes.address ) + .addOptionalParam("proxyAdmin", "ProxyAdminMultiSig address.", undefined, cliTypes.address) + .addOptionalParam("usdcAddress", "USDC address.", undefined, cliTypes.address) + .addOptionalParam("wMaticAddress", "WMATIC address.", undefined, cliTypes.address) + .addOptionalParam("gasFwdFactory", "GasFwdFactory address.", undefined, cliTypes.address) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." diff --git a/tasks/manage/registrar/updateNetworkConnections.ts b/tasks/manage/registrar/updateNetworkConnections.ts index 800eeb7bb..3df8831d1 100644 --- a/tasks/manage/registrar/updateNetworkConnections.ts +++ b/tasks/manage/registrar/updateNetworkConnections.ts @@ -1,8 +1,9 @@ import {task, types} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {Registrar__factory} from "typechain-types"; import {LocalRegistrarLib} from "typechain-types/contracts/core/registrar/LocalRegistrar"; -import {NetworkConnectionAction} from "types"; +import {ChainID, NetworkConnectionAction} from "types"; import { AddressObj, getAPTeamOwner, @@ -10,21 +11,29 @@ import { getAddressesByNetworkId, getAxlNetworkName, getChainIdFromNetworkName, + getEnumValuesAsString, getNetworkNameFromChainId, logger, structToObject, } from "utils"; type TaskArgs = { - chainId: number; + chainId?: ChainID; refundAddr?: string; apTeamSignerPkey?: string; yes: boolean; }; task("manage:registrar:updateNetworkConnections") - .addOptionalParam("chainId", "Chain ID of the network connection to update.", 0, types.int) - .addOptionalParam("refundAddr", "Refund address.") + .addOptionalParam( + "chainId", + `Chain ID of the network connection to update, possible values:\n${getEnumValuesAsString( + ChainID + )}`, + ChainID.none, + cliTypes.enums(ChainID, "ChainID") + ) + .addOptionalParam("refundAddr", "Refund address.", undefined, cliTypes.address) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." @@ -39,7 +48,7 @@ task("manage:registrar:updateNetworkConnections") let networkName: string; let targetAddresses: AddressObj; // If we're updating info on this chain for another chain, arg info MUST specify chain id - if (taskArgs.chainId > 0) { + if (!!taskArgs.chainId) { networkName = getNetworkNameFromChainId(taskArgs.chainId); targetAddresses = getAddressesByNetworkId(taskArgs.chainId); } else { diff --git a/tasks/manage/registrar/updateTokenPriceFeed.ts b/tasks/manage/registrar/updateTokenPriceFeed.ts index 6349d680c..1375aa53b 100644 --- a/tasks/manage/registrar/updateTokenPriceFeed.ts +++ b/tasks/manage/registrar/updateTokenPriceFeed.ts @@ -1,5 +1,6 @@ import {task} from "hardhat/config"; import {submitMultiSigTx} from "tasks/helpers"; +import {cliTypes} from "tasks/types"; import {IRegistrar__factory} from "typechain-types"; import {confirmAction, getAPTeamOwner, getAddresses, logger} from "utils"; @@ -14,8 +15,8 @@ task( "manage:registrar:updateTokenPriceFeed", "Updates a Registrar-Level Accepted Token's Price Feed contract address in storage." ) - .addParam("token", "Address of the token.") - .addParam("priceFeed", "Address of the token's price feed.") + .addParam("token", "Address of the token.", undefined, cliTypes.address) + .addParam("priceFeed", "Address of the token's price feed.", undefined, cliTypes.address) .addOptionalParam( "apTeamSignerPkey", "If running on prod, provide a pkey for a valid APTeam Multisig Owner." diff --git a/tasks/manage/updateRegistrar.ts b/tasks/manage/updateRegistrar.ts index aeed9f915..e925daa37 100644 --- a/tasks/manage/updateRegistrar.ts +++ b/tasks/manage/updateRegistrar.ts @@ -1,8 +1,8 @@ -import {task} from "hardhat/config"; import {CONFIG} from "config"; +import {task} from "hardhat/config"; import {cliTypes} from "tasks/types"; import {RegistrarMessages} from "typechain-types/contracts/core/registrar/interfaces/IRegistrar"; -import {ADDRESS_ZERO, connectSignerFromPkey, getAddresses, getSigners, logger} from "utils"; +import {ADDRESS_ZERO, getAddresses, getSigners, logger} from "utils"; type TaskArgs = { acceptedTokens: string[]; @@ -14,7 +14,7 @@ task( "manage:updateRegistrar", "Will update the registrar config with the most recent addresses & config data" ) - .addOptionalParam("acceptedTokens", "List of accepted tokens.", [], cliTypes.array.string) + .addOptionalParam("acceptedTokens", "List of accepted tokens.", [], cliTypes.array.address) .addOptionalParam( "acceptanceStates", "List of acceptance state flags related to `acceptedTokens`. Flag `acceptanceStates[i]` designates `acceptedTokens[i]` token's acceptance status (`true === accepted`, `false === not accepted`). Defaults to `true` for any index `i` that is not set in `acceptanceStates` but is set in `acceptedTokens`.", @@ -62,31 +62,33 @@ task( yes: true, }); - if (taskArgs.acceptedTokens.length > 0) { - logger.divider(); - logger.out("Updating accepted tokens..."); - for (let i = 0; i < taskArgs.acceptedTokens.length; i++) { - try { - const tokenAddress = taskArgs.acceptedTokens[i]; - const acceptanceState = taskArgs.acceptanceStates.at(i) ?? true; - const signerKey = taskArgs.apTeamSignerPkey; - if (taskArgs.apTeamSignerPkey) { - await hre.run("manage:registrar:setTokenAccepted", { - tokenAddress, - acceptanceState, - signerKey, - apTeamSignerPkey: taskArgs.apTeamSignerPkey, - }); - } else { - await hre.run("manage:registrar:setTokenAccepted", { - tokenAddress, - acceptanceState, - apTeamSignerPkey: taskArgs.apTeamSignerPkey, - }); - } - } catch (error) { - logger.out(error, logger.Level.Error); + if (taskArgs.acceptedTokens.length === 0) { + return; + } + + logger.divider(); + logger.out("Updating accepted tokens..."); + for (let i = 0; i < taskArgs.acceptedTokens.length; i++) { + try { + const tokenAddress = taskArgs.acceptedTokens[i]; + const acceptanceState = taskArgs.acceptanceStates.at(i) ?? true; + const signerKey = taskArgs.apTeamSignerPkey; + if (taskArgs.apTeamSignerPkey) { + await hre.run("manage:registrar:setTokenAccepted", { + tokenAddress, + acceptanceState, + signerKey, + apTeamSignerPkey: taskArgs.apTeamSignerPkey, + }); + } else { + await hre.run("manage:registrar:setTokenAccepted", { + tokenAddress, + acceptanceState, + apTeamSignerPkey: taskArgs.apTeamSignerPkey, + }); } + } catch (error) { + logger.out(error, logger.Level.Error); } } } catch (error) { diff --git a/tasks/types.ts b/tasks/types.ts index 584f86f68..4074f1f13 100644 --- a/tasks/types.ts +++ b/tasks/types.ts @@ -1,39 +1,97 @@ +import {allStrategyConfigs} from "contracts/integrations/stratConfig"; +import {constants} from "ethers"; +import {isAddress} from "ethers/lib/utils"; import {HardhatError} from "hardhat/internal/core/errors"; import {ERRORS} from "hardhat/internal/core/errors-list"; -import {int} from "hardhat/internal/core/params/argumentTypes"; +import {boolean, int, string} from "hardhat/internal/core/params/argumentTypes"; import {CLIArgumentType} from "hardhat/types"; +import {StratConfig} from "utils"; + +const address: CLIArgumentType = { + name: "address", + parse: (argname, strValue) => string.parse(argname, strValue), + /** + * Check if argument value is a valid EVM address + * + * @param argName {string} argument's name - used for context in case of error. + * @param argValue {any} argument's value to validate. + * + * @throws HH301 if value is not a valid EVM address + */ + validate: (argName: string, argValue: any): void => { + string.validate(argName, argValue); + + if (!isAddress(argValue) || argValue === constants.AddressZero) { + throw new Error( + `Invalid value '${argValue}' for argument '${argName}' - must be a valid non-zero EVM address` + ); + } + }, +}; + +const addressArray: CLIArgumentType> = { + name: "addressArray", + parse: (argName, strValue) => stringArray.parse(argName, strValue), + /** + * Check if argument value is an array of valid EVM addresses + * + * @param argName {string} argument's name - used for context in case of error. + * @param argValue {any} argument's value to validate. + * + * @throws HH301 if value is not an array of valid EVM addresses + */ + validate: (argName: string, argValue: any): void => { + // verify this is a string array + stringArray.validate(argName, argValue); + // cast to string[] + const strArr = argValue as string[]; + // verify each item in the array is a valid EVM address + strArr.forEach((strValue, i) => address.validate(`${argName}[${i}]`, strValue)); + }, +}; const booleanArray: CLIArgumentType> = { name: "booleanArray", parse: (argName, strValue) => { const values = strValue.split(/\s*,\s*/); - const result = values.map((val) => { - if (val.toLowerCase() === "true") { - return true; - } - if (val.toLowerCase() === "false") { - return false; - } - - throw new Error(`Invalid value ${val} in argument ${argName} of type \`boolean[]\``); - }); - + const result = values.map((value, i) => boolean.parse(`${argName}[${i}]`, value)); return result; }, /** * Check if argument value is of type "boolean[]" * * @param argName {string} argument's name - used for context in case of error. - * @param arr {any} argument's array value to validate. + * @param argValue {any} argument's value to validate. * * @throws HH301 if value is not of type "boolean[]" */ - validate: (argName: string, arr: any): void => { - const isBooleanArray = - Array.isArray(arr) && (arr.length === 0 || arr.every((val) => typeof val === "boolean")); + validate: (argName: string, argValue: any): void => { + if (!Array.isArray(argValue)) { + throw new Error( + `Invalid value '${argValue}' for argument '${argName}' of type \`boolean[]\`` + ); + } + (argValue as any[]).forEach((value, i) => boolean.validate(`${argName}[${i}]`, value)); + }, +}; - if (!isBooleanArray) { - throw new Error(`Invalid value ${arr} for argument ${argName} of type \`boolean[]\``); +const stratConfig: CLIArgumentType = { + name: "StratConfig", + parse: (_, strValue) => allStrategyConfigs[strValue] || {error: strValue}, + /** + * Check if argument value is of type "StratConfig" + * + * @param argName {string} argument's name - used for context in case of error. + * @param argValue {any} argument's value to validate. + * + * @throws HH301 if value is not of type "StratConfig" + */ + validate: (argName: string, argValue: any): void => { + if (!argValue || typeof argValue !== "object" || "error" in argValue) { + const invalidValue = "error" in argValue ? argValue.error : argValue; + throw new Error( + `Invalid value '${invalidValue}' for argument '${argName}' of type \`StratConfig\`` + ); } }, }; @@ -45,17 +103,15 @@ const stringArray: CLIArgumentType> = { * Check if argument value is of type "string[]" * * @param argName {string} argument's name - used for context in case of error. - * @param arr {any} argument's array value to validate. + * @param argValue {any} argument's value to validate. * * @throws HH301 if value is not of type "string[]" */ - validate: (argName: string, arr: any): void => { - const isStringArray = - Array.isArray(arr) && (arr.length === 0 || arr.every((val) => typeof val === "string")); - - if (!isStringArray) { - throw new Error(`Invalid value ${arr} for argument ${argName} of type \`string[]\``); + validate: (argName: string, argValue: any): void => { + if (!Array.isArray(argValue)) { + throw new Error(`Invalid value '${argValue}' for argument '${argName}' of type \`string[]\``); } + (argValue as any[]).forEach((value, i) => string.validate(`${argName}[${i}]`, value)); }, }; @@ -86,12 +142,12 @@ function enums( }); }, /** - * Check if argument value is of type "string[]" + * Check if argument value is of enum type "T" * * @param argName {string} argument's name - used for context in case of error. * @param value {any} argument's value to validate. * - * @throws HH301 if value is not of type "string[]" + * @throws HH301 if value is not of type "T" */ validate: (argName: string, value: any): void => { if (Object.values(enumObj).includes(value)) { @@ -122,9 +178,12 @@ function enums( } export const cliTypes = { + address, array: { + address: addressArray, boolean: booleanArray, string: stringArray, }, enums, + stratConfig, }; diff --git a/tasks/upgrade/upgradeEndowmentMultiSig.ts b/tasks/upgrade/upgradeEndowmentMultiSig.ts index 3d0243b16..e8b1e16e1 100644 --- a/tasks/upgrade/upgradeEndowmentMultiSig.ts +++ b/tasks/upgrade/upgradeEndowmentMultiSig.ts @@ -14,7 +14,6 @@ import { } from "utils"; type TaskArgs = { - factory?: string; skipVerify: boolean; yes: boolean; apTeamSignerPkey?: string; @@ -24,10 +23,6 @@ task( "upgrade:EndowmentMultiSig", "Will upgrade the implementation of the EndowmentMultiSig contract" ) - .addOptionalParam( - "factory", - "MultiSigFactory contract address. Will do a local lookup from contract-address.json if none is provided." - ) .addFlag("skipVerify", "Skip contract verification") .addFlag("yes", "Automatic yes to prompt.") .addOptionalParam( @@ -50,14 +45,11 @@ task( const addresses = await getAddresses(hre); - const EndowmentMultiSigFactoryAddress = - taskArgs.factory || addresses.multiSig.endowment.factory.proxy; - const deployment = await deploy(new EndowmentMultiSig__factory(deployer)); logger.out("Upgrading EndowmentMultiSigFactory's implementation address..."); const endowmentMultiSigFactory = EndowmentMultiSigFactory__factory.connect( - EndowmentMultiSigFactoryAddress, + addresses.multiSig.endowment.factory.proxy, apTeamOwner ); const payload = endowmentMultiSigFactory.interface.encodeFunctionData( diff --git a/tasks/upgrade/upgradeFacets/upgradeFacets.ts b/tasks/upgrade/upgradeFacets/upgradeFacets.ts index c8b698bfe..04934bc7d 100644 --- a/tasks/upgrade/upgradeFacets/upgradeFacets.ts +++ b/tasks/upgrade/upgradeFacets/upgradeFacets.ts @@ -13,6 +13,7 @@ import {ALL_FACET_NAMES} from "./constants"; import cutDiamond from "./cutDiamond"; import deployFacets from "./deployFacets"; import sortIntoFacetCuts from "./sortIntoFacetCuts"; +import {cliTypes} from "tasks/types"; type TaskArgs = { accountsDiamond?: string; @@ -22,27 +23,25 @@ type TaskArgs = { proxyAdminPkey?: string; }; -// Sample syntax: npx hardhat upgrade:facets --yes --network mumbai "AccountsStrategy" - task("upgrade:facets", "Will redeploy and upgrade all facets that use AccountStorage struct") .addOptionalParam( "accountsDiamond", - "Accounts Diamond contract address. Will do a local lookup from contract-address.json if none is provided." + "Accounts Diamond contract address. Will do a local lookup from contract-address.json if none is provided.", + undefined, + cliTypes.address ) - .addVariadicPositionalParam( + .addParam( "facets", - "List of facets to upgrade. If set to 'all', will upgrade all facets." + "List of facets to upgrade. If set to 'all', will upgrade all facets.", + undefined, + cliTypes.array.string ) .addFlag("skipVerify", "Skip contract verification") .addFlag("yes", "Automatic yes to prompt.") .addOptionalParam("proxyAdminPkey", "The pkey for the prod proxy admin multisig") .setAction(async (taskArgs: TaskArgs, hre) => { try { - if (taskArgs.facets.length === 0) { - throw new Error("Must provide at least one facet name or pass 'all'"); - } - const facetsToUpgrade = /^all$/i.test(taskArgs.facets[0]) ? ALL_FACET_NAMES : taskArgs.facets; const isConfirmed = diff --git a/utils/enums.ts b/utils/enums.ts new file mode 100644 index 000000000..13d8126a1 --- /dev/null +++ b/utils/enums.ts @@ -0,0 +1,11 @@ +export function getEnumKeys(enumValue: T): (keyof T)[] { + return Object.keys(enumValue).filter((key) => isNaN(Number(enumValue[key]))); +} + +export function getEnumValuesAsString( + enumValue: T +): string { + return getEnumKeys(enumValue) + .map((key) => `${String(key)} - ${enumValue[key]}`) + .join(", "); +} diff --git a/utils/getEnumKeys.ts b/utils/getEnumKeys.ts deleted file mode 100644 index d5d95dbb4..000000000 --- a/utils/getEnumKeys.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function getEnumKeys(enumValue: T): (keyof T)[] { - return Object.keys(enumValue).filter((key) => isNaN(Number(enumValue[key]))); -} diff --git a/utils/index.ts b/utils/index.ts index bafd48a0d..a64deb2ec 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -1,8 +1,8 @@ export * from "./confirmAction"; export * from "./constants"; export * from "./deploy"; +export * from "./enums"; export * from "./getContractName"; -export * from "./getEnumKeys"; export * from "./getKeysTyped"; export * from "./filterEvents"; export * from "./signers"; diff --git a/utils/networkHelpers.ts b/utils/networkHelpers.ts index 35a90e646..d448c6b9b 100644 --- a/utils/networkHelpers.ts +++ b/utils/networkHelpers.ts @@ -7,7 +7,7 @@ const PROD_NETWORKS = [ChainID.ethereum, ChainID.polygon]; // There are errors/mismatches in the axelar sdk jsons, so we just implement a lightweight // version here and use this instead. -const AxelarNetworks = new TwoWayMap({ +export const AXELAR_NETWORKS = new TwoWayMap({ [ChainID.ethereum]: "Ethereum", [ChainID.goerli]: "ethereum-2", [ChainID.polygon]: "Polygon", @@ -20,20 +20,20 @@ export function isLocalNetwork(hre: HardhatRuntimeEnvironment) { } export function networkNameMatchesId(id: number, name: string) { - return AxelarNetworks.get(id) == name; + return AXELAR_NETWORKS.get(id) == name; } export function getChainIdFromNetworkName(name: string): number { - return AxelarNetworks.revGet(name); + return AXELAR_NETWORKS.revGet(name); } export function getNetworkNameFromChainId(id: number): string { - return AxelarNetworks.get(id); + return AXELAR_NETWORKS.get(id); } export async function getAxlNetworkName(hre: HardhatRuntimeEnvironment): Promise { const chainId = await getChainId(hre); - return AxelarNetworks.get(chainId); + return AXELAR_NETWORKS.get(chainId); } export async function getChainId(hre: HardhatRuntimeEnvironment): Promise { diff --git a/utils/twoWayMap.ts b/utils/twoWayMap.ts index 12d292174..2f27221ad 100644 --- a/utils/twoWayMap.ts +++ b/utils/twoWayMap.ts @@ -1,6 +1,6 @@ export class TwoWayMap { - map: Record; - reverseMap: Record; + private map: Record; + private reverseMap: Record; constructor(map: Record) { this.map = map; this.reverseMap = {}; @@ -15,4 +15,7 @@ export class TwoWayMap { revGet(key: any) { return this.reverseMap[key]; } + values() { + return Object.values(this.map); + } }