diff --git a/package.json b/package.json index 6fac9b33..2e73b9a1 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "deploy": "node scripts/deployConnectorsFromCmd.js", "test:runner": "hardhat run scripts/tests/run-tests.ts", "typechain": "hardhat typechain", - "compile": "hardhat compile" + "compile": "hardhat compile", + "deploy:runner": "hardhat run scripts/deployment/deployConnectorsFromCmd.ts" }, "repository": { "type": "git", diff --git a/scripts/constant/deployAddress.ts b/scripts/constant/deployAddress.ts new file mode 100644 index 00000000..e69de29b diff --git a/scripts/deployment/connectors.ts b/scripts/deployment/connectors.ts new file mode 100644 index 00000000..04cec719 --- /dev/null +++ b/scripts/deployment/connectors.ts @@ -0,0 +1,53 @@ +export const connectMapping: Record = { + mainnet: { + "1INCH-A": "ConnectV2OneInch", + "1INCH-B": "ConnectV2OneProto", + "AAVE-V1-A": "ConnectV2AaveV1", + "AAVE-V2-A": "ConnectV2AaveV2", + "AUTHORITY-A": "ConnectV2Auth", + "BASIC-A": "ConnectV2Basic", + "COMP-A": "ConnectV2COMP", + "COMPOUND-A": "ConnectV2Compound", + "DYDX-A": "ConnectV2Dydx", + "FEE-A": "ConnectV2Fee", + "GELATO-A": "ConnectV2Gelato", + "MAKERDAO-A": "ConnectV2Maker", + "UNISWAP-A": "ConnectV2UniswapV2", + }, + polygon: { + "QUICKSWAP-A": "ConnectV2Paraswap", + "UniswapV3-v1": "ConnectV2UniswapV3Polygon", + "Uniswap-V3-Staker-v1.1": "ConnectV2UniswapV3StakerPolygon", + "Paraswap-v5": "ConnectV2ParaswapV5Polygon", + "1INCH-V4": "ConnectV2OneInchV4Polygon", + }, + avalanche: { + "ZEROEX-A": "ConnectV2ZeroExAvalanche", + }, +}; + +export const connectors: Record> = { + mainnet: [ + "1INCH-A", + "1INCH-B", + "AAVE-V1-A", + "AAVE-V2-A", + "AUTHORITY-A", + "BASIC-A", + "COMP-A", + "COMPOUND-A", + "DYDX-A", + "FEE-A", + "GELATO-A", + "MAKERDAO-A", + "UNISWAP-A", + ], + polygon: [ + "QUICKSWAP-A", + "UniswapV3-v1", + "Uniswap-V3-Staker-v1.1", + "Paraswap-v5", + "1INCH-V4", + ], + avalanche: ["ZEROEX-A"], +}; diff --git a/scripts/deployment/deploy.ts b/scripts/deployment/deploy.ts index 09159d7a..233c72e5 100644 --- a/scripts/deployment/deploy.ts +++ b/scripts/deployment/deploy.ts @@ -1,35 +1,17 @@ import { ethers } from "hardhat"; import { deployConnector } from "./deployConnector"; +import { connectMapping } from "./connectors"; async function main() { - const accounts = await ethers.getSigners(); + if (process.env.connectorName) { + await deployConnector(); + } else { + const addressMapping: Record = {}; - const connectMapping: Record = { - "1INCH-A": "ConnectV2OneInch", - "1INCH-B": "ConnectV2OneProto", - "AAVE-V1-A": "ConnectV2AaveV1", - "AAVE-V2-A": "ConnectV2AaveV2", - "AUTHORITY-A": "ConnectV2Auth", - "BASIC-A": "ConnectV2Basic", - "COMP-A": "ConnectV2COMP", - "COMPOUND-A": "ConnectV2Compound", - "DYDX-A": "ConnectV2Dydx", - "FEE-A": "ConnectV2Fee", - "GELATO-A": "ConnectV2Gelato", - "MAKERDAO-A": "ConnectV2Maker", - "UNISWAP-A": "ConnectV2UniswapV2", - "QUICKSWAP-A": "ConnectV2QuickswapPolygon", - "UniswapV3-v1" : "ConnectV2UniswapV3Polygon", - "Uniswap-V3-Staker-v1.1" : "ConnectV2UniswapV3StakerPolygon", - "Paraswap-v5" : "ConnectV2ParaswapV5Polygon", - "1INCH-V4" : "ConnectV2OneInchV4Polygon", - "ZEROEX-A": "ConnectV2ZeroExAvalanche", - }; - - const addressMapping: Record = {}; - - for (const key in connectMapping) { - addressMapping[key] = await deployConnector(connectMapping[key]); + for (const key in connectMapping) { + addressMapping[key] = await deployConnector(connectMapping[key]); + } + console.log(addressMapping); } } diff --git a/scripts/deployment/deployConnector.ts b/scripts/deployment/deployConnector.ts index 8f3bcd28..cbcca6b1 100644 --- a/scripts/deployment/deployConnector.ts +++ b/scripts/deployment/deployConnector.ts @@ -1,21 +1,36 @@ import hre, { ethers } from "hardhat"; -export const deployConnector = async (connectorName: string) => { +import { execScript } from "../tests/command"; +export const deployConnector = async (connectorName?: string) => { + connectorName = String(process.env.connectorName) ?? connectorName; const Connector = await ethers.getContractFactory(connectorName); const connector = await Connector.deploy(); await connector.deployed(); console.log(`${connectorName} Deployed: ${connector.address}`); - try { - await hre.run("verify:verify", { - address: connector.address, - constructorArguments: [], - }); - } catch (error) { - console.log(`Failed to verify: ${connectorName}@${connector.address}`); - console.log(error); - console.log(); + const chain = String(hre.network.name); + if (chain !== "hardhat") { + try { + await execScript({ + cmd: "npx", + args: [ + "hardhat", + "verify", + "--network", + `${chain}`, + `${connector.address}`, + ], + env: { + networkType: chain, + }, + }); + } catch (error) { + console.log(`Failed to verify: ${connectorName}@${connector.address}`); + console.log(error); + console.log(); + } } + return connector.address; }; diff --git a/scripts/deployment/deployConnectorsFromCmd.ts b/scripts/deployment/deployConnectorsFromCmd.ts index f3c24f45..60fb880a 100644 --- a/scripts/deployment/deployConnectorsFromCmd.ts +++ b/scripts/deployment/deployConnectorsFromCmd.ts @@ -1,108 +1,95 @@ -import fs from "fs"; -import hre from "hardhat" -const { ethers, network, config } = hre; +import { execScript } from "../tests/command"; +import inquirer from "inquirer"; +import { connectors, connectMapping } from "./connectors"; +import { join } from "path"; -let args = process.argv; -args = args.splice(2, args.length); -let params: Record = {}; +let start: number, end: number, runchain: string; -for (let i = 0; i < args.length; i += 2) { - if (args[i][0] !== "-" || args[i][1] !== "-") { - console.log("Please add '--' for the key"); - process.exit(-1); - } - let key = args[i].slice(2, args[i].length); - params[key] = args[i + 1]; -} +// async function connectorSelect(chain: string) { +// let { connector } = await inquirer.prompt([ +// { +// name: "connector", +// message: "Which connector do you want to deploy?", +// type: "list", +// choices: connectors[chain], +// }, +// ]); -if (!params.hasOwnProperty("connector")) { - console.error("Should include connector params"); - process.exit(-1); -} +// return connector; +// } -if (!params.hasOwnProperty("network")) { - console.error("Should include network params"); - process.exit(-1); -} +async function deployRunner() { + let { chain } = await inquirer.prompt([ + { + name: "chain", + message: "What chain do you want to deploy on?", + type: "list", + choices: ["mainnet", "polygon", "avalanche", "arbitrum"], + }, + ]); -if (!params.hasOwnProperty("gasPrice")) { - console.error("Should include gas params"); - process.exit(-1); -} + // let connector = await connectorSelect(chain); -let privateKey = String(process.env.PRIVATE_KEY); -let provider = new ethers.providers.JsonRpcProvider( - config.networks[params["network"]].url -); -let wallet = new ethers.Wallet(privateKey, provider); + // let { choice } = await inquirer.prompt([ + // { + // name: "choice", + // message: "Do you wanna select again?", + // type: "list", + // choices: ["yes", "no"], + // }, + // ]); -network.name = params["networkName"]; -network.config = config.networks[params["networkName"]]; -network.provider = provider; -let contracts: (string | string[])[] = []; + // if (choice === "yes") { + // connector = await connectorSelect(chain); + // } + // connector = connectMapping[chain][connector]; -const parseFile = async (filePath: fs.PathOrFileDescriptor) => { - const data = fs.readFileSync(filePath, "utf-8"); - let parsedData = data.split("contract "); - parsedData = parsedData[parsedData.length - 1].split(" "); - return parsedData[0]; -}; + let { connector } = await inquirer.prompt([ + { + name: "connector", + message: "Enter the connector contract name? (ex: ConnectV2Paraswap)", + type: "input", + }, + ]); -const parseDir = async (root: string | any[], basePath: string, addPath: string) => { - for (let i = 0; i < root.length; i++) { - addPath = "/" + root[i]; - const dir = fs.readdirSync(basePath + addPath); - if (dir.indexOf("main.sol") !== -1) { - const fileData = await parseFile(basePath + addPath + "/main.sol"); - contracts.push(fileData); - } else { - await parseDir(dir, basePath + addPath, ""); - } - } -}; + let { choice } = await inquirer.prompt([ + { + name: "choice", + message: "Do you wanna try deploy on hardhat first?", + type: "list", + choices: ["yes", "no"], + }, + ]); -const main = async () => { - const mainnet = fs.readdirSync("./contracts/mainnet/connectors/"); - const polygon = fs.readdirSync("./contracts/polygon/connectors/"); - let basePathMainnet = "./contracts/mainnet/connectors/"; - let basePathPolygon = "./contracts/polygon/connectors/"; + runchain = choice === "yes" ? "hardhat" : chain; - const connectorName = params["connector"]; + console.log( + `Deploying ${connector} on ${runchain}, press (ctrl + c) to stop` + ); - await parseDir(mainnet, basePathMainnet, ""); - await parseDir(polygon, basePathPolygon, ""); - - if (contracts.indexOf(connectorName) === -1) { - throw new Error( - "can not find the connector!\n" + - "supported connector names are:\n" + - contracts.join("\n") - ); - } - - const Connector = await ethers.getContractFactory(connectorName); - const connector = await Connector.connect(wallet).deploy({ - gasPrice: ethers.utils.parseUnits(params["gasPrice"], "gwei"), + start = Date.now(); + await execScript({ + cmd: "npx", + args: [ + "hardhat", + "run", + "scripts/deployment/deploy.ts", + "--network", + `${runchain}`, + ], + env: { + connectorName: connector, + networkType: chain, + }, }); - await connector.deployed(); + end = Date.now(); +} - console.log(`${connectorName} Deployed: ${connector.address}`); - try { - await hre.run("verify:verify", { - address: connector.address, - constructorArguments: [], - }); - } catch (error) { - console.log(`Failed to verify: ${connectorName}@${connector.address}`); - console.log(error); - } - - return connector.address; -}; - -main() +deployRunner() .then(() => { - console.log("Done successfully"); + console.log( + `Done successfully, total time taken: ${(end - start) / 1000} sec` + ); process.exit(0); }) .catch((err) => { diff --git a/scripts/tests/addLiquidity.ts b/scripts/tests/addLiquidity.ts index 53a75a48..a18d172f 100644 --- a/scripts/tests/addLiquidity.ts +++ b/scripts/tests/addLiquidity.ts @@ -1,79 +1,31 @@ -import { Provider } from "@ethersproject/abstract-provider"; -import { Signer } from "@ethersproject/abstract-signer"; -import { ethers, network } from "hardhat"; +import { ethers } from "hardhat"; + import { impersonateAccounts } from "./impersonate"; +import { tokenMapping as mainnetMapping } from "./mainnet/tokens"; +import { tokenMapping as polygonMapping } from "./polygon/tokens"; +import { tokenMapping as avalancheMapping } from "./avalanche/tokens"; const mineTx = async (tx: any) => { await (await tx).wait(); }; -const tokenMapping: Record = { - usdc: { - impersonateSigner: "0xfcb19e6a322b27c06842a71e8c725399f049ae3a", - address: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - abi: [ - "function mint(address _to, uint256 _amount) external returns (bool);", - ], - process: async function(owner: Signer | Provider, to: any, amt: any) { - const contract = new ethers.Contract(this.address, this.abi, owner); - - await mineTx(contract.mint(to, amt)); - }, - }, - dai: { - impersonateSigner: "0x47ac0fb4f2d84898e4d9e7b4dab3c24507a6d503", - abi: ["function transfer(address to, uint value)"], - address: "0x6b175474e89094c44da98b954eedeac495271d0f", - process: async function(owner: Signer | Provider, to: any, amt: any) { - const contract = new ethers.Contract(this.address, this.abi, owner); - await mineTx(contract.transfer(to, amt)); - }, - }, - usdt: { - impersonateSigner: "0xc6cde7c39eb2f0f0095f41570af89efc2c1ea828", - address: "0xdac17f958d2ee523a2206206994597c13d831ec7", - abi: [ - "function issue(uint amount)", - "function transfer(address to, uint value)", - ], - process: async function(owner: Signer | Provider, address: any, amt: any) { - const contract = new ethers.Contract(this.address, this.abi, owner); - - await mineTx(contract.issue(amt)); - await mineTx(contract.transfer(address, amt)); - }, - }, - wbtc: { - impersonateSigner: "0xCA06411bd7a7296d7dbdd0050DFc846E95fEBEB7", - address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", - abi: ["function mint(address _to, uint256 _amount) public returns (bool)"], - process: async function(owner: Signer | Provider, address: any, amt: any) { - const contract = new ethers.Contract(this.address, this.abi, owner); - await mineTx(contract.mint(address, amt)); - }, - }, - inst: { - impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88", - address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb", - abi: ["function transfer(address to, uint value)"], - process: async function(owner: Signer | Provider, address: any, amt: any) { - const contract = new ethers.Contract(this.address, this.abi, owner); - await mineTx(contract.transfer(address, amt)); - }, - }, +const tokenMapping: Record> = { + mainnet: mainnetMapping, + polygon: polygonMapping, + avalanche: avalancheMapping, }; export async function addLiquidity(tokenName: string, address: any, amt: any) { const [signer] = await ethers.getSigners(); tokenName = tokenName.toLowerCase(); - if (!tokenMapping[tokenName]) { + const chain = String(process.env.networkType); + if (!tokenMapping[chain][tokenName]) { throw new Error( `Add liquidity doesn't support the following token: ${tokenName}` ); } - const token = tokenMapping[tokenName]; - + const token = tokenMapping[chain][tokenName]; const [impersonatedSigner] = await impersonateAccounts([ token.impersonateSigner, ]); diff --git a/scripts/tests/avalanche/tokens.ts b/scripts/tests/avalanche/tokens.ts index fc679ab4..f35ad299 100644 --- a/scripts/tests/avalanche/tokens.ts +++ b/scripts/tests/avalanche/tokens.ts @@ -1,3 +1,11 @@ +import { Provider } from "@ethersproject/abstract-provider"; +import { Signer } from "@ethersproject/abstract-signer"; +import { ethers } from "hardhat"; + +const mineTx = async (tx: any) => { + await (await tx).wait(); +}; + export const tokens = { eth: { type: "token", @@ -21,3 +29,59 @@ export const tokens = { decimals: 6, }, }; + +export const tokenMapping: Record = { + usdc: { + impersonateSigner: "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3", + address: "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664", + abi: [ + "function mint(address _to, uint256 _amount) external returns (bool);", + ], + process: async function (owner: Signer | Provider, to: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + + await mineTx(contract.mint(to, amt)); + }, + }, + dai: { + impersonateSigner: "0xed2a7edd7413021d440b09d654f3b87712abab66", + address: "0xd586e7f844cea2f87f50152665bcbc2c279d8d70", + abi: ["function transfer(address to, uint value)"], + process: async function (owner: Signer | Provider, to: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.transfer(to, amt)); + }, + }, + usdt: { + impersonateSigner: "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3", + address: "0xc7198437980c041c805a1edcba50c1ce5db95118", + abi: [ + "function issue(uint amount)", + "function transfer(address to, uint value)", + ], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + + await mineTx(contract.issue(amt)); + await mineTx(contract.transfer(address, amt)); + }, + }, + wbtc: { + impersonateSigner: "0x63cdb19c13497383726ad6bbf7c6b6cf725a3164", + address: "0x50b7545627a5162f82a992c33b87adc75187b218", + abi: ["function mint(address _to, uint256 _amount) public returns (bool)"], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.mint(address, amt)); + }, + }, + // inst: { + // impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88", + // address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb", + // abi: ["function transfer(address to, uint value)"], + // process: async function (owner: Signer | Provider, address: any, amt: any) { + // const contract = new ethers.Contract(this.address, this.abi, owner); + // await mineTx(contract.transfer(address, amt)); + // }, + // }, +}; diff --git a/scripts/tests/mainnet/tokens.ts b/scripts/tests/mainnet/tokens.ts index d3c95180..4fa7a6b1 100644 --- a/scripts/tests/mainnet/tokens.ts +++ b/scripts/tests/mainnet/tokens.ts @@ -1,3 +1,11 @@ +import { Provider } from "@ethersproject/abstract-provider"; +import { Signer } from "@ethersproject/abstract-signer"; +import { ethers } from "hardhat"; + +const mineTx = async (tx: any) => { + await (await tx).wait(); +}; + export const tokens = { eth: { type: "token", @@ -21,3 +29,59 @@ export const tokens = { decimals: 6, }, }; + +export const tokenMapping: Record = { + usdc: { + impersonateSigner: "0xfcb19e6a322b27c06842a71e8c725399f049ae3a", + address: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + abi: [ + "function mint(address _to, uint256 _amount) external returns (bool);", + ], + process: async function (owner: Signer | Provider, to: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + + await mineTx(contract.mint(to, amt)); + }, + }, + dai: { + impersonateSigner: "0x47ac0fb4f2d84898e4d9e7b4dab3c24507a6d503", + abi: ["function transfer(address to, uint value)"], + address: "0x6b175474e89094c44da98b954eedeac495271d0f", + process: async function (owner: Signer | Provider, to: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.transfer(to, amt)); + }, + }, + usdt: { + impersonateSigner: "0xc6cde7c39eb2f0f0095f41570af89efc2c1ea828", + address: "0xdac17f958d2ee523a2206206994597c13d831ec7", + abi: [ + "function issue(uint amount)", + "function transfer(address to, uint value)", + ], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + + await mineTx(contract.issue(amt)); + await mineTx(contract.transfer(address, amt)); + }, + }, + wbtc: { + impersonateSigner: "0xCA06411bd7a7296d7dbdd0050DFc846E95fEBEB7", + address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", + abi: ["function mint(address _to, uint256 _amount) public returns (bool)"], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.mint(address, amt)); + }, + }, + inst: { + impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88", + address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb", + abi: ["function transfer(address to, uint value)"], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.transfer(address, amt)); + }, + }, +}; diff --git a/scripts/tests/polygon/tokens.ts b/scripts/tests/polygon/tokens.ts index d621b68e..83b66b68 100644 --- a/scripts/tests/polygon/tokens.ts +++ b/scripts/tests/polygon/tokens.ts @@ -1,3 +1,11 @@ +import { Provider } from "@ethersproject/abstract-provider"; +import { Signer } from "@ethersproject/abstract-signer"; +import { ethers } from "hardhat"; + +const mineTx = async (tx: any) => { + await (await tx).wait(); +}; + export const tokens = { matic: { type: "token", @@ -10,7 +18,7 @@ export const tokens = { type: "token", symbol: "ETH", name: "Ethereum", - address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", + address: "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619", decimals: 18, }, dai: { @@ -28,3 +36,59 @@ export const tokens = { decimals: 6, }, }; + +export const tokenMapping: Record = { + usdc: { + impersonateSigner: "0x6e7a5fafcec6bb1e78bae2a1f0b612012bf14827", + address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + abi: [ + "function mint(address _to, uint256 _amount) external returns (bool);", + ], + process: async function (owner: Signer | Provider, to: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + + await mineTx(contract.mint(to, amt)); + }, + }, + dai: { + impersonateSigner: "0x4a35582a710e1f4b2030a3f826da20bfb6703c09", + address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", + abi: ["function transfer(address to, uint value)"], + process: async function (owner: Signer | Provider, to: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.transfer(to, amt)); + }, + }, + usdt: { + impersonateSigner: "0x0d0707963952f2fba59dd06f2b425ace40b492fe", + address: "0xc2132d05d31c914a87c6611c10748aeb04b58e8f", + abi: [ + "function issue(uint amount)", + "function transfer(address to, uint value)", + ], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + + await mineTx(contract.issue(amt)); + await mineTx(contract.transfer(address, amt)); + }, + }, + wbtc: { + impersonateSigner: "0xdc9232e2df177d7a12fdff6ecbab114e2231198d", + address: "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6", + abi: ["function mint(address _to, uint256 _amount) public returns (bool)"], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.mint(address, amt)); + }, + }, + inst: { + impersonateSigner: "0xf1f22f25f748f79263d44735198e023b72806ab1", + address: "0xf50d05a1402d0adafa880d36050736f9f6ee7dee", + abi: ["function transfer(address to, uint value)"], + process: async function (owner: Signer | Provider, address: any, amt: any) { + const contract = new ethers.Contract(this.address, this.abi, owner); + await mineTx(contract.transfer(address, amt)); + }, + }, +};