From 3561a3a7fc927be94ffd866d559085a3c4391d8f Mon Sep 17 00:00:00 2001 From: ryanbajollari <54822716+rbajollari@users.noreply.github.com> Date: Wed, 19 Jun 2024 09:55:16 -0400 Subject: [PATCH] refactor: Update deployment scripts (#47) * refactor: Update deployment scripts * price feeds script --- .env.example | 8 +- mainnet_chains.json | 33 +++++- scripts/createPriceFeed.ts | 37 ------- scripts/createPriceFeeds.ts | 50 +++++++++ scripts/deployCloneFactory.ts | 24 ++-- scripts/deployMockOjo.ts | 39 +++---- scripts/deployOjo.ts | 62 ++++++----- scripts/deployPriceFeedImplementation.ts | 24 ++-- scripts/upgradeOjo.ts | 37 ++++--- scripts/utils/upgradable.ts | 11 ++ testnet_chains.json | 133 +++++++++++++++++++---- 11 files changed, 310 insertions(+), 148 deletions(-) delete mode 100644 scripts/createPriceFeed.ts create mode 100644 scripts/createPriceFeeds.ts diff --git a/.env.example b/.env.example index fc1b313..19a3a94 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,10 @@ PRIVATE_KEY=yourprivatekeyhere CONTRACT_KEY=yourkeyhere MAINNET=FALSE -OJO_CONTRACT_ADDRESS=0x0 -AXELAR_GAS_RECEIVER_ADDRESS=0x2d5d7d31F671F86C782533cc367F14109a082712 -CREATE2_DEPLOYER_ADDRESS=0x98b2920d53612483f91f12ed7754e51b4a77919e +EVM_CHAINS=["Ethereum"] OJO_CHAIN=ojo OJO_ADDRESS=ojo1es9mhmnunh208ucwq8rlrl97hqulxrz8k37dcu RESOLVE_WINDOW=7200 ASSET_LIMIT=5 -PRICE_FEED_IMPLEMENTATION_CONTRACT_ADDRESS=0xD1077c12ba7C0ED41d288F5505af2Cb23bBD680a -CLONE_FACTORY_CONTRACT_ADDRESS=0x9AaE2ac2637B9f441d1537bBdCEB712854dd426B +PRICE_FEED_DECIMALS=9 +PRICE_FEED_DESCRIPTIONS=["steakLRT", "Re7LRT", "amphrETH", "rstETH"] diff --git a/mainnet_chains.json b/mainnet_chains.json index 77e730e..0d8e102 100644 --- a/mainnet_chains.json +++ b/mainnet_chains.json @@ -4,20 +4,47 @@ "chainId": 42161, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://arbitrum-mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0x2d5d7d31F671F86C782533cc367F14109a082712", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0xa1aB70C0F3725AcA1D1e85Bd4402Dd2d5F6AFf19", + "cloneFactory": "0xd285A4F0Ad1BB6b1Db8cD3dD839E9f423938ef9E" }, { "name": "Optimism", "chainId": 10, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://optimism-mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0x2d5d7d31F671F86C782533cc367F14109a082712", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0xfaC9d315b9b558e10eBdb0462aA42577aADe6601", + "cloneFactory": "0x02Ed15B70D4dE1209c3Dd5a75195CB3f3dDB8B07" }, { "name": "Base", "chainId": 8453, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://developer-access-mainnet.base.org", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0x2d5d7d31F671F86C782533cc367F14109a082712", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0x09d43904C8ABd470df1B793df68904A9714558CF", + "cloneFactory": "0xfaC9d315b9b558e10eBdb0462aA42577aADe6601" + }, + { + "name": "Ethereum", + "chainId": 1, + "gateway": "0x4F4495243837681061C4743b74B3eEdf548D56A5", + "rpc": "https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", + "tokenSymbol": "ETH", + "gasReceiver": "0x2d5d7d31F671F86C782533cc367F14109a082712", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0xde471274F1B684476d341eB131224F389AD4A270", + "cloneFactory": "0x710C8a3c8CB393cA24748849de3585b5C48D4D0c" } ] diff --git a/scripts/createPriceFeed.ts b/scripts/createPriceFeed.ts deleted file mode 100644 index 41b0ac5..0000000 --- a/scripts/createPriceFeed.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Wallet, ethers } from "ethers"; -import CloneFactory from '../artifacts/contracts/pricefeed/CloneFactory.sol/CloneFactory.json'; -import testnet_chains from '../testnet_chains.json'; -import mainnet_chains from '../mainnet_chains.json'; - -async function main() { - const cloneFactoryAddress = process.env.CLONE_FACTORY_CONTRACT_ADDRESS as string; - const priceFeedDecimals = 18; - const priceFeedDescription = "ETH"; - - const privateKey = process.env.PRIVATE_KEY; - - if (!privateKey) { - throw new Error('Invalid private key. Make sure the PRIVATE_KEY environment variable is set.'); - } - - const mainnet = process.env.MAINNET as string - let evmChains = testnet_chains.map((chain) => ({ ...chain })); - if (mainnet === "TRUE") { - evmChains = mainnet_chains.map((chain) => ({ ...chain })); - } - - for (const chain of evmChains) { - const provider = new ethers.JsonRpcProvider(chain.rpc) - const wallet = new Wallet(privateKey, provider); - const balance = await provider.getBalance(wallet.address) - console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); - - const cloneFactoryContract = new ethers.Contract(cloneFactoryAddress, CloneFactory.abi, wallet) - await cloneFactoryContract.createPriceFeed(priceFeedDecimals, priceFeedDescription) - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/createPriceFeeds.ts b/scripts/createPriceFeeds.ts new file mode 100644 index 0000000..8630f18 --- /dev/null +++ b/scripts/createPriceFeeds.ts @@ -0,0 +1,50 @@ +import { Wallet, ethers } from "ethers"; +import CloneFactory from '../artifacts/contracts/pricefeed/CloneFactory.sol/CloneFactory.json'; +import testnet_chains from '../testnet_chains.json'; +import mainnet_chains from '../mainnet_chains.json'; + +async function main() { + const evmChains = JSON.parse(process.env.EVM_CHAINS!); + const priceFeedDecimals = process.env.PRICE_FEED_DECIMALS as any; + const priceFeedDescriptions = JSON.parse(process.env.PRICE_FEED_DESCRIPTIONS!); + + const privateKey = process.env.PRIVATE_KEY; + + if (!privateKey) { + throw new Error('Invalid private key. Make sure the PRIVATE_KEY environment variable is set.'); + } + + const mainnet = process.env.MAINNET as string + let chains = testnet_chains.map((chain) => ({ ...chain })); + if (mainnet === "TRUE") { + chains = mainnet_chains.map((chain) => ({ ...chain })); + } + + for (const chain of chains) { + if (evmChains.includes(chain.name)) { + const provider = new ethers.JsonRpcProvider(chain.rpc) + const wallet = new Wallet(privateKey, provider); + const balance = await provider.getBalance(wallet.address) + console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); + + const cloneFactoryContract = new ethers.Contract(chain.cloneFactory, CloneFactory.abi, wallet) + for (const priceFeedDescription of priceFeedDescriptions) { + console.log(`Deploying ${priceFeedDescription} price feed on ${chain.name}`); + try { + const tx = await cloneFactoryContract.createPriceFeed(priceFeedDecimals, priceFeedDescription); + console.log(`Transaction sent: ${tx.hash}`); + + const receipt = await tx.wait(); + console.log(`Transaction mined: ${receipt.transactionHash}`); + } catch (error) { + console.error(`Failed to deploy ${priceFeedDescription} on ${chain.name}:`, error); + } + } + } + } +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/deployCloneFactory.ts b/scripts/deployCloneFactory.ts index e5f73a3..6cc51c8 100644 --- a/scripts/deployCloneFactory.ts +++ b/scripts/deployCloneFactory.ts @@ -4,7 +4,7 @@ import testnet_chains from '../testnet_chains.json'; import mainnet_chains from '../mainnet_chains.json'; async function main () { - const priceFeedImplementation = process.env.PRICE_FEED_IMPLEMENTATION_CONTRACT_ADDRESS; + const evmChains = JSON.parse(process.env.EVM_CHAINS!); const privateKey = process.env.PRIVATE_KEY; @@ -13,20 +13,22 @@ async function main () { } const mainnet = process.env.MAINNET as string - let evmChains = testnet_chains.map((chain) => ({ ...chain })); + let chains = testnet_chains.map((chain) => ({ ...chain })); if (mainnet === "TRUE") { - evmChains = mainnet_chains.map((chain) => ({ ...chain })); + chains = mainnet_chains.map((chain) => ({ ...chain })); } - for (const chain of evmChains) { - const provider = new ethers.JsonRpcProvider(chain.rpc) - const wallet = new Wallet(privateKey, provider); - const balance = await provider.getBalance(wallet.address) - console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); + for (const chain of chains) { + if (evmChains.includes(chain.name)) { + const provider = new ethers.JsonRpcProvider(chain.rpc) + const wallet = new Wallet(privateKey, provider); + const balance = await provider.getBalance(wallet.address) + console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); - const priceFeedFactory = new ethers.ContractFactory(CloneFactory.abi, CloneFactory.bytecode, wallet) - const priceFeed = await priceFeedFactory.deploy(priceFeedImplementation) - console.log(`${chain.name}, address: ${await priceFeed.getAddress()}`); + const priceFeedFactory = new ethers.ContractFactory(CloneFactory.abi, CloneFactory.bytecode, wallet) + const priceFeed = await priceFeedFactory.deploy(chain.priceFeedImplementation) + console.log(`${chain.name}, address: ${await priceFeed.getAddress()}`); + } } } diff --git a/scripts/deployMockOjo.ts b/scripts/deployMockOjo.ts index 5db1f62..af622c9 100644 --- a/scripts/deployMockOjo.ts +++ b/scripts/deployMockOjo.ts @@ -5,8 +5,7 @@ import testnet_chains from '../testnet_chains.json'; import mainnet_chains from '../mainnet_chains.json'; async function main() { - const ojoContractddress = process.env.OJO_CONTRACT_ADDRESS; - const create2DeployerAddress = process.env.CREATE2_DEPLOYER_ADDRESS as string; + const evmChains = JSON.parse(process.env.EVM_CHAINS!); const privateKey = process.env.PRIVATE_KEY; @@ -15,32 +14,34 @@ async function main() { } const mainnet = process.env.MAINNET as string - let evmChains = testnet_chains.map((chain) => ({ ...chain })); + let chains = testnet_chains.map((chain) => ({ ...chain })); if (mainnet === "TRUE") { - evmChains = mainnet_chains.map((chain) => ({ ...chain })); + chains = mainnet_chains.map((chain) => ({ ...chain })); } - for (const chain of evmChains) { - const provider = new ethers.JsonRpcProvider(chain.rpc) - const wallet = new Wallet(privateKey, provider); - const balance = await provider.getBalance(wallet.address) - console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); + for (const chain of chains) { + if (evmChains.includes(chain.name)) { + const provider = new ethers.JsonRpcProvider(chain.rpc) + const wallet = new Wallet(privateKey, provider); + const balance = await provider.getBalance(wallet.address) + console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); - const deployerContract = new ethers.Contract(create2DeployerAddress, Create2Deployer.abi, wallet); + const deployerContract = new ethers.Contract(chain.create2Deployer, Create2Deployer.abi, wallet); - const salt = ethers.zeroPadValue(ethers.toUtf8Bytes("MockOjo"), 32); + const salt = ethers.zeroPadValue(ethers.toUtf8Bytes("MockOjo"), 32); - const creationCode = ethers.solidityPacked( + const creationCode = ethers.solidityPacked( ["bytes", "bytes"], - [MockOjo.bytecode, ethers.AbiCoder.defaultAbiCoder().encode(["address"], [ojoContractddress])] - ); + [MockOjo.bytecode, ethers.AbiCoder.defaultAbiCoder().encode(["address"], [chain.ojoContract])] + ); - // perform static call to log address of the contract - const deployedAddress = await deployerContract.deploy.staticCallResult(creationCode, salt); - console.log(`${chain.name}, address: ${deployedAddress}`); + // perform static call to log address of the contract + const deployedAddress = await deployerContract.deploy.staticCallResult(creationCode, salt); + console.log(`${chain.name}, address: ${deployedAddress}`); - // perform actual deploy tx - await deployerContract.deploy(creationCode, salt); + // perform actual deploy tx + await deployerContract.deploy(creationCode, salt); + } } } diff --git a/scripts/deployOjo.ts b/scripts/deployOjo.ts index 27af4c6..bf0e059 100644 --- a/scripts/deployOjo.ts +++ b/scripts/deployOjo.ts @@ -3,13 +3,11 @@ import Ojo from '../artifacts/contracts/Ojo.sol/Ojo.json'; import OjoProxy from '../artifacts/contracts/OjoProxy.sol/OjoProxy.json'; import testnet_chains from '../testnet_chains.json'; import mainnet_chains from '../mainnet_chains.json'; -import { deployCreate2InitUpgradable } from './utils/upgradable'; +import { deployCreate2InitUpgradable, estimateDeploymentGas } from './utils/upgradable'; async function main() { - const axelarGasReceiverAddress = process.env.AXELAR_GAS_RECEIVER_ADDRESS; - const create2DeployerAddress = process.env.CREATE2_DEPLOYER_ADDRESS; + const evmChains = JSON.parse(process.env.EVM_CHAINS!); const ojoChain = process.env.OJO_CHAIN; - const ojoAddress = process.env.OJO_ADDRESS; const resolveWindow = Number(process.env.RESOLVE_WINDOW); const assetLimit = Number(process.env.ASSET_LIMIT); @@ -20,30 +18,44 @@ async function main() { } const mainnet = process.env.MAINNET as string - let evmChains = testnet_chains.map((chain) => ({ ...chain })); + let chains = testnet_chains.map((chain) => ({ ...chain })); if (mainnet === "TRUE") { - evmChains = mainnet_chains.map((chain) => ({ ...chain })); + chains = mainnet_chains.map((chain) => ({ ...chain })); } - const key = Number(process.env.PRIVATE_KEY); - - for (const chain of evmChains) { - const provider = new ethers.JsonRpcProvider(chain.rpc) - const wallet = new Wallet(privateKey, provider); - const balance = await provider.getBalance(wallet.address) - console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); - - const deployedContract = await deployCreate2InitUpgradable( - create2DeployerAddress, - wallet, - Ojo, - OjoProxy, - [chain.gateway, axelarGasReceiverAddress], - ethers.AbiCoder.defaultAbiCoder().encode(["string", "string", "uint256", "uint16"],[ojoChain, ojoAddress, resolveWindow, assetLimit]), - key - ); - - console.log(`${chain.name}, address: ${await deployedContract.getAddress()}`); + const key = Number(process.env.CONTRACT_KEY); + + for (const chain of chains) { + if (evmChains.includes(chain.name)) { + const provider = new ethers.JsonRpcProvider(chain.rpc) + const wallet = new Wallet(privateKey, provider); + const balance = await provider.getBalance(wallet.address) + console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); + + const feeData = await provider.getFeeData(); + const gasPrice = feeData.maxFeePerGas ?? feeData.gasPrice; + if (!gasPrice) { + throw new Error('Unable to retrieve gas price'); + } + const estimatedGas = await estimateDeploymentGas(wallet, Ojo, [chain.gateway, chain.gasReceiver]); + const deploymentCost = estimatedGas * gasPrice; + + if (balance < deploymentCost) { + throw new Error(`Insufficient funds in wallet for deploying on ${chain.name}, deploymentCost: ${ethers.formatEther(deploymentCost.toString())} ${chain.tokenSymbol}`); + } + + const deployedContract = await deployCreate2InitUpgradable( + chain.create2Deployer, + wallet, + Ojo, + OjoProxy, + [chain.gateway, chain.gasReceiver], + ethers.AbiCoder.defaultAbiCoder().encode(["string", "string", "uint256", "uint16"],[ojoChain, chain.ojoContract, resolveWindow, assetLimit]), + key + ); + + console.log(`${chain.name}, address: ${await deployedContract.getAddress()}`); + } } } diff --git a/scripts/deployPriceFeedImplementation.ts b/scripts/deployPriceFeedImplementation.ts index 491f4a1..0258769 100644 --- a/scripts/deployPriceFeedImplementation.ts +++ b/scripts/deployPriceFeedImplementation.ts @@ -4,7 +4,7 @@ import testnet_chains from '../testnet_chains.json'; import mainnet_chains from '../mainnet_chains.json'; async function main() { - const ojoAddress = process.env.OJO_CONTRACT_ADDRESS; + const evmChains = JSON.parse(process.env.EVM_CHAINS!); const privateKey = process.env.PRIVATE_KEY; @@ -13,20 +13,22 @@ async function main() { } const mainnet = process.env.MAINNET as string - let evmChains = testnet_chains.map((chain) => ({ ...chain })); + let chains = testnet_chains.map((chain) => ({ ...chain })); if (mainnet === "TRUE") { - evmChains = mainnet_chains.map((chain) => ({ ...chain })); + chains = mainnet_chains.map((chain) => ({ ...chain })); } - for (const chain of evmChains) { - const provider = new ethers.JsonRpcProvider(chain.rpc) - const wallet = new Wallet(privateKey, provider); - const balance = await provider.getBalance(wallet.address) - console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); + for (const chain of chains) { + if (evmChains.includes(chain.name)) { + const provider = new ethers.JsonRpcProvider(chain.rpc) + const wallet = new Wallet(privateKey, provider); + const balance = await provider.getBalance(wallet.address) + console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); - const priceFeedFactory = new ethers.ContractFactory(PriceFeed.abi, PriceFeed.bytecode, wallet) - const priceFeed = await priceFeedFactory.deploy(ojoAddress) - console.log(`${chain.name}, address: ${await priceFeed.getAddress()}`); + const priceFeedFactory = new ethers.ContractFactory(PriceFeed.abi, PriceFeed.bytecode, wallet) + const priceFeed = await priceFeedFactory.deploy(chain.ojoContract) + console.log(`${chain.name}, address: ${await priceFeed.getAddress()}`); + } } } diff --git a/scripts/upgradeOjo.ts b/scripts/upgradeOjo.ts index b6696b1..9902d07 100644 --- a/scripts/upgradeOjo.ts +++ b/scripts/upgradeOjo.ts @@ -5,8 +5,7 @@ import mainnet_chains from '../mainnet_chains.json'; import { upgradeUpgradable } from './utils/upgradable'; async function main() { - const ojoProxyAddress = process.env.OJO_CONTRACT_ADDRESS; - const axelarGasReceiverAddress = process.env.AXELAR_GAS_RECEIVER_ADDRESS; + const evmChains = JSON.parse(process.env.EVM_CHAINS!); const privateKey = process.env.PRIVATE_KEY; @@ -15,25 +14,27 @@ async function main() { } const mainnet = process.env.MAINNET as string - let evmChains = testnet_chains.map((chain) => ({ ...chain })); + let chains = testnet_chains.map((chain) => ({ ...chain })); if (mainnet === "TRUE") { - evmChains = mainnet_chains.map((chain) => ({ ...chain })); + chains = mainnet_chains.map((chain) => ({ ...chain })); } - for (const chain of evmChains) { - const provider = new ethers.JsonRpcProvider(chain.rpc) - const wallet = new Wallet(privateKey, provider); - const balance = await provider.getBalance(wallet.address) - console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); - - const upgradeTx = await upgradeUpgradable( - ojoProxyAddress, - wallet, - Ojo, - [chain.gateway, axelarGasReceiverAddress] - ); - - console.log(`${chain.name}, upgrade tx: ${upgradeTx.hash}`); + for (const chain of chains) { + if (evmChains.includes(chain.name)) { + const provider = new ethers.JsonRpcProvider(chain.rpc) + const wallet = new Wallet(privateKey, provider); + const balance = await provider.getBalance(wallet.address) + console.log(`${chain.name} wallet balance: ${ethers.formatEther(balance.toString())} ${chain.tokenSymbol}`); + + const upgradeTx = await upgradeUpgradable( + chain.ojoContract, + wallet, + Ojo, + [chain.gateway, chain.gasReceiver] + ); + + console.log(`${chain.name}, upgrade tx: ${upgradeTx.hash}`); + } } } diff --git a/scripts/utils/upgradable.ts b/scripts/utils/upgradable.ts index a405f95..e5dc063 100644 --- a/scripts/utils/upgradable.ts +++ b/scripts/utils/upgradable.ts @@ -27,6 +27,17 @@ export async function deployCreate2InitUpgradable( return new ethers.Contract(await proxy.getAddress(), implementationJson.abi, wallet); } +export async function estimateDeploymentGas( + wallet: ethers.Wallet, + implementationJson: { abi: ethers.Interface | ethers.InterfaceAbi; bytecode: ethers.BytesLike | { object: string; }; }, + implementationConstructorArgs: any +) { + const implementationFactory = new ethers.ContractFactory(implementationJson.abi, implementationJson.bytecode, wallet); + const deployTransaction = await implementationFactory.getDeployTransaction(...implementationConstructorArgs); + const estimatedGas = await wallet.estimateGas(deployTransaction); + return estimatedGas; +} + export async function upgradeUpgradable( proxyAddress: any, wallet: ethers.Wallet, diff --git a/testnet_chains.json b/testnet_chains.json index 8e3df94..4e2b088 100644 --- a/testnet_chains.json +++ b/testnet_chains.json @@ -4,132 +4,227 @@ "chainId": 5, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Ethereum Sepolia", "chainId": 11155111, "rpc": "https://1rpc.io/sepolia", "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "BNB Chain", "chainId": 97, "gateway": "0x4D147dCb984e6affEEC47e44293DA442580A3Ec0", "rpc": "https://data-seed-prebsc-1-s1.bnbchain.org:8545", - "tokenSymbol": "tBNB" + "tokenSymbol": "tBNB", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Polygon Mumbai", "chainId": 80001, "gateway": "0xBF62ef1486468a6bd26Dd669C06db43dEd5B849B", "rpc": "https://polygon-mumbai.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", - "tokenSymbol": "MATIC" + "tokenSymbol": "MATIC", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Polygon zkEVM", "chainId": 1442, "gateway": "0x999117D44220F33e0441fbAb2A5aDB8FF485c54D", "rpc": "https://rpc.public.zkevm-test.net", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Avalanche Fuji C-Chain", "chainId": 43113, "rpc": "https://api.avax-test.network/ext/bc/C/rpc", "gateway": "0xC249632c2D40b9001FE907806902f63038B737Ab", - "tokenSymbol": "AVAX" + "tokenSymbol": "AVAX", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Fantom", "chainId": 4002, "gateway": "0x97837985Ec0494E7b9C71f5D3f9250188477ae14", "rpc": "https://rpc.testnet.fantom.network", - "tokenSymbol": "FTM" + "tokenSymbol": "FTM", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Moonbase", "chainId": 1287, "rpc": "https://rpc.api.moonbase.moonbeam.network", "gateway": "0x5769D84DD62a6fD969856c75c7D321b84d455929", - "tokenSymbol": "DEV" + "tokenSymbol": "DEV", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Arbitrum Goerli", "chainId": 421613, "rpc": "https://arbitrum-goerli.publicnode.com", "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", - "tokenSymbol": "AGOR" + "tokenSymbol": "AGOR", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Arbitrum Sepolia", "chainId": 421614, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://arbitrum-sepolia.blockpi.network/v1/rpc/public", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0x3DB6DF9EDfDcfE97D574Aa6f106C767051561Be2", + "cloneFactory": "0xab2c7cc090A45836fae04501e0454413ECA96611" }, { "name": "Optimism Goerli", "chainId": 420, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://optimism-goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Optimism Sepolia", "chainId": 11155420, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://sepolia.optimism.io", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0x48B10B538B7E5af4CbFd93B1C4d36668e8F6F644", + "cloneFactory": "0xe9c4145FCeDdc19bc9B788C5d16cF08AD70d3850" }, { "name": "Base Goerli", "chainId": 84531, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://goerli.base.org", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Base Sepolia", "chainId": 84532, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://base-sepolia-rpc.publicnode.com", - "tokenSymbol": "ETH" + "tokenSymbol": "ETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "0x09d43904C8ABd470df1B793df68904A9714558CF", + "cloneFactory": "0x02Ed15B70D4dE1209c3Dd5a75195CB3f3dDB8B07" }, { "name": "Mantle", "chainId": 5001, "rpc": "https://rpc.testnet.mantle.xyz", "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", - "tokenSymbol": "MNT" + "tokenSymbol": "MNT", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Alfajores", "chainId": 44787, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://alfajores-forno.celo-testnet.org", - "tokenSymbol": "CELO" + "tokenSymbol": "CELO", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Kava", "chainId": 2221, "rpc": "https://evm.testnet.kava.io", "gateway": "0xC8D18F85cB0Cee5C95eC29c69DeaF6cea972349c", - "tokenSymbol": "KAVA" + "tokenSymbol": "KAVA", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Filecoin Calibration", "chainId": 314159, "gateway": "0x999117D44220F33e0441fbAb2A5aDB8FF485c54D", "rpc": "https://rpc.ankr.com/filecoin_testnet", - "tokenSymbol": "FIL" + "tokenSymbol": "FIL", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" }, { "name": "Linea Goerli", "chainId": 59140, "gateway": "0xe432150cce91c13a887f7D836923d5597adD8E31", "rpc": "https://rpc.goerli.linea.build", - "tokenSymbol": "LineaETH" + "tokenSymbol": "LineaETH", + "gasReceiver": "0xbE406F0189A0B4cf3A05C286473D23791Dd44Cc6", + "ojoContract": "0x5BB3E85f91D08fe92a3D123EE35050b763D6E6A7", + "create2Deployer": "0x98b2920d53612483f91f12ed7754e51b4a77919e", + "priceFeedImplementation": "", + "cloneFactory": "" } ]