From 44836462121cee7f8abcf2e0ddbd6dcaf54fddb7 Mon Sep 17 00:00:00 2001 From: Taylor Brent Date: Wed, 11 Sep 2024 22:01:05 -0400 Subject: [PATCH 1/4] multisig facade --- common/configuration.ts | 4 + contracts/facade/Facade.sol | 4 +- package.json | 2 + .../deployment/phase1-core/4_deploy_facade.ts | 6 +- .../phase1-facade/1_deploy_readFacet.ts | 22 ++- .../phase1-facade/2_deploy_actFacet.ts | 20 +- .../phase1-facade/3_deploy_maxIssuable.ts | 24 ++- .../4_deploy_backingBufferFacet.ts | 24 ++- .../phase1-facade/5_deploy_revenueFacet.ts | 18 +- scripts/deployment/utils.ts | 53 +++++- scripts/verification/4_verify_facade.ts | 7 +- test/fixtures.ts | 7 +- test/integration/fixtures.ts | 7 +- .../plugins/individual-collateral/fixtures.ts | 8 +- yarn.lock | 176 +++++++++++++++++- 15 files changed, 340 insertions(+), 42 deletions(-) diff --git a/common/configuration.ts b/common/configuration.ts index 928d4b96ac..1f8610a742 100644 --- a/common/configuration.ts +++ b/common/configuration.ts @@ -169,6 +169,7 @@ interface INetworkConfig { AAVE_V3_POOL?: string STARGATE_STAKING_CONTRACT?: string CURVE_POOL_WETH_FRXETH?: string + DEV_MULTISIG?: string } export const networkConfig: { [key: string]: INetworkConfig } = { @@ -308,6 +309,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = { AAVE_V3_INCENTIVES_CONTROLLER: '0x8164Cc65827dcFe994AB23944CBC90e0aa80bFcb', STARGATE_STAKING_CONTRACT: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b', CURVE_POOL_WETH_FRXETH: '0x9c3b46c0ceb5b9e304fcd6d88fc50f7dd24b31bc', + DEV_MULTISIG: '0xf8A981f5D79a204835B5a105CEe54E176012a633', // same on all networks }, '3': { name: 'tenderly', @@ -541,6 +543,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = { AAVE_V3_POOL: '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5', AAVE_V3_INCENTIVES_CONTROLLER: '0xf9cc4F0D883F1a1eb2c253bdb46c254Ca51E1F44', STARGATE_STAKING_CONTRACT: '0x06Eb48763f117c7Be887296CDcdfad2E4092739C', + DEV_MULTISIG: '0xf8A981f5D79a204835B5a105CEe54E176012a633', // same on all networks }, '42161': { name: 'arbitrum', @@ -581,6 +584,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = { COMET_EXT: '0x1B2E88cC7365d90e7E81392432482925BD8437E9', AAVE_V3_POOL: '0x794a61358D6845594F94dc1DB02A252b5b4814aD', AAVE_V3_INCENTIVES_CONTROLLER: '0x929EC64c34a17401F460460D4B9390518E5B473e', + DEV_MULTISIG: '0xf8A981f5D79a204835B5a105CEe54E176012a633', // same on all networks }, '421614': { name: 'arbitrum-sepolia', diff --git a/contracts/facade/Facade.sol b/contracts/facade/Facade.sol index b2657bb4ff..548a5b5c9e 100644 --- a/contracts/facade/Facade.sol +++ b/contracts/facade/Facade.sol @@ -14,7 +14,9 @@ contract Facade is IFacade, Ownable { mapping(bytes4 => address) public facets; // solhint-disable-next-line no-empty-blocks - constructor() Ownable() {} + constructor(address owner) Ownable() { + _transferOwnership(owner); + } // Save new facets to the Facade, forcefully function save(address facet, bytes4[] memory selectors) external onlyOwner { diff --git a/package.json b/package.json index 88fe3e26ee..a27b742073 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,8 @@ "@openzeppelin/contracts": "4.9.6", "@openzeppelin/contracts-upgradeable": "4.9.6", "@openzeppelin/hardhat-upgrades": "^1.23.0", + "@safe-global/api-kit": "^2.4.5", + "@safe-global/protocol-kit": "^4.1.0", "@tenderly/hardhat-tenderly": "^1.7.7", "@typechain/ethers-v5": "^7.2.0", "@typechain/hardhat": "^2.3.1", diff --git a/scripts/deployment/phase1-core/4_deploy_facade.ts b/scripts/deployment/phase1-core/4_deploy_facade.ts index c23b86c665..357970f1d8 100644 --- a/scripts/deployment/phase1-core/4_deploy_facade.ts +++ b/scripts/deployment/phase1-core/4_deploy_facade.ts @@ -33,10 +33,14 @@ async function main() { throw new Error(`RSR Asset contract not found in network ${hre.network.name}`) } + if (!networkConfig[chainId].DEV_MULTISIG) { + throw new Error(`Missing DEV_MULTISIG address in network ${hre.network.name}`) + } + // ******************** Deploy Facade ****************************************/ const FacadeFactory = await ethers.getContractFactory('Facade') - facade = await FacadeFactory.connect(burner).deploy() + facade = await FacadeFactory.connect(burner).deploy(networkConfig[chainId].DEV_MULTISIG) await facade.deployed() // Write temporary deployments file diff --git a/scripts/deployment/phase1-facade/1_deploy_readFacet.ts b/scripts/deployment/phase1-facade/1_deploy_readFacet.ts index 04e5ec5e53..012a27bfc8 100644 --- a/scripts/deployment/phase1-facade/1_deploy_readFacet.ts +++ b/scripts/deployment/phase1-facade/1_deploy_readFacet.ts @@ -4,8 +4,11 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' +import { initiateMultisigTx } from '../utils' import { ReadFacet } from '../../../typechain' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + let readFacet: ReadFacet async function main() { @@ -47,16 +50,21 @@ async function main() { // ******************** Save to Facade ****************************************/ - console.log('Configuring with Facade...') + console.log('Configuring with Facade via multisig...') - // Save ReadFacet to Facade + // Save ReadFacet functions to Facade const facade = await ethers.getContractAt('Facade', deployments.facade) - await facade.save( - readFacet.address, - Object.entries(readFacet.functions).map(([fn]) => readFacet.interface.getSighash(fn)) - ) - console.log('Finished saving to Facade') + const tx: MetaTransactionData = { + to: facade.address, + value: '0', + data: facade.interface.encodeFunctionData('save', [ + readFacet.address, + Object.entries(readFacet.functions).map(([fn]) => readFacet.interface.getSighash(fn)), + ]), + } + + await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/2_deploy_actFacet.ts b/scripts/deployment/phase1-facade/2_deploy_actFacet.ts index 38b48c8e4c..8301df9c7e 100644 --- a/scripts/deployment/phase1-facade/2_deploy_actFacet.ts +++ b/scripts/deployment/phase1-facade/2_deploy_actFacet.ts @@ -4,8 +4,11 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' +import { initiateMultisigTx } from '../utils' import { ActFacet } from '../../../typechain' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + let actFacet: ActFacet async function main() { @@ -49,14 +52,19 @@ async function main() { console.log('Configuring with Facade...') - // Save ReadFacet to Facade + // Save ActFacet functions to Facade const facade = await ethers.getContractAt('Facade', deployments.facade) - await facade.save( - actFacet.address, - Object.entries(actFacet.functions).map(([fn]) => actFacet.interface.getSighash(fn)) - ) - console.log('Finished saving to Facade') + const tx: MetaTransactionData = { + to: facade.address, + value: '0', + data: facade.interface.encodeFunctionData('save', [ + actFacet.address, + Object.entries(actFacet.functions).map(([fn]) => actFacet.interface.getSighash(fn)), + ]), + } + + await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts b/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts index 02cb8201df..6559b2f683 100644 --- a/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts +++ b/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts @@ -4,8 +4,11 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' +import { initiateMultisigTx } from '../utils' import { MaxIssuableFacet } from '../../../typechain' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + let maxIssuableFacet: MaxIssuableFacet async function main() { @@ -51,14 +54,19 @@ async function main() { // Save MaxIssuableFacet functions to Facade const facade = await ethers.getContractAt('Facade', deployments.facade) - await facade.save( - maxIssuableFacet.address, - Object.entries(maxIssuableFacet.functions).map(([fn]) => - maxIssuableFacet.interface.getSighash(fn) - ) - ) - - console.log('Finished saving to Facade') + + const tx: MetaTransactionData = { + to: facade.address, + value: '0', + data: facade.interface.encodeFunctionData('save', [ + maxIssuableFacet.address, + Object.entries(maxIssuableFacet.functions).map(([fn]) => + maxIssuableFacet.interface.getSighash(fn) + ), + ]), + } + + await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts b/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts index 3b8eda24c2..6b4007a240 100644 --- a/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts +++ b/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts @@ -4,8 +4,11 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' +import { initiateMultisigTx } from '../utils' import { BackingBufferFacet } from '../../../typechain' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + let backingBufferFacet: BackingBufferFacet async function main() { @@ -51,14 +54,19 @@ async function main() { // Save BackingBufferFacet functions to Facade const facade = await ethers.getContractAt('Facade', deployments.facade) - await facade.save( - backingBufferFacet.address, - Object.entries(backingBufferFacet.functions).map(([fn]) => - backingBufferFacet.interface.getSighash(fn) - ) - ) - - console.log('Finished saving to Facade') + + const tx: MetaTransactionData = { + to: facade.address, + value: '0', + data: facade.interface.encodeFunctionData('save', [ + backingBufferFacet.address, + Object.entries(backingBufferFacet.functions).map(([fn]) => + backingBufferFacet.interface.getSighash(fn) + ), + ]), + } + + await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts b/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts index d50d257742..7c0f264743 100644 --- a/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts +++ b/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts @@ -4,8 +4,11 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' +import { initiateMultisigTx } from '../utils' import { RevenueFacet } from '../../../typechain' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + let revenueFacet: RevenueFacet async function main() { @@ -51,12 +54,17 @@ async function main() { // Save RevenueFacet functions to Facade const facade = await ethers.getContractAt('Facade', deployments.facade) - await facade.save( - revenueFacet.address, - Object.entries(revenueFacet.functions).map(([fn]) => revenueFacet.interface.getSighash(fn)) - ) - console.log('Finished saving to Facade') + const tx: MetaTransactionData = { + to: facade.address, + value: '0', + data: facade.interface.encodeFunctionData('save', [ + revenueFacet.address, + Object.entries(revenueFacet.functions).map(([fn]) => revenueFacet.interface.getSighash(fn)), + ]), + } + + await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/utils.ts b/scripts/deployment/utils.ts index 07f238d13c..6a7579456a 100644 --- a/scripts/deployment/utils.ts +++ b/scripts/deployment/utils.ts @@ -8,6 +8,12 @@ import { IComponents, arbitrumL2Chains, baseL2Chains } from '../../common/config import { isValidContract } from '../../common/blockchain-utils' import { IDeployments } from './common' import { useEnv } from '#/utils/env' +import { networkConfig } from '../../common/configuration' + +import Safe from '@safe-global/protocol-kit' +import SafeApiKit from '@safe-global/api-kit' +import { HttpNetworkConfig } from 'hardhat/types' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' export const priceTimeout = bn('604800') // 1 week @@ -182,7 +188,13 @@ export const getEmptyDeployment = (): IDeployments => { }, tradingLib: '', basketLib: '', - facets: { actFacet: '', readFacet: '', maxIssuableFacet: '' }, + facets: { + actFacet: '', + readFacet: '', + maxIssuableFacet: '', + backingBufferFacet: '', + revenueFacet: '', + }, facade: '', facadeWriteLib: '', facadeWrite: '', @@ -275,3 +287,42 @@ export const getUsdtOracleError = (network: string): BigNumber => { return fp('0.0025') // 0.25% mainnet } } + +export const initiateMultisigTx = async ( + chainId: string, + tx: MetaTransactionData +): Promise => { + if (hre.network.name == 'localhost' || hre.network.name == 'hardhat') { + console.log('Skipping multisig tx on localhost') + return + } + + const provider = (hre.config.networks[hre.network.name] as HttpNetworkConfig).url + const signer = hre.ethers.Wallet.fromMnemonic(process.env.MNEMONIC!).privateKey + const safeAddress = networkConfig[chainId].DEV_MULTISIG! + + const safe = await Safe.init({ + provider, + signer, + safeAddress, + }) + const safeApi = new SafeApiKit({ + chainId: parseInt(chainId) as unknown as bigint, + }) + const safeTx = await safe.createTransaction({ transactions: [tx] }) + const safeTxHash = await safe.getTransactionHash(safeTx) + const signature = await safe.signHash(safeTxHash) + + // Propose transaction to the service + await safeApi.proposeTransaction({ + safeAddress: await safe.getAddress(), + safeTransactionData: safeTx.data, + safeTxHash, + senderAddress: tx.to, + senderSignature: signature.data, + }) + + const hyperlink = `https://app.safe.global/transactions/queue?safe=${hre.network.name}:${networkConfig[chainId].DEV_MULTISIG}` + + console.log(`Queued tx, requires confirmation: ${hyperlink}`) +} diff --git a/scripts/verification/4_verify_facade.ts b/scripts/verification/4_verify_facade.ts index 5fb61de951..a208c75aaa 100644 --- a/scripts/verification/4_verify_facade.ts +++ b/scripts/verification/4_verify_facade.ts @@ -21,7 +21,12 @@ async function main() { deployments = getDeploymentFile(getDeploymentFilename(chainId)) /** ******************** Verify Facade ****************************************/ - await verifyContract(chainId, deployments.facade, [], 'contracts/facade/Facade.sol:Facade') + await verifyContract( + chainId, + deployments.facade, + [networkConfig[chainId].DEV_MULTISIG], + 'contracts/facade/Facade.sol:Facade' + ) /** ******************** Verify ReadFacet ****************************************/ await verifyContract( diff --git a/test/fixtures.ts b/test/fixtures.ts index a2a93b8c15..23d7cc81ee 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -740,7 +740,12 @@ const makeDefaultFixture = async (setBasket: boolean): Promise = // Deploy Facade const FacadeFactory: ContractFactory = await ethers.getContractFactory('Facade') - const facade = await ethers.getContractAt('TestIFacade', (await FacadeFactory.deploy()).address) + const facade = await ethers.getContractAt( + 'TestIFacade', + ( + await FacadeFactory.deploy(owner.address) + ).address + ) // Save ReadFacet to Facade const ReadFacetFactory: ContractFactory = await ethers.getContractFactory('ReadFacet') diff --git a/test/integration/fixtures.ts b/test/integration/fixtures.ts index cc0049d9b0..d7c861cd3f 100644 --- a/test/integration/fixtures.ts +++ b/test/integration/fixtures.ts @@ -670,7 +670,12 @@ const makeDefaultFixture = async (setBasket: boolean): Promise = // Deploy Facade const FacadeFactory: ContractFactory = await ethers.getContractFactory('Facade') - const facade = await ethers.getContractAt('TestIFacade', (await FacadeFactory.deploy()).address) + const facade = await ethers.getContractAt( + 'TestIFacade', + ( + await FacadeFactory.deploy(owner.address) + ).address + ) // Save ReadFacet to Facade const ReadFacetFactory: ContractFactory = await ethers.getContractFactory('ReadFacet') diff --git a/test/plugins/individual-collateral/fixtures.ts b/test/plugins/individual-collateral/fixtures.ts index e83b6bae25..77225a529c 100644 --- a/test/plugins/individual-collateral/fixtures.ts +++ b/test/plugins/individual-collateral/fixtures.ts @@ -77,6 +77,7 @@ export interface DefaultFixture extends RSRAndModuleFixture { export const getDefaultFixture = async function (salt: string) { const defaultFixture: Fixture = async function (): Promise { let chainId = await getChainId(hre) + const signers = await ethers.getSigners() if (useEnv('FORK_NETWORK').toLowerCase() == 'base') chainId = 8453 if (useEnv('FORK_NETWORK').toLowerCase() == 'arbitrum') chainId = 42161 const { rsr } = await rsrFixture(chainId) @@ -87,7 +88,12 @@ export const getDefaultFixture = async function (salt: string) { // Deploy Facade const FacadeFactory: ContractFactory = await ethers.getContractFactory('Facade') - const facade = await ethers.getContractAt('TestIFacade', (await FacadeFactory.deploy()).address) + const facade = await ethers.getContractAt( + 'TestIFacade', + ( + await FacadeFactory.deploy(signers[0].address) + ).address + ) // Save ReadFacet to Facade const ReadFacetFactory: ContractFactory = await ethers.getContractFactory('ReadFacet') diff --git a/yarn.lock b/yarn.lock index 30347f1c64..344b0f414b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37,6 +37,13 @@ __metadata: languageName: node linkType: hard +"@adraffy/ens-normalize@npm:1.10.1": + version: 1.10.1 + resolution: "@adraffy/ens-normalize@npm:1.10.1" + checksum: 10c0/fdd647604e8fac6204921888aaf5a6bc65eabf0d2921bc5f93b64d01f4bc33ead167c1445f7de05468d05cd92ac31b74c68d2be840c62b79d73693308f885c06 + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.2.1 resolution: "@ampproject/remapping@npm:2.2.1" @@ -1214,6 +1221,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:1.2.0": + version: 1.2.0 + resolution: "@noble/curves@npm:1.2.0" + dependencies: + "@noble/hashes": "npm:1.3.2" + checksum: 10c0/0bac7d1bbfb3c2286910b02598addd33243cb97c3f36f987ecc927a4be8d7d88e0fcb12b0f0ef8a044e7307d1844dd5c49bb724bfa0a79c8ec50ba60768c97f6 + languageName: node + linkType: hard + "@noble/hashes@npm:1.2.0, @noble/hashes@npm:~1.2.0": version: 1.2.0 resolution: "@noble/hashes@npm:1.2.0" @@ -1221,6 +1237,20 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.3.2": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: 10c0/2482cce3bce6a596626f94ca296e21378e7a5d4c09597cbc46e65ffacc3d64c8df73111f2265444e36a3168208628258bbbaccba2ef24f65f58b2417638a20e7 + languageName: node + linkType: hard + +"@noble/hashes@npm:^1.3.3": + version: 1.5.0 + resolution: "@noble/hashes@npm:1.5.0" + checksum: 10c0/1b46539695fbfe4477c0822d90c881a04d4fa2921c08c552375b444a48cac9930cb1ee68de0a3c7859e676554d0f3771999716606dc4d8f826e414c11692cdd9 + languageName: node + linkType: hard + "@noble/secp256k1@npm:1.7.1, @noble/secp256k1@npm:~1.7.0": version: 1.7.1 resolution: "@noble/secp256k1@npm:1.7.1" @@ -1713,6 +1743,59 @@ __metadata: languageName: node linkType: hard +"@safe-global/api-kit@npm:^2.4.5": + version: 2.4.5 + resolution: "@safe-global/api-kit@npm:2.4.5" + dependencies: + "@safe-global/protocol-kit": "npm:^4.1.0" + "@safe-global/safe-core-sdk-types": "npm:^5.1.0" + ethers: "npm:^6.13.1" + node-fetch: "npm:^2.7.0" + checksum: 10c0/21308d4a1a5c2d15e39ff9c34e7c343c098703d223ed0bad5f3e5d6b8ae113459e1cae21b2c102798f013d2312b8d6237be2fc5281f28c45b3a434bd44fe6338 + languageName: node + linkType: hard + +"@safe-global/protocol-kit@npm:^4.1.0": + version: 4.1.0 + resolution: "@safe-global/protocol-kit@npm:4.1.0" + dependencies: + "@noble/hashes": "npm:^1.3.3" + "@safe-global/safe-core-sdk-types": "npm:^5.1.0" + "@safe-global/safe-deployments": "npm:^1.37.3" + "@safe-global/safe-modules-deployments": "npm:^2.2.1" + abitype: "npm:^1.0.2" + ethereumjs-util: "npm:^7.1.5" + ethers: "npm:^6.13.1" + semver: "npm:^7.6.2" + checksum: 10c0/a112ababfa43cd9b6ed753913857d530e2805f39e1ead1f70c1e5770719f466c312c81a932f6f5348aa514c064aec74fd05f98a8a3fd07fc614dae7494e110d0 + languageName: node + linkType: hard + +"@safe-global/safe-core-sdk-types@npm:^5.1.0": + version: 5.1.0 + resolution: "@safe-global/safe-core-sdk-types@npm:5.1.0" + dependencies: + abitype: "npm:^1.0.2" + checksum: 10c0/f8572603f5980f2653be51cb148e4a014c06fd063e5bac1e318f1bed7f3485f6380e6ee0e4a2d4998dd5707ae537aaf781e7a1d25839c1ec3173676626fdf6ff + languageName: node + linkType: hard + +"@safe-global/safe-deployments@npm:^1.37.3": + version: 1.37.5 + resolution: "@safe-global/safe-deployments@npm:1.37.5" + dependencies: + semver: "npm:^7.6.2" + checksum: 10c0/dcec4f8a19a37b3d9bcc0a4d7a97d4799d53d02d1e9d58e29f4f662351ce4a73ce76d5e7f5771a9b2e24589571fbdfb80fdad2457a65d551cdcb74a9b0e22410 + languageName: node + linkType: hard + +"@safe-global/safe-modules-deployments@npm:^2.2.1": + version: 2.2.1 + resolution: "@safe-global/safe-modules-deployments@npm:2.2.1" + checksum: 10c0/72f4d44342264e0f945f27207c814fbd5e1ce3671cc808c92f7e798869d138a8d930acf3b1d1846019003d3c29894827e18955e7f0824b700f1e506a205ba9a6 + languageName: node + linkType: hard + "@scure/base@npm:~1.1.0": version: 1.1.1 resolution: "@scure/base@npm:1.1.1" @@ -2093,6 +2176,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:18.15.13": + version: 18.15.13 + resolution: "@types/node@npm:18.15.13" + checksum: 10c0/6e5f61c559e60670a7a8fb88e31226ecc18a21be103297ca4cf9848f0a99049dae77f04b7ae677205f2af494f3701b113ba8734f4b636b355477a6534dbb8ada + languageName: node + linkType: hard + "@types/node@npm:^10.0.3": version: 10.17.60 resolution: "@types/node@npm:10.17.60" @@ -2310,6 +2400,21 @@ __metadata: languageName: node linkType: hard +"abitype@npm:^1.0.2": + version: 1.0.6 + resolution: "abitype@npm:1.0.6" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: 10c0/30ca97010bbf34b9aaed401858eeb6bc30419f7ff11eb34adcb243522dd56c9d8a9d3d406aa5d4f60a7c263902f5136043005698e3f073ea882a4922d43a2929 + languageName: node + linkType: hard + "abort-controller@npm:^3.0.0": version: 3.0.0 resolution: "abort-controller@npm:3.0.0" @@ -2399,6 +2504,13 @@ __metadata: languageName: node linkType: hard +"aes-js@npm:4.0.0-beta.5": + version: 4.0.0-beta.5 + resolution: "aes-js@npm:4.0.0-beta.5" + checksum: 10c0/444f4eefa1e602cbc4f2a3c644bc990f93fd982b148425fee17634da510586fc09da940dcf8ace1b2d001453c07ff042e55f7a0482b3cc9372bf1ef75479090c + languageName: node + linkType: hard + "agent-base@npm:6, agent-base@npm:^6.0.2": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -4914,7 +5026,7 @@ __metadata: languageName: node linkType: hard -"ethereumjs-util@npm:^7.0.3, ethereumjs-util@npm:^7.1.0, ethereumjs-util@npm:^7.1.4": +"ethereumjs-util@npm:^7.0.3, ethereumjs-util@npm:^7.1.0, ethereumjs-util@npm:^7.1.4, ethereumjs-util@npm:^7.1.5": version: 7.1.5 resolution: "ethereumjs-util@npm:7.1.5" dependencies: @@ -4982,6 +5094,21 @@ __metadata: languageName: node linkType: hard +"ethers@npm:^6.13.1": + version: 6.13.2 + resolution: "ethers@npm:6.13.2" + dependencies: + "@adraffy/ens-normalize": "npm:1.10.1" + "@noble/curves": "npm:1.2.0" + "@noble/hashes": "npm:1.3.2" + "@types/node": "npm:18.15.13" + aes-js: "npm:4.0.0-beta.5" + tslib: "npm:2.4.0" + ws: "npm:8.17.1" + checksum: 10c0/5956389a180992f8b6d90bc21b2e0f28619a098513d3aeb7a350a0b7c5852d635a9d7fd4ced1af50c985dd88398716f66dfd4a2de96c5c3a67150b93543d92af + languageName: node + linkType: hard + "ethjs-unit@npm:0.1.6": version: 0.1.6 resolution: "ethjs-unit@npm:0.1.6" @@ -8005,6 +8132,20 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:^2.7.0": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: "npm:^5.0.0" + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8 + languageName: node + linkType: hard + "node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.3.0": version: 4.6.0 resolution: "node-gyp-build@npm:4.6.0" @@ -8991,6 +9132,8 @@ __metadata: "@openzeppelin/contracts": "npm:4.9.6" "@openzeppelin/contracts-upgradeable": "npm:4.9.6" "@openzeppelin/hardhat-upgrades": "npm:^1.23.0" + "@safe-global/api-kit": "npm:^2.4.5" + "@safe-global/protocol-kit": "npm:^4.1.0" "@tenderly/hardhat-tenderly": "npm:^1.7.7" "@typechain/ethers-v5": "npm:^7.2.0" "@typechain/hardhat": "npm:^2.3.1" @@ -9370,6 +9513,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.6.2": + version: 7.6.3 + resolution: "semver@npm:7.6.3" + bin: + semver: bin/semver.js + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf + languageName: node + linkType: hard + "send@npm:0.18.0": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -10297,6 +10449,13 @@ __metadata: languageName: node linkType: hard +"tslib@npm:2.4.0": + version: 2.4.0 + resolution: "tslib@npm:2.4.0" + checksum: 10c0/eb19bda3ae545b03caea6a244b34593468e23d53b26bf8649fbc20fce43e9b21a71127fd6d2b9662c0fe48ee6ff668ead48fd00d3b88b2b716b1c12edae25b5d + languageName: node + linkType: hard + "tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" @@ -10925,6 +11084,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:8.17.1": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe + languageName: node + linkType: hard + "ws@npm:^7.4.6": version: 7.5.9 resolution: "ws@npm:7.5.9" From 7cb9935d93984d8f37e21f438a36ffff7dca4d9d Mon Sep 17 00:00:00 2001 From: Taylor Brent Date: Wed, 11 Sep 2024 22:13:30 -0400 Subject: [PATCH 2/4] fix hyperlink --- scripts/deployment/utils.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/deployment/utils.ts b/scripts/deployment/utils.ts index 6a7579456a..a6462604d9 100644 --- a/scripts/deployment/utils.ts +++ b/scripts/deployment/utils.ts @@ -322,7 +322,11 @@ export const initiateMultisigTx = async ( senderSignature: signature.data, }) - const hyperlink = `https://app.safe.global/transactions/queue?safe=${hre.network.name}:${networkConfig[chainId].DEV_MULTISIG}` + let prefix = 'base' + if (hre.network.name == 'mainnet') prefix = 'eth' + else if (hre.network.name == 'arbitrum') prefix = 'arb' + + const hyperlink = `https://app.safe.global/transactions/queue?safe=${prefix}:${networkConfig[chainId].DEV_MULTISIG}` console.log(`Queued tx, requires confirmation: ${hyperlink}`) } From df9d9db0bf54ac7d2cf2a8e4b2b862d2ffbfe127 Mon Sep 17 00:00:00 2001 From: Taylor Brent Date: Thu, 12 Sep 2024 17:06:52 -0400 Subject: [PATCH 3/4] batch --- common/configuration.ts | 6 +- scripts/addresses/1-tmp-deployments.json | 2 +- scripts/addresses/42161-tmp-deployments.json | 2 +- scripts/addresses/8453-tmp-deployments.json | 2 +- .../arbitrum-3.4.0/42161-tmp-deployments.json | 2 +- .../base-3.4.0/8453-tmp-deployments.json | 2 +- .../mainnet-3.4.0/1-tmp-deployments.json | 2 +- .../phase1-facade/1_deploy_readFacet.ts | 21 ------- .../phase1-facade/2_deploy_actFacet.ts | 21 ------- .../phase1-facade/3_deploy_maxIssuable.ts | 23 ------- .../4_deploy_backingBufferFacet.ts | 23 ------- .../phase1-facade/5_deploy_revenueFacet.ts | 21 ------- scripts/deployment/phase1-facade/save.ts | 60 +++++++++++++++++++ scripts/deployment/utils.ts | 16 +++-- 14 files changed, 81 insertions(+), 122 deletions(-) create mode 100644 scripts/deployment/phase1-facade/save.ts diff --git a/common/configuration.ts b/common/configuration.ts index ccc252f1eb..3cdc021ee5 100644 --- a/common/configuration.ts +++ b/common/configuration.ts @@ -307,7 +307,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = { AAVE_V3_INCENTIVES_CONTROLLER: '0x8164Cc65827dcFe994AB23944CBC90e0aa80bFcb', STARGATE_STAKING_CONTRACT: '0xB0D502E938ed5f4df2E681fE6E419ff29631d62b', CURVE_POOL_WETH_FRXETH: '0x9c3b46c0ceb5b9e304fcd6d88fc50f7dd24b31bc', - DEV_MULTISIG: '0xf8A981f5D79a204835B5a105CEe54E176012a633', // same on all networks + DEV_MULTISIG: '0xe63AfB49529E135be5ab2747104fF1D3ceAE0EFf', // same on all networks }, '3': { name: 'tenderly', @@ -541,7 +541,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = { AAVE_V3_POOL: '0xA238Dd80C259a72e81d7e4664a9801593F98d1c5', AAVE_V3_INCENTIVES_CONTROLLER: '0xf9cc4F0D883F1a1eb2c253bdb46c254Ca51E1F44', STARGATE_STAKING_CONTRACT: '0x06Eb48763f117c7Be887296CDcdfad2E4092739C', - DEV_MULTISIG: '0xf8A981f5D79a204835B5a105CEe54E176012a633', // same on all networks + DEV_MULTISIG: '0xe63AfB49529E135be5ab2747104fF1D3ceAE0EFf', // same on all networks }, '42161': { name: 'arbitrum', @@ -582,7 +582,7 @@ export const networkConfig: { [key: string]: INetworkConfig } = { COMET_EXT: '0x1B2E88cC7365d90e7E81392432482925BD8437E9', AAVE_V3_POOL: '0x794a61358D6845594F94dc1DB02A252b5b4814aD', AAVE_V3_INCENTIVES_CONTROLLER: '0x929EC64c34a17401F460460D4B9390518E5B473e', - DEV_MULTISIG: '0xf8A981f5D79a204835B5a105CEe54E176012a633', // same on all networks + DEV_MULTISIG: '0xe63AfB49529E135be5ab2747104fF1D3ceAE0EFf', // same on all networks }, '421614': { name: 'arbitrum-sepolia', diff --git a/scripts/addresses/1-tmp-deployments.json b/scripts/addresses/1-tmp-deployments.json index ae1d7c6348..3aa957d0ba 100644 --- a/scripts/addresses/1-tmp-deployments.json +++ b/scripts/addresses/1-tmp-deployments.json @@ -5,7 +5,7 @@ "GNOSIS_EASY_AUCTION": "0x0b7fFc1f4AD541A4Ed16b40D8c37f0929158D101" }, "tradingLib": "0xa54544C6C36C0d776cc4F04EBB847e0BB3A11ea2", - "facade": "0x2C7ca56342177343A2954C250702Fd464f4d0613", + "facade": "0x9d49b363d492725412bf8350bBb525B7a80a7470", "facets": { "actFacet": "0xCAB3D3d0d5544145A6BCB47e58F61368BCcAe2dB", "readFacet": "0x823110a13eB26cB09c4Bb118DBfE4ff5f96D5526", diff --git a/scripts/addresses/42161-tmp-deployments.json b/scripts/addresses/42161-tmp-deployments.json index 90c7ca5a41..dd30fec9ed 100644 --- a/scripts/addresses/42161-tmp-deployments.json +++ b/scripts/addresses/42161-tmp-deployments.json @@ -6,7 +6,7 @@ }, "tradingLib": "0x348644F24FA34c40a8E3C4Cf9aF14f8a96aD63fC", "cvxMiningLib": "", - "facade": "0x387A0C36681A22F728ab54426356F4CAa6bB48a9", + "facade": "0xb48a407e225b4764fD3BCc2a2329fF7745af7e64", "facets": { "actFacet": "0xE774CCF1431c3DEe7Fa4c20f67534b61289CAa45", "readFacet": "0x15175d35F3d88548B49600B4ee8067253A2e4e66", diff --git a/scripts/addresses/8453-tmp-deployments.json b/scripts/addresses/8453-tmp-deployments.json index 5c49047817..7d32446fa9 100644 --- a/scripts/addresses/8453-tmp-deployments.json +++ b/scripts/addresses/8453-tmp-deployments.json @@ -5,7 +5,7 @@ "GNOSIS_EASY_AUCTION": "0xb1875Feaeea32Bbb02DE83D81772e07E37A40f02" }, "tradingLib": "0x6419fe6cf428150e2d8ed38a3316b1bb468f79a7", - "facade": "0xEb2071e9B542555E90E6e4E1F83fa17423583991", + "facade": "0xE41416d8dC94ac1F6d12282d6D46B714F39a87d9", "facets": { "actFacet": "0x0eac15B9Fe585432E48Cf175571D75D111861F43", "readFacet": "0x5Af543D6F95a98200Dd770f39A902Fe793BAeB27", diff --git a/scripts/addresses/arbitrum-3.4.0/42161-tmp-deployments.json b/scripts/addresses/arbitrum-3.4.0/42161-tmp-deployments.json index 84e86fa98f..1d87b00c7d 100644 --- a/scripts/addresses/arbitrum-3.4.0/42161-tmp-deployments.json +++ b/scripts/addresses/arbitrum-3.4.0/42161-tmp-deployments.json @@ -6,7 +6,7 @@ }, "tradingLib": "0x348644F24FA34c40a8E3C4Cf9aF14f8a96aD63fC", "cvxMiningLib": "", - "facade": "0x387A0C36681A22F728ab54426356F4CAa6bB48a9", + "facade": "0xb48a407e225b4764fD3BCc2a2329fF7745af7e64", "facets": { "actFacet": "0xE774CCF1431c3DEe7Fa4c20f67534b61289CAa45", "readFacet": "0x15175d35F3d88548B49600B4ee8067253A2e4e66", diff --git a/scripts/addresses/base-3.4.0/8453-tmp-deployments.json b/scripts/addresses/base-3.4.0/8453-tmp-deployments.json index d8d51f4261..b34350b2be 100644 --- a/scripts/addresses/base-3.4.0/8453-tmp-deployments.json +++ b/scripts/addresses/base-3.4.0/8453-tmp-deployments.json @@ -5,7 +5,7 @@ "GNOSIS_EASY_AUCTION": "0xb1875Feaeea32Bbb02DE83D81772e07E37A40f02" }, "tradingLib": "0x6419fe6cf428150e2d8ed38a3316b1bb468f79a7", - "facade": "0xEb2071e9B542555E90E6e4E1F83fa17423583991", + "facade": "0xE41416d8dC94ac1F6d12282d6D46B714F39a87d9", "facets": { "actFacet": "0x0eac15B9Fe585432E48Cf175571D75D111861F43", "readFacet": "0x5Af543D6F95a98200Dd770f39A902Fe793BAeB27", diff --git a/scripts/addresses/mainnet-3.4.0/1-tmp-deployments.json b/scripts/addresses/mainnet-3.4.0/1-tmp-deployments.json index 967cf69776..613035154f 100644 --- a/scripts/addresses/mainnet-3.4.0/1-tmp-deployments.json +++ b/scripts/addresses/mainnet-3.4.0/1-tmp-deployments.json @@ -5,7 +5,7 @@ "GNOSIS_EASY_AUCTION": "0x0b7fFc1f4AD541A4Ed16b40D8c37f0929158D101" }, "tradingLib": "0xa54544C6C36C0d776cc4F04EBB847e0BB3A11ea2", - "facade": "0x2C7ca56342177343A2954C250702Fd464f4d0613", + "facade": "0x9d49b363d492725412bf8350bBb525B7a80a7470", "facets": { "actFacet": "0xCAB3D3d0d5544145A6BCB47e58F61368BCcAe2dB", "readFacet": "0x823110a13eB26cB09c4Bb118DBfE4ff5f96D5526", diff --git a/scripts/deployment/phase1-facade/1_deploy_readFacet.ts b/scripts/deployment/phase1-facade/1_deploy_readFacet.ts index 012a27bfc8..1b94633920 100644 --- a/scripts/deployment/phase1-facade/1_deploy_readFacet.ts +++ b/scripts/deployment/phase1-facade/1_deploy_readFacet.ts @@ -4,11 +4,8 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' -import { initiateMultisigTx } from '../utils' import { ReadFacet } from '../../../typechain' -import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - let readFacet: ReadFacet async function main() { @@ -47,24 +44,6 @@ async function main() { console.log(`Deployed to ${hre.network.name} (${chainId}) ReadFacet: ${readFacet.address} Deployment file: ${deploymentFilename}`) - - // ******************** Save to Facade ****************************************/ - - console.log('Configuring with Facade via multisig...') - - // Save ReadFacet functions to Facade - const facade = await ethers.getContractAt('Facade', deployments.facade) - - const tx: MetaTransactionData = { - to: facade.address, - value: '0', - data: facade.interface.encodeFunctionData('save', [ - readFacet.address, - Object.entries(readFacet.functions).map(([fn]) => readFacet.interface.getSighash(fn)), - ]), - } - - await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/2_deploy_actFacet.ts b/scripts/deployment/phase1-facade/2_deploy_actFacet.ts index 8301df9c7e..3c1b76e5ab 100644 --- a/scripts/deployment/phase1-facade/2_deploy_actFacet.ts +++ b/scripts/deployment/phase1-facade/2_deploy_actFacet.ts @@ -4,11 +4,8 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' -import { initiateMultisigTx } from '../utils' import { ActFacet } from '../../../typechain' -import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - let actFacet: ActFacet async function main() { @@ -47,24 +44,6 @@ async function main() { console.log(`Deployed to ${hre.network.name} (${chainId}) ActFacet: ${actFacet.address} Deployment file: ${deploymentFilename}`) - - // ******************** Save to Facade ****************************************/ - - console.log('Configuring with Facade...') - - // Save ActFacet functions to Facade - const facade = await ethers.getContractAt('Facade', deployments.facade) - - const tx: MetaTransactionData = { - to: facade.address, - value: '0', - data: facade.interface.encodeFunctionData('save', [ - actFacet.address, - Object.entries(actFacet.functions).map(([fn]) => actFacet.interface.getSighash(fn)), - ]), - } - - await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts b/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts index 6559b2f683..bf584bb055 100644 --- a/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts +++ b/scripts/deployment/phase1-facade/3_deploy_maxIssuable.ts @@ -4,11 +4,8 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' -import { initiateMultisigTx } from '../utils' import { MaxIssuableFacet } from '../../../typechain' -import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - let maxIssuableFacet: MaxIssuableFacet async function main() { @@ -47,26 +44,6 @@ async function main() { console.log(`Deployed to ${hre.network.name} (${chainId}) MaxIssuableFacet: ${maxIssuableFacet.address} Deployment file: ${deploymentFilename}`) - - // ******************** Save to Facade ****************************************/ - - console.log('Configuring with Facade...') - - // Save MaxIssuableFacet functions to Facade - const facade = await ethers.getContractAt('Facade', deployments.facade) - - const tx: MetaTransactionData = { - to: facade.address, - value: '0', - data: facade.interface.encodeFunctionData('save', [ - maxIssuableFacet.address, - Object.entries(maxIssuableFacet.functions).map(([fn]) => - maxIssuableFacet.interface.getSighash(fn) - ), - ]), - } - - await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts b/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts index 6b4007a240..3429f52546 100644 --- a/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts +++ b/scripts/deployment/phase1-facade/4_deploy_backingBufferFacet.ts @@ -4,11 +4,8 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' -import { initiateMultisigTx } from '../utils' import { BackingBufferFacet } from '../../../typechain' -import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - let backingBufferFacet: BackingBufferFacet async function main() { @@ -47,26 +44,6 @@ async function main() { console.log(`Deployed to ${hre.network.name} (${chainId}) BackingBufferFacet: ${backingBufferFacet.address} Deployment file: ${deploymentFilename}`) - - // ******************** Save to Facade ****************************************/ - - console.log('Configuring with Facade...') - - // Save BackingBufferFacet functions to Facade - const facade = await ethers.getContractAt('Facade', deployments.facade) - - const tx: MetaTransactionData = { - to: facade.address, - value: '0', - data: facade.interface.encodeFunctionData('save', [ - backingBufferFacet.address, - Object.entries(backingBufferFacet.functions).map(([fn]) => - backingBufferFacet.interface.getSighash(fn) - ), - ]), - } - - await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts b/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts index 7c0f264743..d09b69c67e 100644 --- a/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts +++ b/scripts/deployment/phase1-facade/5_deploy_revenueFacet.ts @@ -4,11 +4,8 @@ import hre, { ethers } from 'hardhat' import { getChainId, isValidContract } from '../../../common/blockchain-utils' import { networkConfig } from '../../../common/configuration' import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' -import { initiateMultisigTx } from '../utils' import { RevenueFacet } from '../../../typechain' -import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' - let revenueFacet: RevenueFacet async function main() { @@ -47,24 +44,6 @@ async function main() { console.log(`Deployed to ${hre.network.name} (${chainId}) RevenueFacet: ${revenueFacet.address} Deployment file: ${deploymentFilename}`) - - // ******************** Save to Facade ****************************************/ - - console.log('Configuring with Facade...') - - // Save RevenueFacet functions to Facade - const facade = await ethers.getContractAt('Facade', deployments.facade) - - const tx: MetaTransactionData = { - to: facade.address, - value: '0', - data: facade.interface.encodeFunctionData('save', [ - revenueFacet.address, - Object.entries(revenueFacet.functions).map(([fn]) => revenueFacet.interface.getSighash(fn)), - ]), - } - - await initiateMultisigTx(chainId, tx) } main().catch((error) => { diff --git a/scripts/deployment/phase1-facade/save.ts b/scripts/deployment/phase1-facade/save.ts new file mode 100644 index 0000000000..b369788747 --- /dev/null +++ b/scripts/deployment/phase1-facade/save.ts @@ -0,0 +1,60 @@ +import hre, { ethers } from 'hardhat' + +import { getChainId, isValidContract } from '../../../common/blockchain-utils' +import { getDeploymentFile, getDeploymentFilename, IDeployments } from '../common' +import { initiateMultisigTxs } from '../utils' +import { MetaTransactionData } from '@safe-global/safe-core-sdk-types' + +async function main() { + // ==== Read Configuration ==== + const [burner] = await hre.ethers.getSigners() + const chainId = await getChainId(hre) + + console.log(`Saving Facets to Facade on network ${hre.network.name} (${chainId}) + with burner account: ${burner.address}`) + + const deploymentFilename = getDeploymentFilename(chainId) + const deployments = getDeploymentFile(deploymentFilename) + + // Check facade exists + if (!deployments.facade) { + throw new Error(`Missing deployed contracts in network ${hre.network.name}`) + } else if (!(await isValidContract(hre, deployments.facade))) { + throw new Error(`Facade contract not found in network ${hre.network.name}`) + } + + // ******************** Save Facets to Facade ****************************************/ + + if (hre.network.name == 'localhost' || hre.network.name == 'hardhat') { + console.log('Skipping saving facets on localhost') + return + } + + const facade = await ethers.getContractAt('Facade', deployments.facade) + + const facets = [ + await ethers.getContractAt('ReadFacet', deployments.facets.readFacet), + await ethers.getContractAt('ActFacet', deployments.facets.actFacet), + await ethers.getContractAt('MaxIssuableFacet', deployments.facets.maxIssuableFacet), + await ethers.getContractAt('BackingBufferFacet', deployments.facets.backingBufferFacet), + await ethers.getContractAt('RevenueFacet', deployments.facets.revenueFacet), + ] + + const txs = facets.map((facet): MetaTransactionData => { + return { + to: facade.address, + value: '0', + data: facade.interface.encodeFunctionData('save', [ + facet.address, + Object.entries(facet.functions).map(([fn]) => facet.interface.getSighash(fn)), + ]), + } + }) + + await initiateMultisigTxs(chainId, txs) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/deployment/utils.ts b/scripts/deployment/utils.ts index 3e55e5dfc0..82946ea1cb 100644 --- a/scripts/deployment/utils.ts +++ b/scripts/deployment/utils.ts @@ -284,6 +284,14 @@ export const getUsdtOracleError = (network: string): BigNumber => { export const initiateMultisigTx = async ( chainId: string, tx: MetaTransactionData +): Promise => { + return await initiateMultisigTxs(chainId, [tx]) +} + +// Note: may end up with conflicting nonces if used naively +export const initiateMultisigTxs = async ( + chainId: string, + txs: MetaTransactionData[] ): Promise => { if (hre.network.name == 'localhost' || hre.network.name == 'hardhat') { console.log('Skipping multisig tx on localhost') @@ -291,18 +299,18 @@ export const initiateMultisigTx = async ( } const provider = (hre.config.networks[hre.network.name] as HttpNetworkConfig).url - const signer = hre.ethers.Wallet.fromMnemonic(process.env.MNEMONIC!).privateKey + const wallet = hre.ethers.Wallet.fromMnemonic(process.env.MNEMONIC!) const safeAddress = networkConfig[chainId].DEV_MULTISIG! const safe = await Safe.init({ provider, - signer, + signer: wallet.privateKey, safeAddress, }) const safeApi = new SafeApiKit({ chainId: parseInt(chainId) as unknown as bigint, }) - const safeTx = await safe.createTransaction({ transactions: [tx] }) + const safeTx = await safe.createTransaction({ transactions: txs }) const safeTxHash = await safe.getTransactionHash(safeTx) const signature = await safe.signHash(safeTxHash) @@ -311,7 +319,7 @@ export const initiateMultisigTx = async ( safeAddress: await safe.getAddress(), safeTransactionData: safeTx.data, safeTxHash, - senderAddress: tx.to, + senderAddress: wallet.address, senderSignature: signature.data, }) From 18912fcba1c3d2f3f5adbdaaa40afc9cfa37175b Mon Sep 17 00:00:00 2001 From: Taylor Brent Date: Thu, 12 Sep 2024 17:07:59 -0400 Subject: [PATCH 4/4] deploy.ts --- scripts/deploy.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/deploy.ts b/scripts/deploy.ts index cc2a51418b..012b1a7eca 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -46,7 +46,8 @@ async function main() { 'phase1-facade/2_deploy_actFacet.ts', 'phase1-facade/3_deploy_maxIssuable.ts', 'phase1-facade/4_deploy_backingBufferFacet.ts', - 'phase1-facade/5_deploy_revenueFacet.ts' + 'phase1-facade/5_deploy_revenueFacet.ts', + 'phase1-facade/save.ts' ) // =============================================