From 0e57dcd118ae3a07563782fd6b19cf1221803b82 Mon Sep 17 00:00:00 2001 From: livingrockrises <90545960+livingrockrises@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:27:19 +0400 Subject: [PATCH] refactor scripts --- scripts/1-deploy-token-paymaster.ts | 2 +- scripts/2-deploy-oracle-aggregator.ts | 123 ----- scripts/3-deploy-derived-price-feeds.ts | 7 - scripts/4-set-token-oracles.ts | 11 - ...r.ts => 8-deploy-sponsorship-paymaster.ts} | 0 scripts/deploy-arbitrum-goerli.ts | 474 ----------------- scripts/deploy-arbitrum-one-mainnet.ts | 484 ------------------ scripts/deploy-avalanche-mainnet.ts | 481 ----------------- scripts/deploy-avalanche-testnet.ts | 481 ----------------- scripts/deploy-base-goerli.ts | 481 ----------------- scripts/deploy-bnb-mainnet.ts | 484 ------------------ scripts/deploy-bnb-testnet.ts | 481 ----------------- scripts/deploy-eth-mainnet.ts | 478 ----------------- scripts/deploy-goerli.ts | 481 ----------------- scripts/deploy-moonbeam-mainnet.ts | 481 ----------------- scripts/deploy-mumbai.ts | 481 ----------------- scripts/deploy-optimism-goerli.ts | 481 ----------------- scripts/deploy-optimism-mainnet.ts | 481 ----------------- scripts/deploy-polygon-mainnet.ts | 484 ------------------ scripts/deploy-sepolia.ts | 481 ----------------- ...er.ts => deploy-token-paymaster-mumbai.ts} | 105 +++- .../token-paymaster/TokenPaymaster.t.sol | 1 - .../TokenPaymasterMumbai.t.sol | 1 - 23 files changed, 105 insertions(+), 7359 deletions(-) delete mode 100644 scripts/2-deploy-oracle-aggregator.ts delete mode 100644 scripts/3-deploy-derived-price-feeds.ts delete mode 100644 scripts/4-set-token-oracles.ts rename scripts/{8-deploy-verifying-paymaster.ts => 8-deploy-sponsorship-paymaster.ts} (100%) delete mode 100644 scripts/deploy-arbitrum-goerli.ts delete mode 100644 scripts/deploy-arbitrum-one-mainnet.ts delete mode 100644 scripts/deploy-avalanche-mainnet.ts delete mode 100644 scripts/deploy-avalanche-testnet.ts delete mode 100644 scripts/deploy-base-goerli.ts delete mode 100644 scripts/deploy-bnb-mainnet.ts delete mode 100644 scripts/deploy-bnb-testnet.ts delete mode 100644 scripts/deploy-eth-mainnet.ts delete mode 100644 scripts/deploy-goerli.ts delete mode 100644 scripts/deploy-moonbeam-mainnet.ts delete mode 100644 scripts/deploy-mumbai.ts delete mode 100644 scripts/deploy-optimism-goerli.ts delete mode 100644 scripts/deploy-optimism-mainnet.ts delete mode 100644 scripts/deploy-polygon-mainnet.ts delete mode 100644 scripts/deploy-sepolia.ts rename scripts/token-paymaster-v2/{deploy-token-paymaster.ts => deploy-token-paymaster-mumbai.ts} (56%) diff --git a/scripts/1-deploy-token-paymaster.ts b/scripts/1-deploy-token-paymaster.ts index 77db8bf..f606894 100644 --- a/scripts/1-deploy-token-paymaster.ts +++ b/scripts/1-deploy-token-paymaster.ts @@ -29,7 +29,7 @@ async function deployTokenPaymasterContract( ): Promise { try { const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) + ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER_V2) ); const BiconomyTokenPaymaster = await ethers.getContractFactory( diff --git a/scripts/2-deploy-oracle-aggregator.ts b/scripts/2-deploy-oracle-aggregator.ts deleted file mode 100644 index 1f0a83e..0000000 --- a/scripts/2-deploy-oracle-aggregator.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { ethers, run } from "hardhat"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - isContract, -} from "./utils"; -import { Deployer, Deployer__factory } from "../typechain-types"; - -const provider = ethers.provider; -const DEPLOYER_CONTRACT_ADDRESS = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - try { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - - if (!isOracleAggregatorDeployed) { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; - } catch (err) { - console.log(err); - } -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstance(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS, signer); - } -} - -async function main() { - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstance = await getPredeployedDeployerContractInstance(); - console.log("========================================="); - - // Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstance, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/3-deploy-derived-price-feeds.ts b/scripts/3-deploy-derived-price-feeds.ts deleted file mode 100644 index 5af3485..0000000 --- a/scripts/3-deploy-derived-price-feeds.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Should be able to specify array of symbols for which you need to run this script - -// Deploy price feeds using appropritae salts from config. Could be a way to fetch salt using the symbol. - -// If price feed is supposed to be derived then go ahead and deploy the derived feed - -// TODO: passing the array of symbols and chainId - based on chainId config file is fetched, only run on required symbols diff --git a/scripts/4-set-token-oracles.ts b/scripts/4-set-token-oracles.ts deleted file mode 100644 index 789e366..0000000 --- a/scripts/4-set-token-oracles.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Connect and return instance with given EOA signer and provided address - -// Should be able to specify array of symbols for which you need to run this script - -// Fetch price feed addresses and priceFeedFunction - -// Set token oracles using the current owner - -// Transfer ownership back to intended owner if ownership was transferred back to run the script - -// TODO: passing the array of symbols and chainId - based on chainId config file is fetched, only run on required symbols diff --git a/scripts/8-deploy-verifying-paymaster.ts b/scripts/8-deploy-sponsorship-paymaster.ts similarity index 100% rename from scripts/8-deploy-verifying-paymaster.ts rename to scripts/8-deploy-sponsorship-paymaster.ts diff --git a/scripts/deploy-arbitrum-goerli.ts b/scripts/deploy-arbitrum-goerli.ts deleted file mode 100644 index 922ecf3..0000000 --- a/scripts/deploy-arbitrum-goerli.ts +++ /dev/null @@ -1,474 +0,0 @@ -import { ethers, run } from "hardhat"; -import { arbGoerliConfigInfoProd } from "./configs"; -import { TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = arbGoerliConfigInfoProd; - -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-arbitrum-one-mainnet.ts b/scripts/deploy-arbitrum-one-mainnet.ts deleted file mode 100644 index bb14b04..0000000 --- a/scripts/deploy-arbitrum-one-mainnet.ts +++ /dev/null @@ -1,484 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { arbitrumOneConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = arbitrumOneConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(7000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(7000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(7000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-avalanche-mainnet.ts b/scripts/deploy-avalanche-mainnet.ts deleted file mode 100644 index b3c5850..0000000 --- a/scripts/deploy-avalanche-mainnet.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { avalancheMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = avalancheMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-avalanche-testnet.ts b/scripts/deploy-avalanche-testnet.ts deleted file mode 100644 index e75ae03..0000000 --- a/scripts/deploy-avalanche-testnet.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { avalancheFujiConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = avalancheFujiConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-base-goerli.ts b/scripts/deploy-base-goerli.ts deleted file mode 100644 index b789057..0000000 --- a/scripts/deploy-base-goerli.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { baseGoerliConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = baseGoerliConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-bnb-mainnet.ts b/scripts/deploy-bnb-mainnet.ts deleted file mode 100644 index 97b255c..0000000 --- a/scripts/deploy-bnb-mainnet.ts +++ /dev/null @@ -1,484 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { bnbMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = bnbMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-bnb-testnet.ts b/scripts/deploy-bnb-testnet.ts deleted file mode 100644 index 86d1b8d..0000000 --- a/scripts/deploy-bnb-testnet.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { bnbTestnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = bnbTestnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-eth-mainnet.ts b/scripts/deploy-eth-mainnet.ts deleted file mode 100644 index f88c948..0000000 --- a/scripts/deploy-eth-mainnet.ts +++ /dev/null @@ -1,478 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { ethMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = ethMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(7000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - // const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - // console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(7000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(7000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - const derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - // derivedPriceFeedAddress = await deployDerivedPriceFeed(deployerInstanceDEV, nativeOracleAddress, tokenOracleAddress, description, feedSalt); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - // await delay(7000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-goerli.ts b/scripts/deploy-goerli.ts deleted file mode 100644 index 4663fb8..0000000 --- a/scripts/deploy-goerli.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { goerliConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = goerliConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-moonbeam-mainnet.ts b/scripts/deploy-moonbeam-mainnet.ts deleted file mode 100644 index 7b2ec76..0000000 --- a/scripts/deploy-moonbeam-mainnet.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { moonbeamMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = moonbeamMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-mumbai.ts b/scripts/deploy-mumbai.ts deleted file mode 100644 index 9a144eb..0000000 --- a/scripts/deploy-mumbai.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { mumbaiConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = mumbaiConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_PROD || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_PROD || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-optimism-goerli.ts b/scripts/deploy-optimism-goerli.ts deleted file mode 100644 index 36abd9a..0000000 --- a/scripts/deploy-optimism-goerli.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { optimismGoerliConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = optimismGoerliConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-optimism-mainnet.ts b/scripts/deploy-optimism-mainnet.ts deleted file mode 100644 index 7672ad2..0000000 --- a/scripts/deploy-optimism-mainnet.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { optimismMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = optimismMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(10000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(10000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(10000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-polygon-mainnet.ts b/scripts/deploy-polygon-mainnet.ts deleted file mode 100644 index 93b7d45..0000000 --- a/scripts/deploy-polygon-mainnet.ts +++ /dev/null @@ -1,484 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { polygonMainnetConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = polygonMainnetConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(4000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(4000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(4000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(4000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(4000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - console.log( - `derived price feed address for token ${symbol} is ${derivedPriceFeedAddress}` - ); - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(4000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/deploy-sepolia.ts b/scripts/deploy-sepolia.ts deleted file mode 100644 index 6fb53c2..0000000 --- a/scripts/deploy-sepolia.ts +++ /dev/null @@ -1,481 +0,0 @@ -import { ethers, run, network } from "hardhat"; -import { sepoliaConfigInfoProd } from "./configs"; -import { Token, TokenConfig } from "./utils/Types"; -import { - deployContract, - DEPLOYMENT_SALTS, - encodeParam, - getDeployerInstance, - isContract, -} from "./utils"; -import { - BiconomyTokenPaymaster, - BiconomyTokenPaymaster__factory, - ChainlinkOracleAggregator, - ChainlinkOracleAggregator__factory, - Deployer, - Deployer__factory, -} from "../typechain-types"; - -const tokenConfig: TokenConfig = sepoliaConfigInfoProd; - -const provider = ethers.provider; -const entryPointAddress = - process.env.ENTRY_POINT_ADDRESS || - "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"; -const owner = process.env.PAYMASTER_OWNER_ADDRESS_DEV || ""; -const verifyingSigner = process.env.PAYMASTER_SIGNER_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_DEV = - process.env.DEPLOYER_CONTRACT_ADDRESS_DEV || ""; -const DEPLOYER_CONTRACT_ADDRESS_PROD = - process.env.DEPLOYER_CONTRACT_ADDRESS_PROD || ""; - -function delay(ms: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); -} - -async function deployChainlinkOracleAggregatorContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const ORACLE_AGGREGATOR_SALT = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.ORACLE_AGGREGATOR) - ); - - const OracleAggregator = await ethers.getContractFactory( - "ChainlinkOracleAggregator" - ); - const oracleAggregatorBytecode = `${OracleAggregator.bytecode}${encodeParam( - "address", - earlyOwnerAddress - ).slice(2)}`; - const oracleAggregatorComputedAddr = await deployerInstance.addressOf( - ORACLE_AGGREGATOR_SALT - ); - console.log( - "Chainlink Oracle Aggregator Computed Address: ", - oracleAggregatorComputedAddr - ); - - const isOracleAggregatorDeployed = await isContract( - oracleAggregatorComputedAddr, - provider - ); // true (deployed on-chain) - if (!isOracleAggregatorDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.ORACLE_AGGREGATOR, - oracleAggregatorComputedAddr, - ORACLE_AGGREGATOR_SALT, - oracleAggregatorBytecode, - deployerInstance - ); - await delay(10000); - } catch (err) { - console.log("issue with the deployment"); - console.log(err); - return ethers.constants.AddressZero; - } - - try { - await run(`verify:verify`, { - address: oracleAggregatorComputedAddr, - constructorArguments: [earlyOwnerAddress], - }); - } catch (err) { - console.log("issue with the verification ", oracleAggregatorComputedAddr); - - return oracleAggregatorComputedAddr; - } - } else { - console.log( - "Chainlink Oracle Aggregator is already deployed with address ", - oracleAggregatorComputedAddr - ); - } - return oracleAggregatorComputedAddr; -} - -async function deployTokenPaymasterContract( - deployerInstance: Deployer, - earlyOwnerAddress: string -): Promise { - const salt = ethers.utils.keccak256( - ethers.utils.toUtf8Bytes(DEPLOYMENT_SALTS.TOKEN_PAYMASTER) - ); - - const BiconomyTokenPaymaster = await ethers.getContractFactory( - "BiconomyTokenPaymaster" - ); - const tokenPaymasterBytecode = `${ - BiconomyTokenPaymaster.bytecode - }${encodeParam("address", earlyOwnerAddress).slice(2)}${encodeParam( - "address", - entryPointAddress - ).slice(2)}${encodeParam("address", verifyingSigner).slice(2)}`; - - const tokenPaymasterComputedAddr = await deployerInstance.addressOf(salt); - console.log("Token paymaster Computed Address: ", tokenPaymasterComputedAddr); - const isContractDeployed = await isContract( - tokenPaymasterComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - DEPLOYMENT_SALTS.TOKEN_PAYMASTER, - tokenPaymasterComputedAddr, - salt, - tokenPaymasterBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: tokenPaymasterComputedAddr, - constructorArguments: [ - earlyOwnerAddress, - entryPointAddress, - verifyingSigner, - ], - }); - } catch (err) { - console.log("issue with the verification ", tokenPaymasterComputedAddr); - - return tokenPaymasterComputedAddr; - } - } else { - console.log( - "Token Paymaster is Already deployed with address ", - tokenPaymasterComputedAddr - ); - } - return tokenPaymasterComputedAddr; -} - -async function deployDerivedPriceFeed( - deployerInstance: Deployer, - nativeOracleAddress: string, - tokenOracleAddress: string, - description: string, - feedSalt: string -): Promise { - const salt = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(feedSalt)); - - const DerivedPriceFeed = await ethers.getContractFactory("DerivedPriceFeed"); - - const derivedPriceFeedBytecode = `${ - DerivedPriceFeed.bytecode - }${ethers.utils.defaultAbiCoder - .encode( - ["address", "address", "string"], - [nativeOracleAddress, tokenOracleAddress, description] - ) - .slice(2)}`; - - const derivedPriceFeedBComputedAddr = await deployerInstance.addressOf(salt); - console.log( - "Derived Price Feed Computed Address: ", - derivedPriceFeedBComputedAddr - ); - const isContractDeployed = await isContract( - derivedPriceFeedBComputedAddr, - provider - ); - if (!isContractDeployed) { - try { - await deployContract( - feedSalt, - derivedPriceFeedBComputedAddr, - salt, - derivedPriceFeedBytecode, - deployerInstance - ); - await delay(5000); - } catch (err) { - console.log(err); - console.log("issue with the deployment"); - return ethers.constants.AddressZero; - } - try { - await run(`verify:verify`, { - address: derivedPriceFeedBComputedAddr, - constructorArguments: [ - nativeOracleAddress, - tokenOracleAddress, - description, - ], - }); - } catch (err) { - console.log( - "issue with the verification ", - derivedPriceFeedBComputedAddr - ); - - return derivedPriceFeedBComputedAddr; - } - } else { - console.log( - "Derived Price Feed is Already deployed with address ", - derivedPriceFeedBComputedAddr - ); - } - return derivedPriceFeedBComputedAddr; -} - -async function setTokenOracle( - oracleAggregatorInstance: ChainlinkOracleAggregator, - tokenAddress: string, - priceFeedAddress: string, - priceFeedDecimals: number, - priceFeedFunctionName: string -) { - const PriceFeedContract = await ethers.getContractAt( - "FeedInterface", - priceFeedAddress - ); - - // Find the function ABI based on the provided function name - // @ts-ignore - const functionAbi = - PriceFeedContract.interface.functions[ - priceFeedFunctionName as keyof typeof PriceFeedContract.functions - ]; - - // Generate the function data based on the function ABI - const functionData = - PriceFeedContract.interface.encodeFunctionData(functionAbi); - - const tx = await oracleAggregatorInstance.setTokenOracle( - tokenAddress, - priceFeedAddress, - priceFeedDecimals, - functionData, - true - ); - const receipt = await tx.wait(); - console.log( - `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` - ); -} - -/* - * This function is added to support the flow with pre-deploying the deployer contract - * using the `deployer-contract.deploy.ts` script. - */ -async function getPredeployedDeployerContractInstanceDEV(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_DEV); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_DEV - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_DEV, signer); - } -} - -async function getPredeployedDeployerContractInstancePROD(): Promise { - const code = await provider.getCode(DEPLOYER_CONTRACT_ADDRESS_PROD); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Deployer not deployed on chain ${chainId}, deploy it with deployer-contract.deploy.ts script before using this script.` - ); - throw new Error("Deployer not deployed"); - } else { - console.log( - "Deploying with EOA %s through Deployer Contract %s", - signer.address, - DEPLOYER_CONTRACT_ADDRESS_PROD - ); - return Deployer__factory.connect(DEPLOYER_CONTRACT_ADDRESS_PROD, signer); - } -} - -async function getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress: string -): Promise { - const code = await provider.getCode(oracleAggregatorAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `ChainlinkOracleAggregator not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("ChainlinkOracleAggregator not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - oracleAggregatorAddress - ); - return ChainlinkOracleAggregator__factory.connect( - oracleAggregatorAddress, - signer - ); - } -} - -async function getTokenPaymasterContractInstance( - tokenPaymasterAddress: string -): Promise { - const code = await provider.getCode(tokenPaymasterAddress); - const chainId = (await provider.getNetwork()).chainId; - const [signer] = await ethers.getSigners(); - - if (code === "0x") { - console.log( - `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` - ); - throw new Error("Biconomy Token Paymaster not deployed"); - } else { - console.log( - "Returning instance connected with EOA %s and address %s", - signer.address, - tokenPaymasterAddress - ); - return BiconomyTokenPaymaster__factory.connect( - tokenPaymasterAddress, - signer - ); - } -} - -async function main() { - let tx, receipt; - const provider = ethers.provider; - - const accounts = await ethers.getSigners(); - const earlyOwner = await accounts[0].getAddress(); - - const deployerInstanceDEV = await getPredeployedDeployerContractInstanceDEV(); - console.log("========================================="); - - const deployerInstancePROD = - await getPredeployedDeployerContractInstancePROD(); - console.log("========================================="); - - // 1. Deploy Chainlink Oracle Aggregator - // @note: owner is kept the deployer because we need to perform more actions on this contract using owner as part of other scripts - // @note: ownership should be transferred at the end - const oracleAggregatorAddress = await deployChainlinkOracleAggregatorContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================oracleAggregatorAddress=======================", - oracleAggregatorAddress - ); - await delay(5000); - - // 2. Deploy Token paymaster - const tokenPaymasterAddress = await deployTokenPaymasterContract( - deployerInstancePROD, - earlyOwner - ); - console.log( - "==================tokenPaymasterAddress=======================", - tokenPaymasterAddress - ); - await delay(5000); - - let oracleAggregatorInstance; - if (oracleAggregatorAddress) { - oracleAggregatorInstance = - await getChainlinkOracleAggregatorContractInstance( - oracleAggregatorAddress - ); - console.log( - "==================oracleAggregatorInstance=======================" - ); - } - - // 3a. Deploy the derived price feeds for all chainlink supported ERC20 tokens - for (const token of tokenConfig.tokens) { - const { - symbol, - address, - nativeOracleAddress, - tokenOracleAddress, - priceFeedAddress, - description, - priceFeedFunction, - feedSalt, - derivedFeed, - } = token; - let derivedPriceFeedAddress = priceFeedAddress; - - if (derivedPriceFeedAddress == "") { - derivedPriceFeedAddress = await deployDerivedPriceFeed( - deployerInstanceDEV, - nativeOracleAddress, - tokenOracleAddress, - description, - feedSalt - ); - console.log( - `==================${symbol} PriceFeedAddress=======================`, - derivedPriceFeedAddress - ); - await delay(5000); - } - - // Continue with other steps like setting token oracle, transferring ownership, etc. - // Use the derivedPriceFeedAddress and other token-specific information as needed - // ... - - // 4. Set token oracle on oracle aggregator - if (oracleAggregatorInstance) { - let feedAddress = derivedPriceFeedAddress; - if (priceFeedFunction == "latestAnswer()" || derivedFeed == false) { - feedAddress = priceFeedAddress; - } - // TODO - // This should not hardcode tokenOracleDeciamls to 18 - // It works in case of derived price feeds and chainlink feeds which are in the erc20 / native base and quote format. - await setTokenOracle( - oracleAggregatorInstance, - address, - feedAddress, - 18, - priceFeedFunction - ); - } - } - - if (tokenPaymasterAddress) { - // 5b. transfer ownership of token paymaster to the owner - const tokenPaymasterInstance = await getTokenPaymasterContractInstance( - tokenPaymasterAddress - ); - console.log( - "==================tokenPaymasterInstance=======================" - ); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/token-paymaster-v2/deploy-token-paymaster.ts b/scripts/token-paymaster-v2/deploy-token-paymaster-mumbai.ts similarity index 56% rename from scripts/token-paymaster-v2/deploy-token-paymaster.ts rename to scripts/token-paymaster-v2/deploy-token-paymaster-mumbai.ts index 60e5661..0edda51 100644 --- a/scripts/token-paymaster-v2/deploy-token-paymaster.ts +++ b/scripts/token-paymaster-v2/deploy-token-paymaster-mumbai.ts @@ -5,7 +5,17 @@ import { encodeParam, isContract, } from "../utils"; -import { Deployer, Deployer__factory } from "../../typechain-types"; +import { + BiconomyTokenPaymaster, + BiconomyTokenPaymaster__factory, + Deployer, + Deployer__factory, + ERC20__factory, +} from "../../typechain-types"; +import { mumbaiConfigInfoProd } from "../configs"; +import { TokenConfig } from "../utils/Types"; + +const tokenConfig: TokenConfig = mumbaiConfigInfoProd; const provider = ethers.provider; const entryPointAddress = @@ -104,6 +114,58 @@ async function getPredeployedDeployerContractInstance(): Promise { } } +async function setTokenOracle( + tokenPaymasterInstance: BiconomyTokenPaymaster, + tokenAddress: string, + tokenDecimals: number, + tokenOracle: string, + nativeOracle: string, + isDerivedFeed: boolean +) { + // Connect as the owner of the token paymaster + const tx = await tokenPaymasterInstance.setTokenOracle( + tokenAddress, + tokenDecimals, + tokenOracle, + nativeOracle, + isDerivedFeed + ); + const receipt = await tx.wait(); + console.log( + `Oracle set for ${tokenAddress} with tx hash ${receipt.transactionHash}` + ); +} + +async function getTokenPaymasterContractInstance( + tokenPaymasterAddress: string +): Promise { + const code = await provider.getCode(tokenPaymasterAddress); + const chainId = (await provider.getNetwork()).chainId; + const [signer] = await ethers.getSigners(); + + if (code === "0x") { + console.log( + `Biconomy Token Paymaster not deployed on chain ${chainId}, It should have been deployed as part of this script.` + ); + throw new Error("Biconomy Token Paymaster not deployed"); + } else { + console.log( + "Returning instance connected with EOA %s and address %s", + signer.address, + tokenPaymasterAddress + ); + return BiconomyTokenPaymaster__factory.connect( + tokenPaymasterAddress, + signer + ); + } +} + +async function getERC20TokenInstance(tokenAddress: string) { + const [signer] = await ethers.getSigners(); + return ERC20__factory.connect(tokenAddress, signer); +} + async function main() { const accounts = await ethers.getSigners(); const earlyOwner = await accounts[0].getAddress(); @@ -120,6 +182,47 @@ async function main() { "==================tokenPaymasterAddress=======================", tokenPaymasterAddress ); + + let tokenPaymasterInstance; + if (tokenPaymasterAddress) { + tokenPaymasterInstance = await getTokenPaymasterContractInstance( + tokenPaymasterAddress + ); + console.log( + "==================tokenPaymasterInstance=======================" + ); + } + + for (const token of tokenConfig.tokens) { + // Note: In the config priceFeedAddress becomes the tokenOracleAddress + const { + symbol, + address, + nativeOracleAddress, + tokenOracleAddress, + priceFeedAddress, + derivedFeed, + } = token; + + let tokenDecimals = 18; + + if (address) { + const tokenInstance = await getERC20TokenInstance(address); + tokenDecimals = await tokenInstance.decimals(); + } else { + throw new Error("token address can not be undefined"); + } + if (tokenPaymasterInstance) { + await setTokenOracle( + tokenPaymasterInstance, + address, + tokenDecimals, + nativeOracleAddress, + tokenOracleAddress, + derivedFeed + ); + } + } } main().catch((error) => { diff --git a/test/foundry/token-paymaster/TokenPaymaster.t.sol b/test/foundry/token-paymaster/TokenPaymaster.t.sol index 6ae82e1..cf7670b 100644 --- a/test/foundry/token-paymaster/TokenPaymaster.t.sol +++ b/test/foundry/token-paymaster/TokenPaymaster.t.sol @@ -166,7 +166,6 @@ contract TokenPaymasterTest is SATestBase { entryPoint.handleOps(arraifyOps(op), dan.addr); - // todo // review fails to validate updated balances console2.log("paymaster balance after ", usdc.balanceOf(address(_btpm))); assertNotEq(usdc.balanceOf(address(sa)), 100e6); } diff --git a/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol b/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol index e50a804..e3fb4d4 100644 --- a/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol +++ b/test/foundry/token-paymaster/TokenPaymasterMumbai.t.sol @@ -165,7 +165,6 @@ contract TokenPaymasterMumbaiTest is SATestBase { entryPoint.handleOps(arraifyOps(op), dan.addr); - // todo // review fails to validate updated balances console2.log("paymaster balance after ", usdc.balanceOf(address(_btpm))); assertNotEq(usdc.balanceOf(address(sa)), 100e6); }