diff --git a/ops/docker-compose-bnb.yml b/ops/docker-compose-bnb.yml index 885c39b362..5eb4d11d73 100644 --- a/ops/docker-compose-bnb.yml +++ b/ops/docker-compose-bnb.yml @@ -458,8 +458,10 @@ services: - bnb-network networks: - bnb-network: + default: name: local-network + bnb-network: + #name: local-network enable_ipv6: true ipam: config: diff --git a/packages/boba/contracts/bin/deploy.lb.ts b/packages/boba/contracts/bin/deploy.lb.ts new file mode 100644 index 0000000000..0e0d16b0b9 --- /dev/null +++ b/packages/boba/contracts/bin/deploy.lb.ts @@ -0,0 +1,60 @@ +import { Wallet, providers } from 'ethers' +import { getContractFactory } from '@bobanetwork/core_contracts' +import { supportedLocalTestnet } from '@bobanetwork/core_contracts/src/local-network-config' + +/* eslint-disable */ +require('dotenv').config() + +import hre from 'hardhat' + +/** @dev Separate deployment file as limited networks or per network deployments for light bridge (e.g. only L2/L1, etc.) not supported with regular deployment config & flow without deploying everyhing else. */ +const main = async () => { + console.log('Starting BOBA core contracts deployment for light bridge...') + + const network = process.env.NETWORK || 'local' + + const l1Provider = new providers.JsonRpcProvider(process.env.L1_NODE_WEB3_URL) + const l2Provider = new providers.JsonRpcProvider(process.env.L2_NODE_WEB3_URL) + + const deployer_l1 = new Wallet(process.env.DEPLOYER_PRIVATE_KEY, l1Provider) + const deployer_l2 = new Wallet(process.env.DEPLOYER_PRIVATE_KEY, l2Provider) + + const l1ChainId = (await l1Provider.getNetwork()).chainId + const isLocalAltL1 = supportedLocalTestnet[l1ChainId]?.isLocalAltL1 + + const getAddressManager = (provider: any, addressManagerAddress: any) => { + return getContractFactory('Lib_AddressManager') + .connect(provider) + .attach(addressManagerAddress) as any + } + + console.log( + `ADDRESS_MANAGER_ADDRESS was set to ${process.env.ADDRESS_MANAGER_ADDRESS}` + ) + const addressManager = getAddressManager( + deployer_l1, + process.env.ADDRESS_MANAGER_ADDRESS + ) + + await hre.run('deploy', { + isLocalAltL1, + l1Provider, + l2Provider, + deployer_l1, + deployer_l2, + addressManager, + network, + // to ensure only independent networks are deployed + isLightMode: true, + noCompile: process.env.NO_COMPILE ? true : false, + }) +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.log( + JSON.stringify({ error: error.message, stack: error.stack }, null, 2) + ) + process.exit(1) + }) diff --git a/packages/boba/contracts/deploy/000-Messenger.deploy.ts b/packages/boba/contracts/deploy/000-Messenger.deploy.ts index a738b0d8d3..5efd589528 100644 --- a/packages/boba/contracts/deploy/000-Messenger.deploy.ts +++ b/packages/boba/contracts/deploy/000-Messenger.deploy.ts @@ -13,6 +13,10 @@ require('dotenv').config() let L1CrossDomainMessengerFast: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/001-Proxy_Messenger.deploy.ts b/packages/boba/contracts/deploy/001-Proxy_Messenger.deploy.ts index 3cb8382e41..3b2d71f12c 100644 --- a/packages/boba/contracts/deploy/001-Proxy_Messenger.deploy.ts +++ b/packages/boba/contracts/deploy/001-Proxy_Messenger.deploy.ts @@ -14,6 +14,10 @@ let Factory__Proxy__L1CrossDomainMessengerFast: ContractFactory let Proxy__L1CrossDomainMessengerFast: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/002-LiquidityPools.deploy.ts b/packages/boba/contracts/deploy/002-LiquidityPools.deploy.ts index 9db605fe73..e2faca281a 100644 --- a/packages/boba/contracts/deploy/002-LiquidityPools.deploy.ts +++ b/packages/boba/contracts/deploy/002-LiquidityPools.deploy.ts @@ -12,6 +12,11 @@ let L1LiquidityPool: Contract let L2LiquidityPool: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/003-Proxy_LiquidityPools.deploy.ts b/packages/boba/contracts/deploy/003-Proxy_LiquidityPools.deploy.ts index cc4864a1f8..7bd7939779 100644 --- a/packages/boba/contracts/deploy/003-Proxy_LiquidityPools.deploy.ts +++ b/packages/boba/contracts/deploy/003-Proxy_LiquidityPools.deploy.ts @@ -13,6 +13,11 @@ let Proxy__L1LiquidityPool: Contract let Proxy__L2LiquidityPool: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/004-L2ERC20.deploy.ts b/packages/boba/contracts/deploy/004-L2ERC20.deploy.ts index 973adcda2b..561cdf82c2 100644 --- a/packages/boba/contracts/deploy/004-L2ERC20.deploy.ts +++ b/packages/boba/contracts/deploy/004-L2ERC20.deploy.ts @@ -23,6 +23,11 @@ const initialSupply_8 = utils.parseUnits('10000', 8) const initialSupply_18 = utils.parseEther('10000000000') const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const registerLPToken = async (L1TokenAddress, L2TokenAddress) => { const registerL1LP = await Proxy__L1LiquidityPool.registerPool( L1TokenAddress, diff --git a/packages/boba/contracts/deploy/005-TokenPool.deploy.ts b/packages/boba/contracts/deploy/005-TokenPool.deploy.ts index 99d0ee7093..438babd55b 100644 --- a/packages/boba/contracts/deploy/005-TokenPool.deploy.ts +++ b/packages/boba/contracts/deploy/005-TokenPool.deploy.ts @@ -11,6 +11,11 @@ import { let L2TokenPool: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/006-TestComms.deploy.ts b/packages/boba/contracts/deploy/006-TestComms.deploy.ts index 84b572eae9..bbf3514da4 100644 --- a/packages/boba/contracts/deploy/006-TestComms.deploy.ts +++ b/packages/boba/contracts/deploy/006-TestComms.deploy.ts @@ -12,6 +12,11 @@ let L1Message: Contract let L2Message: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/007-AtomicSwap.deploy.ts b/packages/boba/contracts/deploy/007-AtomicSwap.deploy.ts index 1ef90d21a9..4742cc9dbd 100644 --- a/packages/boba/contracts/deploy/007-AtomicSwap.deploy.ts +++ b/packages/boba/contracts/deploy/007-AtomicSwap.deploy.ts @@ -11,6 +11,11 @@ import { let AtomicSwap: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/008-NFT.deploy.ts b/packages/boba/contracts/deploy/008-NFT.deploy.ts index 83c80558f9..1e64389820 100644 --- a/packages/boba/contracts/deploy/008-NFT.deploy.ts +++ b/packages/boba/contracts/deploy/008-NFT.deploy.ts @@ -15,6 +15,11 @@ const nftName = 'TestNFT' const nftSymbol = 'TST' const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/009-NFTBridges.deploy.ts b/packages/boba/contracts/deploy/009-NFTBridges.deploy.ts index d23084f274..ddc6d56736 100644 --- a/packages/boba/contracts/deploy/009-NFTBridges.deploy.ts +++ b/packages/boba/contracts/deploy/009-NFTBridges.deploy.ts @@ -12,6 +12,11 @@ let L1NFTBridge: Contract let L2NFTBridge: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const isLocalAltL1 = (hre as any).deployConfig.isLocalAltL1 const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/010-Proxy_NFTBridges.deploy.ts b/packages/boba/contracts/deploy/010-Proxy_NFTBridges.deploy.ts index d477f52b14..91ee2fea81 100644 --- a/packages/boba/contracts/deploy/010-Proxy_NFTBridges.deploy.ts +++ b/packages/boba/contracts/deploy/010-Proxy_NFTBridges.deploy.ts @@ -13,6 +13,11 @@ let Proxy__L1NFTBridge: Contract let Proxy__L2NFTBridge: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/011-L2ERC721.deploy.ts b/packages/boba/contracts/deploy/011-L2ERC721.deploy.ts index a5e40fee13..56ce717e13 100644 --- a/packages/boba/contracts/deploy/011-L2ERC721.deploy.ts +++ b/packages/boba/contracts/deploy/011-L2ERC721.deploy.ts @@ -16,6 +16,11 @@ let L1ERC721: Contract let L2ERC721: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/012-MultiMessageRelayerFast.deploy.ts b/packages/boba/contracts/deploy/012-MultiMessageRelayerFast.deploy.ts index 139ed663b5..710982eee9 100644 --- a/packages/boba/contracts/deploy/012-MultiMessageRelayerFast.deploy.ts +++ b/packages/boba/contracts/deploy/012-MultiMessageRelayerFast.deploy.ts @@ -13,6 +13,11 @@ require('dotenv').config() let L1_MultiMessageRelayerFast: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } + const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/013-BobaDao.deploy.ts b/packages/boba/contracts/deploy/013-BobaDao.deploy.ts index 26af5f4600..b7a0c56d83 100644 --- a/packages/boba/contracts/deploy/013-BobaDao.deploy.ts +++ b/packages/boba/contracts/deploy/013-BobaDao.deploy.ts @@ -24,6 +24,10 @@ const getTimestamp = async (hre) => { } const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } if ((hre as any).deployConfig.isLocalAltL1) { return } diff --git a/packages/boba/contracts/deploy/014-BobaTuring.deploy.ts b/packages/boba/contracts/deploy/014-BobaTuring.deploy.ts index 514d5e0c48..f2aaa3450b 100644 --- a/packages/boba/contracts/deploy/014-BobaTuring.deploy.ts +++ b/packages/boba/contracts/deploy/014-BobaTuring.deploy.ts @@ -11,6 +11,10 @@ let L2Boba: Contract let BobaTuringHelper: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const isLocalAltL1 = (hre as any).deployConfig.isLocalAltL1 const addressManager = getContractFactory('Lib_AddressManager') diff --git a/packages/boba/contracts/deploy/015-ExitFee.deploy.ts b/packages/boba/contracts/deploy/015-ExitFee.deploy.ts index e6afab40b2..b4e5e5adbb 100644 --- a/packages/boba/contracts/deploy/015-ExitFee.deploy.ts +++ b/packages/boba/contracts/deploy/015-ExitFee.deploy.ts @@ -11,6 +11,10 @@ import { let DiscretionaryExitFee: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const isLocalAltL1 = (hre as any).deployConfig.isLocalAltL1 const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/016-BobaSaving.deploy.ts b/packages/boba/contracts/deploy/016-BobaSaving.deploy.ts index 3156000f8c..a8bcf58c3c 100644 --- a/packages/boba/contracts/deploy/016-BobaSaving.deploy.ts +++ b/packages/boba/contracts/deploy/016-BobaSaving.deploy.ts @@ -12,6 +12,10 @@ let BobaFixedSavings: Contract let Proxy__BobaFixedSavings: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/017-FeedRegistry.deploy.ts b/packages/boba/contracts/deploy/017-FeedRegistry.deploy.ts index 7731ba3386..278c4d7351 100644 --- a/packages/boba/contracts/deploy/017-FeedRegistry.deploy.ts +++ b/packages/boba/contracts/deploy/017-FeedRegistry.deploy.ts @@ -11,6 +11,10 @@ import { let FeedRegistry: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/018-PriceFeedOracle.deploy.ts b/packages/boba/contracts/deploy/018-PriceFeedOracle.deploy.ts index ecacb88143..f29b6011c8 100644 --- a/packages/boba/contracts/deploy/018-PriceFeedOracle.deploy.ts +++ b/packages/boba/contracts/deploy/018-PriceFeedOracle.deploy.ts @@ -16,6 +16,10 @@ const address = (id: number) => { } const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/019-L2BillingContract.deploy.ts b/packages/boba/contracts/deploy/019-L2BillingContract.deploy.ts index c939d69524..a8d11b36b4 100644 --- a/packages/boba/contracts/deploy/019-L2BillingContract.deploy.ts +++ b/packages/boba/contracts/deploy/019-L2BillingContract.deploy.ts @@ -16,6 +16,10 @@ let DiscretionaryExitFee: Contract let L2NFTBridgeContract: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const isLocalAltL1 = (hre as any).deployConfig.isLocalAltL1 const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/020-Teleportation.deploy.ts b/packages/boba/contracts/deploy/020-Teleportation.deploy.ts index 8df742a188..2d00e043b4 100644 --- a/packages/boba/contracts/deploy/020-Teleportation.deploy.ts +++ b/packages/boba/contracts/deploy/020-Teleportation.deploy.ts @@ -1,5 +1,5 @@ /* Imports: External */ -import { Contract, ethers, providers } from 'ethers' +import {BigNumber, Contract, ethers, providers} from 'ethers' import { DeployFunction } from 'hardhat-deploy/dist/types' import { getContractFactory } from '@bobanetwork/core_contracts' import { @@ -31,11 +31,20 @@ enum ChainIds { BOBA_ETH_MAINNET = 288, BOBA_BNB_MAINNET = 56288, BNB_MAINNET = 56, + OPTIMISM_MAINNET = 10, + ARBITRUM_MAINNET = 42161, GOERLI_TESTNET = 5, BOBA_GOERLI_TESTNET = 2888, BOBA_BNB_TESTNET = 9728, BNB_TESTNET = 97, + OPTIMISM_TESTNET = 420, + ARBITRUM_TESTNET = 421613, + + /*LOCAL = 31337, + LOCAL_2 = 31338, + LOCAL_BNB = 99, + LOCAL_BNB_2 = 100,*/ } const deployFn: DeployFunction = async (hre) => { @@ -45,17 +54,23 @@ const deployFn: DeployFunction = async (hre) => { console.log(`'Deploying Teleportation contract...`) + const l1Provider = new providers.JsonRpcProvider(process.env.L1_NODE_WEB3_URL) const l2Provider = new providers.JsonRpcProvider(process.env.L2_NODE_WEB3_URL) - const network = await l2Provider.getNetwork() + const l2Network = await l2Provider.getNetwork() + const l1Network = await l1Provider.getNetwork() - console.log('Network name=', network?.name) - console.log('Network chain id=', network?.chainId) - const currChainId = network.chainId as ChainIds // (await hre.getChainId()) as any as ChainIds + console.log(`Network name=${l2Network?.name} (L2), ${l1Network?.name} (L1)`) + console.log(`Network chain id=${l2Network?.chainId} (L2), ${l1Network?.name} (L1)`) let fileName - let isL2 = true; - for (const deployer of [(hre as any).deployConfig.deployer_l2, (hre as any).deployConfig.deployer_l1]) { - const redeploy = true + for (const {deployer, isL2} of [{deployer: (hre as any).deployConfig.deployer_l2, isL2: true}, {deployer: (hre as any).deployConfig.deployer_l1, isL2: false}]) { + const currChainId = (isL2 ? l2Network.chainId : l1Network.chainId) as ChainIds // (await hre.getChainId()) as any as ChainIds + + // TODO: change back for avoiding errors, right now Goerli + const previousDeploymentAddress = "0x..................." // TODO: Adapt your address here + + const redeploy = !(ethers.utils.isAddress(previousDeploymentAddress) && !isL2) ?? true + if (redeploy) { Teleportation = await deployBobaContract( hre, @@ -66,10 +81,10 @@ const deployFn: DeployFunction = async (hre) => { const TeleportationDeploymentSubmission = getDeploymentSubmission(Teleportation) await hre.deployments.save( - 'Teleportation', + isL2 ? 'L2Teleportation' : 'L1Teleportation', TeleportationDeploymentSubmission ) - console.log(`Teleportation deployed to: ${Teleportation.address}`) + console.log(`Teleportation for isL2 (${isL2}) deployed to: ${Teleportation.address}`) Proxy__Teleportation = await deployBobaContract( hre, @@ -90,14 +105,20 @@ const deployFn: DeployFunction = async (hre) => { `${isL2 ? 'L2' : 'L1'} Proxy__Teleportation deployed to: ${Proxy__Teleportation.address}` ) } else { + if (!previousDeploymentAddress || !ethers.utils.isAddress(previousDeploymentAddress)) { + throw new Error("Trying to use previous address, but cannot find previous deployment - not configured address: "+previousDeploymentAddress) + } + fileName = `${previousDeploymentAddress}-${currChainId}` + file.log(fileName, "Using previous deployment of Teleportation contract on " + previousDeploymentAddress + ", " + isL2) Proxy__Teleportation = await getBobaContractAt( - `${isL2 ? 'L2' : 'L1'}Teleportation`, - '0x...................', // TODO: Adapt your address here + 'Teleportation', + previousDeploymentAddress, deployer ) } // change abi for proxy + console.log("Changing abi from Proxy to Teleportation as calls are delegated..") Proxy__Teleportation = await getBobaContractAt( 'Teleportation', Proxy__Teleportation.address, @@ -109,131 +130,225 @@ const deployFn: DeployFunction = async (hre) => { const defMaxDailyAmount = ethers.utils.parseEther('100000') // Initialize the Proxy__Teleportation contract - let res = await Proxy__Teleportation.initialize() - file.log(fileName, `Initialized proxy: ${await res.wait()}`) - res = await Teleportation.initialize() - file.log(fileName, `Teleportation initialized: ${await res.wait()}`) + if (redeploy) { + let res = await Proxy__Teleportation.initialize() + file.log(fileName, `Initialized proxy: ${await res.wait()}`) + res = await Teleportation.initialize() + file.log(fileName, `Teleportation initialized: ${await res.wait()}`) + } else { + file.log(fileName, `Not initializing contract again as already done.`) + } // TODO: Add Mainnet routes - const desiredRoutes = [ + type Route = { + fromChainId: ChainIds, + toChainId: ChainIds, + fromTokenAddr: string, + minAmount: BigNumber, + maxAmount: BigNumber, + maxDailyAmount: BigNumber, + } + const desiredRoutes: Route[] = [ // ETH: ETH <-> ETH BOBA { fromChainId: ChainIds.GOERLI_TESTNET, toChainId: ChainIds.BOBA_GOERLI_TESTNET, fromTokenAddr: '0x0000000000000000000000000000000000000000', // eth + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BOBA_GOERLI_TESTNET, toChainId: ChainIds.GOERLI_TESTNET, fromTokenAddr: '0x0000000000000000000000000000000000000000', // eth + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, // ETH: BNB <-> BNB BOBA { fromChainId: ChainIds.BNB_TESTNET, toChainId: ChainIds.BOBA_BNB_TESTNET, fromTokenAddr: '0xd66c6B4F0be8CE5b39D52E0Fd1344c389929B378', // eth + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BOBA_BNB_TESTNET, toChainId: ChainIds.BNB_TESTNET, fromTokenAddr: '0xc614A66f82e71758Fa7735C91dAD1088c8362f15', // eth + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, // BOBA: ETH <-> ETH Boba { fromChainId: ChainIds.GOERLI_TESTNET, toChainId: ChainIds.BOBA_GOERLI_TESTNET, fromTokenAddr: '0xeCCD355862591CBB4bB7E7dD55072070ee3d0fC1', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BOBA_GOERLI_TESTNET, toChainId: ChainIds.GOERLI_TESTNET, fromTokenAddr: '0x4200000000000000000000000000000000000023', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, // BOBA: ETH <-> BNB { fromChainId: ChainIds.GOERLI_TESTNET, toChainId: ChainIds.BNB_TESTNET, fromTokenAddr: '0xeCCD355862591CBB4bB7E7dD55072070ee3d0fC1', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BNB_TESTNET, toChainId: ChainIds.GOERLI_TESTNET, fromTokenAddr: '0x875cD11fDf085e0E11B0EE6b814b6d0b38fA554C', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, // BOBA: BNB <-> Boba BNB { fromChainId: ChainIds.BNB_TESTNET, toChainId: ChainIds.BOBA_BNB_TESTNET, fromTokenAddr: '0x875cD11fDf085e0E11B0EE6b814b6d0b38fA554C', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BOBA_BNB_TESTNET, toChainId: ChainIds.BNB_TESTNET, fromTokenAddr: '0x0000000000000000000000000000000000000000', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, // BOBA: ETH BOBA <-> Boba BNB { fromChainId: ChainIds.BOBA_GOERLI_TESTNET, toChainId: ChainIds.BOBA_BNB_TESTNET, fromTokenAddr: '0x4200000000000000000000000000000000000023', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BOBA_BNB_TESTNET, toChainId: ChainIds.BOBA_GOERLI_TESTNET, fromTokenAddr: '0x0000000000000000000000000000000000000000', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, // BOBA: ETH BOBA <-> BNB { fromChainId: ChainIds.BOBA_GOERLI_TESTNET, toChainId: ChainIds.BNB_TESTNET, fromTokenAddr: '0x4200000000000000000000000000000000000023', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, { fromChainId: ChainIds.BNB_TESTNET, toChainId: ChainIds.BOBA_GOERLI_TESTNET, fromTokenAddr: '0x875cD11fDf085e0E11B0EE6b814b6d0b38fA554C', // boba + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, + }, + // limitedNetworks (ARB/OP) + { + // only supporting onboarding + fromChainId: ChainIds.OPTIMISM_TESTNET, + toChainId: ChainIds.BOBA_GOERLI_TESTNET, + fromTokenAddr: '0x0000000000000000000000000000000000000000', // eth + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, }, + { + // only supporting onboarding + fromChainId: ChainIds.ARBITRUM_TESTNET, + toChainId: ChainIds.BOBA_GOERLI_TESTNET, + fromTokenAddr: '0x0000000000000000000000000000000000000000', // eth + minAmount: defMinAmount, + maxAmount: defMaxAmount, + maxDailyAmount: defMaxDailyAmount, + }, + // NOTE: Boba token not supported for OP/ARB, as not deployed there (thus Boba BNB where Boba is native is not supported & no WETH available) ] - const addRoute = async (toChainId: ChainIds, tokenAddr: string) => { - const routeRres = await Proxy__Teleportation.addSupportedToken( - tokenAddr, + const addRoute = async ({toChainId, fromTokenAddr, minAmount, maxAmount, maxDailyAmount}: Route) => { + try { + // avoid wasting gas if already supported + await Proxy__Teleportation.estimateGas.addSupportedToken( + fromTokenAddr, + toChainId, + minAmount, + maxAmount, + maxDailyAmount, + ) + const routeRes = await Proxy__Teleportation.addSupportedToken( + fromTokenAddr, toChainId, - defMinAmount, - defMaxAmount, - defMaxDailyAmount + minAmount, + maxAmount, + maxDailyAmount, ) file.log( fileName, - `Added route for ${toChainId} chain, and token: ${tokenAddr}, receipt: ${await routeRres.wait()}` + `Added route for ${toChainId} chain, and token: ${fromTokenAddr}, receipt: ${await routeRes.wait()}` ) + } catch(err) { + if (JSON.stringify(err).includes('Already supported')) { + file.log(fileName, `Route for ${toChainId} chain, and token: ${fromTokenAddr} not added again, as already supported.`) + } else { + throw new err; + } + } } for (const route of desiredRoutes) { if (currChainId === route.fromChainId) { - await addRoute(route.toChainId, route.fromTokenAddr) + await addRoute(route) } } - await registerBobaAddress( - addressManager, - isL2 ? 'Proxy__L2Teleportation' : 'Proxy__L1Teleportation', - Proxy__Teleportation.address - ) - await registerBobaAddress( - addressManager, - isL2 ? 'L2Teleportation' : 'L1Teleportation', - Teleportation.address - ) + try { + if (redeploy) { + await registerBobaAddress( + addressManager, + isL2 ? 'Proxy__L2Teleportation' : 'Proxy__L1Teleportation', + Proxy__Teleportation.address + ) + await registerBobaAddress( + addressManager, + isL2 ? 'L2Teleportation' : 'L1Teleportation', + Teleportation.address + ) + } else { + console.log("Not adding contract to AddressManager, as already added (used previous deployment, e.g. for limited networks like OP/ARB)") + } + } catch(err) { + console.error("Registering addresses into AddressManager failed, probably missing permission: ", err); + } - isL2 = false; file.log(fileName, 'Network iteration done') } - - - file.log(fileName, 'DONE') } -deployFn.tags = ['Proxy__Teleportation', 'Teleportation', 'required'] +deployFn.tags = ['Proxy__Teleportation', 'Teleportation', 'required', 'lightmode'] export default deployFn diff --git a/packages/boba/contracts/deploy/021-ERC1155Bridges.deploy.ts b/packages/boba/contracts/deploy/021-ERC1155Bridges.deploy.ts index ad60021f15..a276b62911 100644 --- a/packages/boba/contracts/deploy/021-ERC1155Bridges.deploy.ts +++ b/packages/boba/contracts/deploy/021-ERC1155Bridges.deploy.ts @@ -12,6 +12,10 @@ let L1ERC1155Bridge: Contract let L2ERC1155Bridge: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const isLocalAltL1 = (hre as any).deployConfig.isLocalAltL1 const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) diff --git a/packages/boba/contracts/deploy/021-Proxy__ERC1155Bridges.deploy.ts b/packages/boba/contracts/deploy/021-Proxy__ERC1155Bridges.deploy.ts index 04dbf81155..fb23037f8a 100644 --- a/packages/boba/contracts/deploy/021-Proxy__ERC1155Bridges.deploy.ts +++ b/packages/boba/contracts/deploy/021-Proxy__ERC1155Bridges.deploy.ts @@ -13,6 +13,10 @@ let Proxy__L1ERC1155Bridge: Contract let Proxy__L2ERC1155Bridge: Contract const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/deploy/022-PriceFeedOracleHC.deploy.ts b/packages/boba/contracts/deploy/022-PriceFeedOracleHC.deploy.ts index 18df501d85..a92b3e6894 100644 --- a/packages/boba/contracts/deploy/022-PriceFeedOracleHC.deploy.ts +++ b/packages/boba/contracts/deploy/022-PriceFeedOracleHC.deploy.ts @@ -17,6 +17,10 @@ const address = (id: number) => { } const deployFn: DeployFunction = async (hre) => { + if ((hre as any).deployConfig.isLightMode) { + console.log('Skipping deployment function as in light mode..') + return; + } const addressManager = getContractFactory('Lib_AddressManager') .connect((hre as any).deployConfig.deployer_l1) .attach(process.env.ADDRESS_MANAGER_ADDRESS) as any diff --git a/packages/boba/contracts/hardhat.config.ts b/packages/boba/contracts/hardhat.config.ts index d9a5db1620..565091e701 100644 --- a/packages/boba/contracts/hardhat.config.ts +++ b/packages/boba/contracts/hardhat.config.ts @@ -94,6 +94,18 @@ const config: HardhatUserConfig = { bobaoperaTestnet: { url: 'https://testnet.bobaopera.boba.network', }, + optimismTestnet: { + url: 'https://optimism-goerli.publicnode.com', + }, + arbitrumTestnet: { + url: 'https://arbitrum-goerli.publicnode.com', + }, + optimismMainnet: { + url: 'https://optimism.llamarpc.com', + }, + arbitrumMainnet: { + url: 'https://endpoints.omniatech.io/v1/arbitrum/goerli/public', + }, }, solidity: { compilers: [ @@ -173,6 +185,10 @@ const config: HardhatUserConfig = { bobaopera: 'DEFAULT_KEY', fantomTestnet: process.env.FTMSCAN_KEY, bobaoperaTestnet: 'DEFAULT_KEY', + optimismMainnet: process.env.OPTIMISM_ETHERSCAN_KEY, + optimismTestnet: process.env.OPTIMISM_ETHERSCAN_KEY, + arbitrumMainnet: process.env.ARBITRUM_ETHERSCAN_KEY, + arbitrumTestnet: process.env.ARBITRUM_ETHERSCAN_KEY, }, customChains: [ { @@ -319,6 +335,38 @@ const config: HardhatUserConfig = { browserURL: 'https://blockexplorer.testnet.bobaopera.boba.network/', }, }, + { + network: 'optimismMainnet', + chainId: 10, + urls: { + apiURL: 'https://api-optimistic.etherscan.io/', + browserURL: 'https://optimistic.etherscan.io/', + }, + }, + { + network: 'optimismTestnet', + chainId: 420, + urls: { + apiURL: 'https://api-goerli-optimistic.etherscan.io/', + browserURL: 'https://goerli-optimism.etherscan.io/', + }, + }, + { + network: 'arbitrumMainnet', + chainId: 42161, + urls: { + apiURL: 'https://api-arbiscan.io/', + browserURL: 'https://arbiscan.io/', + }, + }, + { + network: 'arbitrumTestnet', + chainId: 421613, + urls: { + apiURL: 'https://api-goerli.arbiscan.io/', + browserURL: 'https://goerli.arbiscan.io/', + }, + }, ], }, } diff --git a/packages/boba/contracts/package.json b/packages/boba/contracts/package.json index 22d0968664..b30433914f 100644 --- a/packages/boba/contracts/package.json +++ b/packages/boba/contracts/package.json @@ -13,6 +13,7 @@ "build:typescript": "tsc -p ./tsconfig.json", "autogen:artifacts": "ts-node src/generate-artifacts.ts", "deploy": "ts-node \"./bin/deploy.ts\"", + "deploy:light": "ts-node \"./bin/deploy.lb.ts\"", "clean": "rm -rf ./artifacts ./cache", "lint": "yarn lint:check", "lint:check": "eslint . --ext js,jsx,ts,tsx", diff --git a/packages/boba/contracts/src/hardhat-deploy-ethers.ts b/packages/boba/contracts/src/hardhat-deploy-ethers.ts index 0e9fa5c54b..b4b7d518a4 100644 --- a/packages/boba/contracts/src/hardhat-deploy-ethers.ts +++ b/packages/boba/contracts/src/hardhat-deploy-ethers.ts @@ -114,10 +114,14 @@ export const getBobaContractAt = async ( address: string, signer?: any ) => { + const artifact = getContractArtifact(name) + if (!artifact) { + throw new Error(`Contract artifact ${name} not found..`) + } if (!signer) { - return new Contract(address, getContractArtifact(name).abi) + return new Contract(address, artifact.abi) } - return new Contract(address, getContractArtifact(name).abi, signer) + return new Contract(address, artifact.abi, signer) } export const getBobaContractABI = (name: string) => { diff --git a/packages/boba/subgraph/L2/config/goerli-l1.json b/packages/boba/subgraph/L2/config/goerli-l1.json new file mode 100644 index 0000000000..7ba6554c74 --- /dev/null +++ b/packages/boba/subgraph/L2/config/goerli-l1.json @@ -0,0 +1,26 @@ +{ + "network": "goerli", + "contracts": { + "L2LiquidityPool": { + "address": "0x0000000000000000000000000000000000000000" + }, + "OVM_L2StandardBridge": { + "address": "0x0000000000000000000000000000000000000000" + }, + "GovernorBravoDelegate": { + "address": "0x0000000000000000000000000000000000000000" + }, + "Boba_GasPriceOracle": { + "address": "0x0000000000000000000000000000000000000000" + }, + "TuringHelperFactory": { + "address": "0x0000000000000000000000000000000000000000" + }, + "TuringMonsters": { + "address": "0x0000000000000000000000000000000000000000" + }, + "Teleportation": { + "address": "0x84b22166366a6f7E0cD0c3ce9998f2913Bf17A13" + } + } +} diff --git a/packages/boba/subgraph/L2/subgraph.yaml b/packages/boba/subgraph/L2/subgraph.yaml index 2625a86381..bb4299e287 100644 --- a/packages/boba/subgraph/L2/subgraph.yaml +++ b/packages/boba/subgraph/L2/subgraph.yaml @@ -6,9 +6,9 @@ schema: dataSources: - kind: ethereum/contract name: L2LiquidityPool - network: boba + network: goerli source: - address: '0x8d3866a79aA780BA3DC1a300a1567635F3754a0e' + address: '0x0000000000000000000000000000000000000000' abi: L2LiquidityPool mapping: kind: ethereum/events @@ -36,9 +36,9 @@ dataSources: - kind: ethereum/contract name: OVM_L2StandardBridge - network: boba + network: goerli source: - address: '0x4200000000000000000000000000000000000010' + address: '0x0000000000000000000000000000000000000000' abi: OVM_L2StandardBridge mapping: kind: ethereum/events @@ -60,9 +60,9 @@ dataSources: - kind: ethereum/contract name: GovernorBravoDelegate - network: boba + network: goerli source: - address: '0x472e5C097C790c6a44366a89a987Ec996A4d83e0' + address: '0x0000000000000000000000000000000000000000' abi: GovernorBravoDelegate mapping: kind: ethereum/events @@ -100,9 +100,9 @@ dataSources: - kind: ethereum/contract name: Boba_GasPriceOracle - network: boba + network: goerli source: - address: '0x7F974A09a251dEA6b75af3e0A0e29D1133DaCf4b' + address: '0x0000000000000000000000000000000000000000' abi: Boba_GasPriceOracle mapping: kind: ethereum/events @@ -124,9 +124,9 @@ dataSources: - kind: ethereum/contract name: TuringMonsters - network: boba + network: goerli source: - address: '0x757b8E819d91659844E44F2141402831B60Fa4EE' + address: '0x0000000000000000000000000000000000000000' abi: TuringMonsters mapping: kind: ethereum/events @@ -145,9 +145,9 @@ dataSources: - kind: ethereum/contract name: TuringHelperFactory - network: boba + network: goerli source: - address: '0x58dDFB37998584991d8b75F87baf0A3428dD095e' + address: '0x0000000000000000000000000000000000000000' abi: TuringHelperFactory mapping: kind: ethereum/events @@ -165,9 +165,9 @@ dataSources: - kind: ethereum/contract name: Teleportation - network: boba + network: goerli source: - address: '0xf4d179d3a083Fa3Eede935FaF4C679D32d514186' + address: '0x84b22166366a6f7E0cD0c3ce9998f2913Bf17A13' abi: Teleportation mapping: kind: ethereum/events diff --git a/packages/boba/teleportation/README.md b/packages/boba/teleportation/README.md index 80d725a4d4..0fe57b2e38 100644 --- a/packages/boba/teleportation/README.md +++ b/packages/boba/teleportation/README.md @@ -54,6 +54,14 @@ Audits outstanding. - Teleportation deployed to: `0x46FA6144C61d2bb9aCDc3Ca90C8673dd9B6caEB2` - Proxy__Teleportation deployed to: `0xf4d179d3a083Fa3Eede935FaF4C679D32d514186` +### Arbitrum Goerli +- Teleportation deployed to: `0x81F27a114A25ac1c6186fC36888B1b120a46a650` +- Proxy__Teleportation deployed to: `0x7063f59e1Db3e505D844d11A71C78F92D39E5963` + +### Optimism Goerli +- Teleportation deployed to: `0x885bfeC3D89755d2bCc1e73b6EeEEae94D54eBE4` +- Proxy__Teleportation deployed to: `0xC226F132A686A08018431C913d87693396246024` + --- @@ -66,7 +74,7 @@ Audits outstanding. ## Contract params This section describes how whitelisted routes between networks can be configured. By default no asset can be bridged, not even the native asset - all need to be explicitly whitelisted. -Asset support is configured on-chain on the Teleportation contract via +Asset support is configured on-chain on the Teleportation contract via `function addSupportedToken(address _token, uint32 _toChainId, uint256 _minDepositAmount, uint256 _maxDepositAmount, uint256 _maxTransferAmountPerDay)`. ### Indicate support diff --git a/packages/boba/teleportation/src/utils/chains.ts b/packages/boba/teleportation/src/utils/chains.ts index e49880a615..acbe833b46 100644 --- a/packages/boba/teleportation/src/utils/chains.ts +++ b/packages/boba/teleportation/src/utils/chains.ts @@ -27,6 +27,7 @@ export const BobaChains: IBobaChains = { //#region boba_networks 288: { + // TODO: seemingly no public graph node available (would require hosted_service or deploying it ourselves) --> boba listed though, but requires a hosted service url: 'https://boba-ethereum.gateway.tenderly.co/1clfZoq7qEGyF4SQvF8gvI', testnet: false, name: 'Boba Ethereum Mainnet', @@ -40,6 +41,7 @@ export const BobaChains: IBobaChains = { }, }, 56288: { + // TODO: seemingly no public graph node available (would require hosted_service or deploying it ourselves) url: 'https://boba-bnb.gateway.tenderly.co/1clfZoq7qEGyF4SQvF8gvI', testnet: false, name: 'Boba BNB Mainnet', @@ -51,6 +53,7 @@ export const BobaChains: IBobaChains = { }, }, 2888: { + // TODO: seemingly no public graph node available (would require hosted_service or deploying it ourselves) url: 'https://replica.goerli.boba.network', testnet: true, name: 'Boba Ethereum Goerli', @@ -62,6 +65,7 @@ export const BobaChains: IBobaChains = { }, }, 9728: { + // TODO: seemingly no public graph node available (would require hosted_service or deploying it ourselves) url: 'https://boba-bnb-testnet.gateway.tenderly.co/1clfZoq7qEGyF4SQvF8gvI', testnet: true, name: 'Boba BNB Testnet', @@ -73,9 +77,30 @@ export const BobaChains: IBobaChains = { ['0xc614A66f82e71758Fa7735C91dAD1088c8362f15'.toLowerCase()]: Asset.ETH, }, }, + 421613: { + url: 'https://arbitrum-goerli.public.blastapi.io', + testnet: true, + name: 'Arbitrum Goerli', + teleportationAddress: '0x7063f59e1Db3e505D844d11A71C78F92D39E5963', + height: 53880808, + supportedAssets: { + ['0x0000000000000000000000000000000000000000'.toLowerCase()]: Asset.ETH, + }, + }, + 420: { + url: 'https://optimism-goerli.publicnode.com', + testnet: true, + name: 'Optimism Goerli', + teleportationAddress: '0xC226F132A686A08018431C913d87693396246024', + height: 17010097, + supportedAssets: { + ['0x0000000000000000000000000000000000000000'.toLowerCase()]: Asset.ETH, + }, + }, //#endregion //#region l1 1: { + // TODO: Public nodes available, deploy once contract is live url: 'https://mainnet.gateway.tenderly.co/1clfZoq7qEGyF4SQvF8gvI', testnet: false, name: 'Ethereum Mainnet', @@ -89,6 +114,7 @@ export const BobaChains: IBobaChains = { }, }, 56: { + // TODO: Public nodes available, deploy once contract is live url: 'https://rpc.ankr.com/bsc', testnet: false, name: 'BNB Mainnet', @@ -102,6 +128,7 @@ export const BobaChains: IBobaChains = { }, }, 5: { + // TODO: DEV VERSION (GRT tokens needed): subgraph deployed: https://api.studio.thegraph.com/query/57436/boba_bridges/version/latest url: 'https://goerli.gateway.tenderly.co', testnet: true, name: 'Goerli Testnet', @@ -115,6 +142,7 @@ export const BobaChains: IBobaChains = { }, }, 97: { + // TODO: seemingly no public graph node available (would require hosted_service or deploying it ourselves) url: 'https://api.zan.top/node/v1/bsc/testnet/public', testnet: true, name: 'BNB Testnet',