diff --git a/governance/development/add-bridge-faucet/built.json b/governance/development/add-bridge-faucet/built.json new file mode 100644 index 000000000..14dc45717 --- /dev/null +++ b/governance/development/add-bridge-faucet/built.json @@ -0,0 +1,5 @@ +{ + "data": "0x81dccd560000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000f211e0c9ba161880c77cf320200f14f67b0db7570000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004499a88ec40000000000000000000000005d1f5f8ef74fb8626fe2d482618f8517a3cbd8f700000000000000000000000071dbb34038297f430d6020dcc4748b05a5bd83bc00000000000000000000000000000000000000000000000000000000", + "to": "0xB1F0bB0d6a40d5003f2A62D9a146791A90270F1d", + "from": "0xa4849f1D96B26066f9C631FCdc8F1457D27Fb5EC" +} \ No newline at end of file diff --git a/governance/development/add-bridge-faucet/unbuilt.json b/governance/development/add-bridge-faucet/unbuilt.json new file mode 100644 index 000000000..bba6fb5e9 --- /dev/null +++ b/governance/development/add-bridge-faucet/unbuilt.json @@ -0,0 +1,11 @@ +{ + "local": [], + "remote": { + "3000": [ + { + "to": "0x000000000000000000000000f211e0c9ba161880c77cf320200f14f67b0db757", + "data": "0x99a88ec40000000000000000000000005d1f5f8ef74fb8626fe2d482618f8517a3cbd8f700000000000000000000000071dbb34038297f430d6020dcc4748b05a5bd83bc" + } + ] + } +} \ No newline at end of file diff --git a/typescript/nomad-deploy/package.json b/typescript/nomad-deploy/package.json index c8d8b6cb1..52399b54b 100644 --- a/typescript/nomad-deploy/package.json +++ b/typescript/nomad-deploy/package.json @@ -18,6 +18,9 @@ "check": "tsc --noEmit", "prettier": "prettier --write ./src ./config ./scripts", "calculate-domain": "npx ts-node scripts/calculateDomain.ts", + "dev-deploy-new-bridge": "npx ts-node scripts/development/governance/upgrade-faucet/index.ts", + "dev-wait-new-bridge": "npx ts-node scripts/development/governance/upgrade-faucet/wait.ts", + "dev-execute-new-bridge": "npx ts-node scripts/development/governance/upgrade-faucet/execute.ts", "deploy-dev-core": "npx ts-node scripts/development/core.ts", "deploy-dev-bridges": "npx ts-node scripts/development/bridge.ts", "add-dev-core": "npx ts-node scripts/development/governance/deployNewCore.ts", diff --git a/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/constants.ts b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/constants.ts new file mode 100644 index 000000000..159726145 --- /dev/null +++ b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/constants.ts @@ -0,0 +1,2 @@ +export const ENVIRONMENT = 'dev'; +export const REASON = 'add-bridge-faucet'; diff --git a/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/execute.ts b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/execute.ts new file mode 100644 index 000000000..295ec1e21 --- /dev/null +++ b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/execute.ts @@ -0,0 +1,49 @@ +import { getPathToDeployConfig } from '../../../../src/verification/readDeployOutput'; +import { ExistingCoreDeploy } from '../../../../src/core/CoreDeploy'; +import * as rinkeby from '../../../../config/testnets/rinkeby'; +import { ExistingBridgeDeploy } from '../../../../src/bridge/BridgeDeploy'; +import { deploysToSDK } from '../../../../src/governance/utils'; +import * as kovan from '../../../../config/testnets/kovan'; +import { NomadContext } from '@nomad-xyz/sdk'; +import { executeRemoteBatches } from '../../../../src/governance'; +import { ENVIRONMENT, REASON } from './constants'; + +// BOILERPLATE +const path = getPathToDeployConfig(ENVIRONMENT); + +// Instantiate existing governor deploy on Rinkeby +const rinkebyCoreDeploy = ExistingCoreDeploy.withPath( + rinkeby.chain, + rinkeby.devConfig, + path, +); +const rinkebyBridgeDeploy = new ExistingBridgeDeploy( + rinkeby.chain, + rinkeby.bridgeConfig, + path, +); +const rinkebyDomain = deploysToSDK(rinkebyCoreDeploy, rinkebyBridgeDeploy); + +// Enroll Kovan as spoke to Rinkeby hub +const kovanCoreDeploy = ExistingCoreDeploy.withPath( + kovan.chain, + kovan.devConfig, + path, +); +const kovanBridgeDeploy = new ExistingBridgeDeploy( + kovan.chain, + kovan.bridgeConfig, + path, +); +const kovanDomain = deploysToSDK(kovanCoreDeploy, kovanBridgeDeploy); + +// setup SDK +const sdkDomains = [rinkebyDomain, kovanDomain]; +const sdk = NomadContext.fromDomains(sdkDomains); +const sdkCores = [rinkebyCoreDeploy, kovanCoreDeploy]; +sdkCores.forEach((core) => { + sdk.registerProvider(core.chain.domain, core.provider); + sdk.registerSigner(core.chain.domain, core.deployer); +}); + +executeRemoteBatches(sdk, ENVIRONMENT, REASON); diff --git a/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/index.ts b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/index.ts new file mode 100644 index 000000000..e192eb2b3 --- /dev/null +++ b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/index.ts @@ -0,0 +1,50 @@ +import * as rinkeby from '../../../../config/testnets/rinkeby'; +import * as kovan from '../../../../config/testnets/kovan'; +import { ExistingCoreDeploy } from '../../../../src/core/CoreDeploy'; +import { ExistingBridgeDeploy } from '../../../../src/bridge/BridgeDeploy'; +import { deploysToSDK } from '../../../../src/governance/utils'; +import { getPathToDeployConfig } from '../../../../src/verification/readDeployOutput'; +import { NomadContext } from '@nomad-xyz/sdk'; +import { upgradeBridgeRouter } from '../../../../src/governance/upgrade'; +import { ENVIRONMENT, REASON } from './constants'; + +// TODO: REPEATING THIS BOILERPLATE EVERYWHERE IS DRIVING ME CRAZY. need to fix. +const path = getPathToDeployConfig(ENVIRONMENT); + +// Instantiate existing governor deploy on Rinkeby +const rinkebyCoreDeploy = ExistingCoreDeploy.withPath( + rinkeby.chain, + rinkeby.devConfig, + path, +); +const rinkebyBridgeDeploy = new ExistingBridgeDeploy( + rinkeby.chain, + rinkeby.bridgeConfig, + path, +); +const rinkebyDomain = deploysToSDK(rinkebyCoreDeploy, rinkebyBridgeDeploy); + +// Enroll Kovan as spoke to Rinkeby hub +const kovanCoreDeploy = ExistingCoreDeploy.withPath( + kovan.chain, + kovan.devConfig, + path, +); +const kovanBridgeDeploy = new ExistingBridgeDeploy( + kovan.chain, + kovan.bridgeConfig, + path, +); +const kovanDomain = deploysToSDK(kovanCoreDeploy, kovanBridgeDeploy); + +// setup SDK +const sdkDomains = [rinkebyDomain, kovanDomain]; +const sdk = NomadContext.fromDomains(sdkDomains); +const sdkCores = [rinkebyCoreDeploy, kovanCoreDeploy]; +sdkCores.forEach((core) => { + sdk.registerProvider(core.chain.domain, core.provider); + sdk.registerSigner(core.chain.domain, core.deployer); +}); + +// upgrade the bridge router on Kovan +upgradeBridgeRouter(sdk, kovanCoreDeploy, kovanBridgeDeploy, REASON); diff --git a/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/wait.ts b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/wait.ts new file mode 100644 index 000000000..2cd03cfbd --- /dev/null +++ b/typescript/nomad-deploy/scripts/development/governance/upgrade-faucet/wait.ts @@ -0,0 +1,49 @@ +import { getPathToDeployConfig } from '../../../../src/verification/readDeployOutput'; +import { ExistingCoreDeploy } from '../../../../src/core/CoreDeploy'; +import * as rinkeby from '../../../../config/testnets/rinkeby'; +import { ExistingBridgeDeploy } from '../../../../src/bridge/BridgeDeploy'; +import { deploysToSDK } from '../../../../src/governance/utils'; +import * as kovan from '../../../../config/testnets/kovan'; +import { NomadContext } from '@nomad-xyz/sdk'; +import { waitBatches } from '../../../../src/governance'; +import { ENVIRONMENT, REASON } from './constants'; + +// BOILERPLATE +const path = getPathToDeployConfig(ENVIRONMENT); + +// Instantiate existing governor deploy on Rinkeby +const rinkebyCoreDeploy = ExistingCoreDeploy.withPath( + rinkeby.chain, + rinkeby.devConfig, + path, +); +const rinkebyBridgeDeploy = new ExistingBridgeDeploy( + rinkeby.chain, + rinkeby.bridgeConfig, + path, +); +const rinkebyDomain = deploysToSDK(rinkebyCoreDeploy, rinkebyBridgeDeploy); + +// Enroll Kovan as spoke to Rinkeby hub +const kovanCoreDeploy = ExistingCoreDeploy.withPath( + kovan.chain, + kovan.devConfig, + path, +); +const kovanBridgeDeploy = new ExistingBridgeDeploy( + kovan.chain, + kovan.bridgeConfig, + path, +); +const kovanDomain = deploysToSDK(kovanCoreDeploy, kovanBridgeDeploy); + +// setup SDK +const sdkDomains = [rinkebyDomain, kovanDomain]; +const sdk = NomadContext.fromDomains(sdkDomains); +const sdkCores = [rinkebyCoreDeploy, kovanCoreDeploy]; +sdkCores.forEach((core) => { + sdk.registerProvider(core.chain.domain, core.provider); + sdk.registerSigner(core.chain.domain, core.deployer); +}); + +waitBatches(sdk, ENVIRONMENT, REASON); diff --git a/typescript/nomad-deploy/src/bridge/index.ts b/typescript/nomad-deploy/src/bridge/index.ts index 0f0601d2f..c9c276558 100644 --- a/typescript/nomad-deploy/src/bridge/index.ts +++ b/typescript/nomad-deploy/src/bridge/index.ts @@ -229,6 +229,23 @@ export async function deployTokenRegistry(deploy: AnyBridgeDeploy) { console.log(`deployed ${deploy.chain.name} TokenRegistry`); } +export async function deployBridgeRouterImplementation( + deploy: AnyBridgeDeploy, +): Promise { + console.log(`deploying ${deploy.chain.name} BridgeRouter Implementation`); + + const bridgeFactory = new xAppContracts.BridgeRouter__factory( + deploy.chain.deployer, + ); + const bridgeRouter = await bridgeFactory.deploy(deploy.overrides); + await bridgeRouter.deployTransaction.wait(deploy.chain.confirmations); + + // TODO: update deploy (?) verification (?) + + console.log(`deployed ${deploy.chain.name} BridgeRouter Implementation`); + return bridgeRouter; +} + /** * Deploys the BridgeRouter on the chain of the given deploy and updates * the deploy instance with the new contract. diff --git a/typescript/nomad-deploy/src/governance/upgrade/index.ts b/typescript/nomad-deploy/src/governance/upgrade/index.ts new file mode 100644 index 000000000..522f9fedf --- /dev/null +++ b/typescript/nomad-deploy/src/governance/upgrade/index.ts @@ -0,0 +1,35 @@ +import { CoreDeploy } from '../../core/CoreDeploy'; +import { + AnyBridgeDeploy, + deployBridgeRouterImplementation, +} from '../../bridge'; +import { NomadContext } from '@nomad-xyz/sdk'; +import { CallBatch } from '@nomad-xyz/sdk/nomad'; +import { executeBatch } from '../index'; + +export async function upgradeBridgeRouter( + sdk: NomadContext, + coreDeploy: CoreDeploy, + bridgeDeploy: AnyBridgeDeploy, + reason: string, +) { + // deploy new bridge router implementation + const newBridgeImplementation = await deployBridgeRouterImplementation( + bridgeDeploy, + ); + // TODO: update config with new implementation address (rust, sdk) + // TODO: update verification inputs + // construct governance batch + const batch = await CallBatch.fromContext(sdk); + // construct transaction to upgrade bridge router to new implementation + const bridgeUpgradeBeacon = + bridgeDeploy.contracts.bridgeRouter!.beacon.address; + const upgradeTx = + await coreDeploy.contracts.upgradeBeaconController!.populateTransaction.upgrade( + bridgeUpgradeBeacon, + newBridgeImplementation.address, + ); + batch.pushRemote(coreDeploy.chain.domain, upgradeTx); + // execute the call batch + await executeBatch(batch, coreDeploy.config.environment, reason); +}