diff --git a/package.json b/package.json index 2db769684..4a75a72f0 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "@nomiclabs/hardhat-waffle": "2.0.5", "@typechain/ethers-v5": "10.2.0", "@typechain/hardhat": "^6.1.5", - "@types/inquirer": "^8.2.0", "@types/node": "^17.0.23", "@types/pino": "^7.0.5", "@typescript-eslint/eslint-plugin": "^5.16.0", @@ -88,8 +87,8 @@ "@uniswap/sdk": "^3.0.3", "chalk": "4.1.2", "defender-relay-client": "^1.26.0", + "enquirer": "^2.4.1", "hardhat-ethers": "^1.0.1", - "inquirer": "^8.2.1", "light-spinner": "^1.0.4", "notify-send": "^0.1.2", "pino": "^7.9.2", diff --git a/script/deploy/deployUpgradesToSAFE.sh b/script/deploy/deployUpgradesToSAFE.sh index 27e215122..9b978d482 100755 --- a/script/deploy/deployUpgradesToSAFE.sh +++ b/script/deploy/deployUpgradesToSAFE.sh @@ -5,7 +5,8 @@ deployUpgradesToSAFE() { source script/config.sh source script/helperFunctions.sh - ENVIRONMENT="production" + ENVIRONMENT=$1 + FILE_SUFFIX=$(getFileSuffix $ENVIRONMENT) NETWORK=$(getUserSelectedNetwork) DIAMOND_CONTRACT_NAME=$(userDialogSelectDiamondType) if [ "$DIAMOND_CONTRACT_NAME" == "LiFiDiamond" ]; then @@ -24,8 +25,9 @@ deployUpgradesToSAFE() { declare -a CUTS for script in $SCRIPTS; do UPDATE_SCRIPT=$(echo "$DEPLOY_SCRIPT_DIRECTORY"Update"$script".s.sol) + PRIVATE_KEY=$(getPrivateKey $NETWORK $ENVIRONMENT) echo "Calculating facet cuts for $script..." - RAW_RETURN_DATA=$(NO_BROADCAST=true NETWORK=$NETWORK FILE_SUFFIX=$FILE_SUFFIX USE_DEF_DIAMOND=$USE_MUTABLE_DIAMOND PRIVATE_KEY=$(getPrivateKey "$ENVIRONMENT") forge script "$UPDATE_SCRIPT" -f $NETWORK -vvvv --json --silent --skip-simulation --legacy) + RAW_RETURN_DATA=$(NO_BROADCAST=true NETWORK=$NETWORK FILE_SUFFIX=$FILE_SUFFIX USE_DEF_DIAMOND=$USE_MUTABLE_DIAMOND PRIVATE_KEY=$PRIVATE_KEY forge script "$UPDATE_SCRIPT" -f $NETWORK -vvvv --json --silent --skip-simulation --legacy) CLEAN_RETURN_DATA=$(echo $RAW_RETURN_DATA | sed 's/^.*{\"logs/{\"logs/') FACET_CUT=$(echo $CLEAN_RETURN_DATA | jq -r '.returns.cutData.value') if [ "$FACET_CUT" != "0x" ]; then @@ -45,7 +47,7 @@ deployUpgradesToSAFE() { DIAMOND_ADDRESS=$(getContractAddressFromDeploymentLogs "$NETWORK" "$ENVIRONMENT" "$DIAMOND_CONTRACT_NAME") # Call the proposeTx script ts-node proposeTx.ts diamondAddress cuts network rpcUrl - ts-node script/deploy/gnosisSAFE/proposeTx.ts "$DIAMOND_ADDRESS" "$CUTS_JSON" "$NETWORK" $(getRPCUrl $NETWORK) + ts-node script/deploy/gnosisSAFE/proposeTx.ts "$DIAMOND_ADDRESS" "$CUTS_JSON" "$NETWORK" $(getRPCUrl $NETWORK) "$PRIVATE_KEY" exit 0 } diff --git a/script/deploy/facets/UpdateCalldataVerificationFacet.s.sol b/script/deploy/facets/UpdateCalldataVerificationFacet.s.sol index 3db4c49bd..28c1d85c6 100644 --- a/script/deploy/facets/UpdateCalldataVerificationFacet.s.sol +++ b/script/deploy/facets/UpdateCalldataVerificationFacet.s.sol @@ -13,32 +13,6 @@ contract DeployScript is UpdateScriptBase { public returns (address[] memory facets, bytes memory cutData) { - address facet = json.readAddress(".CalldataVerificationFacet"); - - // CalldataVerificationFacet - bytes4[] memory exclude; - buildDiamondCut( - getSelectors("CalldataVerificationFacet", exclude), - facet - ); - if (noBroadcast) { - if (cut.length > 0) { - cutData = abi.encodeWithSelector( - DiamondCutFacet.diamondCut.selector, - cut, - address(0), - "" - ); - } - return (facets, cutData); - } - - vm.startBroadcast(deployerPrivateKey); - if (cut.length > 0) { - cutter.diamondCut(cut, address(0), ""); - } - facets = loupe.facetAddresses(); - - vm.stopBroadcast(); + return update("CalldataVerificationFacet"); } } diff --git a/script/deploy/facets/UpdateStandardizedCallFacet.s.sol b/script/deploy/facets/UpdateStandardizedCallFacet.s.sol index 23bffc1a6..93b4378d6 100644 --- a/script/deploy/facets/UpdateStandardizedCallFacet.s.sol +++ b/script/deploy/facets/UpdateStandardizedCallFacet.s.sol @@ -13,29 +13,6 @@ contract DeployScript is UpdateScriptBase { public returns (address[] memory facets, bytes memory cutData) { - address facet = json.readAddress(".StandardizedCallFacet"); - - // StandardizedCallFacet - bytes4[] memory exclude; - buildDiamondCut(getSelectors("StandardizedCallFacet", exclude), facet); - if (noBroadcast) { - if (cut.length > 0) { - cutData = abi.encodeWithSelector( - DiamondCutFacet.diamondCut.selector, - cut, - address(0), - "" - ); - } - return (facets, cutData); - } - - vm.startBroadcast(deployerPrivateKey); - if (cut.length > 0) { - cutter.diamondCut(cut, address(0), ""); - } - facets = loupe.facetAddresses(); - - vm.stopBroadcast(); + return update("StandardizedCallFacet"); } } diff --git a/script/deploy/gnosisSAFE/proposeTx.ts b/script/deploy/gnosisSAFE/proposeTx.ts index 946b2de0a..969cd5524 100644 --- a/script/deploy/gnosisSAFE/proposeTx.ts +++ b/script/deploy/gnosisSAFE/proposeTx.ts @@ -5,18 +5,20 @@ import SafeApiKit, { OwnerResponse, ProposeTransactionProps, } from '@safe-global/api-kit' -import dotenv from 'dotenv' import { SafeTransactionDataPartial } from '@safe-global/safe-core-sdk-types' import { safeApiUrls } from './config' -import { exit } from 'process' -dotenv.config() +import { argv, exit } from 'process' +import enquirer from 'enquirer' -const [, , diamondAddress, rawCuts, network, rpcUrl] = process.argv +// Parse incoming arguments +const [, , diamondAddress, rawCuts, network, rpcUrl, privateKey] = argv -let safeOwner = new ethers.Wallet(process.env.PRIVATE_KEY_PRODUCTION as string) +// Create ethers provider and signer from private key +let safeOwner = new ethers.Wallet(privateKey as string) const provider = new ethers.providers.JsonRpcProvider(rpcUrl) safeOwner = safeOwner.connect(provider) +// Initialize the Safe API const ethAdapter = new EthersAdapter({ ethers, signerOrProvider: safeOwner, @@ -29,25 +31,42 @@ const safeService = new SafeApiKit({ const main = async () => { console.info('Building SAFE TX Proposal..') + + // Get owned SAFE addresses const res: OwnerResponse = await safeService.getSafesByOwner( await safeOwner.getAddress() ) - const safeAddress = res.safes[0] - console.info('SAFE Address: ', res.safes[0]) + + // Prompt the user to choose a SAFE address + const choice = await enquirer.prompt({ + type: 'select', + name: 'safeAddress', + message: 'Choose the SAFE address you would like to use.', + choices: res.safes, + }) + + const safeAddress = (<{ safeAddress: string }>choice).safeAddress + console.info('SAFE Address: ', safeAddress) console.info('Diamond Address: ', diamondAddress) + // Instantiate a SAFE instance const safeSdk: Safe = await Safe.create({ ethAdapter, safeAddress, }) + // Parse the raw diamond cuts const cuts = JSON.parse(rawCuts) + + // Get the latest nonce from the SAFE let nonce = await safeSdk.getNonce() + + // Broadcast each cut as a SAFE transaction proposal console.info(`Proposing ${cuts.length} transactions...`) let i = 1 for (const cut of cuts) { const safeTransactionData: SafeTransactionDataPartial = { - to: '0x9FcB9Aaa138DBb2Cbf484Ba43285ca4b60b56D09', + to: diamondAddress, value: '0', data: cut, nonce, @@ -63,12 +82,13 @@ const main = async () => { senderSignature: txHashSignature.data, } console.info(`Sending proposal [${i}]...`) - // await safeService.proposeTransaction(proposal) + await safeService.proposeTransaction(proposal) nonce++ i++ } } +// Main entry point main() .then(() => { console.info('Done!') diff --git a/script/scriptMaster.sh b/script/scriptMaster.sh index 04a175c3e..e7be7618e 100755 --- a/script/scriptMaster.sh +++ b/script/scriptMaster.sh @@ -38,6 +38,7 @@ scriptMaster() { source script/deploy/deployFacetAndAddToDiamond.sh source script/deploy/deployPeripheryContracts.sh source script/config.sh + source script/deploy/deployUpgradesToSAFE.sh for script in script/tasks/*.sh; do [ -f "$script" ] && source "$script"; done # sources all script in folder script/tasks/ # make sure that all compiled artifacts are current @@ -488,7 +489,7 @@ scriptMaster() { #--------------------------------------------------------------------------------------------------------------------- # use case 11: Propose upgrade TX to Gnosis SAFE elif [[ "$SELECTION" == "11)"* ]]; then - deployUpgradesToSAFE + deployUpgradesToSAFE $ENVIRONMENT else error "invalid use case selected ('$SELECTION') - exiting script" cleanup diff --git a/yarn.lock b/yarn.lock index 0ea4b7159..74cdafcc4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1249,13 +1249,6 @@ resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== -"@types/inquirer@^8.2.0": - version "8.2.5" - resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.5.tgz#c508423bcc11126db278170ab07347783ac2300c" - integrity sha512-QXlzybid60YtAwfgG3cpykptRYUx2KomzNutMlWsQC64J/WG/gQSl+P4w7A21sGN0VIxRVava4rgnT7FQmFCdg== - dependencies: - "@types/through" "*" - "@types/inquirer@^8.2.1": version "8.2.6" resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.6.tgz#abd41a5fb689c7f1acb12933d787d4262a02a0ab" @@ -3296,6 +3289,14 @@ enquirer@^2.3.0, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" +enquirer@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -5158,7 +5159,7 @@ inquirer@^6.2.2: strip-ansi "^5.1.0" through "^2.3.6" -inquirer@^8.2.1, inquirer@^8.2.2: +inquirer@^8.2.2: version "8.2.5" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==