From bfd21e250ed330df138d6b27bff6301aa91421ce Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 13:19:30 +0530 Subject: [PATCH 1/8] updated dependencies --- package-lock.json | 37 ++++++++++++++++++++++++++----------- package.json | 4 ++-- 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index aadbddd5..bc7ad39e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.3", - "@nomiclabs/hardhat-etherscan": "^2.1.8", + "@nomiclabs/hardhat-etherscan": "^3.0.3", "@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-web3": "^2.0.0", "@openzeppelin/test-helpers": "^0.5.15", @@ -2121,9 +2121,9 @@ } }, "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz", - "integrity": "sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", + "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", @@ -2131,8 +2131,8 @@ "cbor": "^5.0.2", "debug": "^4.1.1", "fs-extra": "^7.0.1", - "node-fetch": "^2.6.0", - "semver": "^6.3.0" + "semver": "^6.3.0", + "undici": "^4.14.1" }, "peerDependencies": { "hardhat": "^2.0.4" @@ -28736,6 +28736,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", + "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "dev": true, + "engines": { + "node": ">=12.18" + } + }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -32499,9 +32508,9 @@ "requires": {} }, "@nomiclabs/hardhat-etherscan": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz", - "integrity": "sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.0.3.tgz", + "integrity": "sha512-OfNtUKc/ZwzivmZnnpwWREfaYncXteKHskn3yDnz+fPBZ6wfM4GR+d5RwjREzYFWE+o5iR9ruXhWw/8fejWM9g==", "dev": true, "requires": { "@ethersproject/abi": "^5.1.2", @@ -32509,8 +32518,8 @@ "cbor": "^5.0.2", "debug": "^4.1.1", "fs-extra": "^7.0.1", - "node-fetch": "^2.6.0", - "semver": "^6.3.0" + "semver": "^6.3.0", + "undici": "^4.14.1" } }, "@nomiclabs/hardhat-waffle": { @@ -53586,6 +53595,12 @@ "which-boxed-primitive": "^1.0.2" } }, + "undici": { + "version": "4.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-4.16.0.tgz", + "integrity": "sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw==", + "dev": true + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", diff --git a/package.json b/package.json index 0deaf533..f312326d 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,14 @@ "chalk": "^5.0.0", "dotenv": "^10.0.0", "hardhat-docgen": "^1.2.0", - "inquirer": "^8.2.0", + "inquirer": "^8.2.0", "minimist": "^1.2.5", "solc": "^0.8.10", "typechain": "^6.0.5" }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.3", - "@nomiclabs/hardhat-etherscan": "^2.1.8", + "@nomiclabs/hardhat-etherscan": "^3.0.3", "@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-web3": "^2.0.0", "@openzeppelin/test-helpers": "^0.5.15", From 3177d6a8aae10ab483706463911447a52a88f04e Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 13:19:50 +0530 Subject: [PATCH 2/8] updated config: etherscan <0.3.0> --- hardhat.config.ts | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 9b7e4eb6..0406c6e5 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -42,18 +42,20 @@ const FANTOMSCAN_API = process.env.FANTOM_API_KEY; const OPTIMISM_API = process.env.OPTIMISM_API_KEY; const mnemonic = process.env.MNEMONIC ?? "test test test test test test test test test test test junk"; -const networkGasPriceConfig: Record = { - mainnet: "160", - polygon: "50", - avalanche: "50", - arbitrum: "2" +const networkGasPriceConfig: Record = { + mainnet: 100, + polygon: 50, + avalanche: 30, + arbitrum: 1, + optimism: 0.001, + fantom: 300 }; function createConfig(network: string) { return { url: getNetworkUrl(network), - accounts: !!PRIVATE_KEY ? [`0x${PRIVATE_KEY}`] : { mnemonic } - // gasPrice: 1000000, // 0.0001 GWEI + accounts: !!PRIVATE_KEY ? [`0x${PRIVATE_KEY}`] : { mnemonic }, + gasPrice: networkGasPriceConfig[network] * 1e9 // Update the mapping above }; } @@ -66,16 +68,6 @@ function getNetworkUrl(networkType: string) { else return `https://eth-mainnet.alchemyapi.io/v2/${alchemyApiKey}`; } -function getScanApiKey(networkType: string) { - if (networkType === "avalanche") return SNOWTRACE_API; - else if (networkType === "polygon") return POLYGONSCAN_API; - else if (networkType === "arbitrum") return ARBISCAN_API; - else if (networkType === "fantom") return FANTOMSCAN_API; - else if (networkType === "fantom") return FANTOMSCAN_API; - else if (networkType === "optimism") return OPTIMISM_API; - else return ETHERSCAN_API; -} - /** * @type import('hardhat/config').HardhatUserConfig */ @@ -126,7 +118,14 @@ const config: HardhatUserConfig = { tests: "./test" }, etherscan: { - apiKey: getScanApiKey(String(process.env.networkType)) + apiKey: { + mainnet: String(process.env.MAIN_ETHSCAN_KEY), + optimisticEthereum: String(process.env.OPT_ETHSCAN_KEY), + polygon: String(process.env.POLY_ETHSCAN_KEY), + arbitrumOne: String(process.env.ARB_ETHSCAN_KEY), + avalanche: String(process.env.AVAX_ETHSCAN_KEY), + opera: String(process.env.FTM_ETHSCAN_KEY) + } }, typechain: { outDir: "typechain", From 798690b99e2ecf84a45626415ca92c3ffd2d4241 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 13:20:07 +0530 Subject: [PATCH 3/8] updated .env.example --- .env.example | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index 2525a67a..8a266b33 100644 --- a/.env.example +++ b/.env.example @@ -2,4 +2,10 @@ ETHERSCAN_API_KEY="" PRIVATE_KEY="" TENDERLY_PROJECT="" TENDERLY_USERNAME="" -ALCHEMY_ID="" \ No newline at end of file +ALCHEMY_ID="" +MAIN_ETHSCAN_KEY= +OPT_ETHSCAN_KEY= +POLY_ETHSCAN_KEY= +ARB_ETHSCAN_KEY= +AVAX_ETHSCAN_KEY= +FTM_ETHSCAN_KEY= \ No newline at end of file From 2563e7a9210c685c53591c24a3a2b72929ffbb00 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 13:24:15 +0530 Subject: [PATCH 4/8] updated readme.md --- README.md | 71 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index a3701741..0ce92cba 100644 --- a/README.md +++ b/README.md @@ -47,8 +47,25 @@ Run all the tests: ```sh $ npm run test ``` + (Striclty use this envirnment to test, or otherwise make suitable changes in config file before testing). +### Deploy + +To deploy a connector using interactive CLI + +```sh +$ npm run deploy:runner +``` + +### checks + +To check that code is compatible with github actions + +```sh +$ npm run check +``` + ## How to add a new connector You can create a new PR to add a new connector. To get the PR merged, certain requirements needs to be met which will be explained here. @@ -57,39 +74,39 @@ You can create a new PR to add a new connector. To get the PR merged, certain re Common files for all connectors are in `contracts/common` directory. -* `math.sol` has methods for mathematical operations (`DSMath`) -* `interfaces.sol` contains the common interfaces - * `TokenInterface` for ERC-20 interface including WETH -* `stores.sol` contains the global constants as well as methods `getId` & `setId` (`Stores`) -* `basic.sol` inherits `DSMath` & `Stores` contracts. This contains few details explained below - * Wrapping & unwrapping ETH (`convertEthToWeth` & `convertWethToEth`) - * Getting token & ETH balance of DSA +- `math.sol` has methods for mathematical operations (`DSMath`) +- `interfaces.sol` contains the common interfaces + - `TokenInterface` for ERC-20 interface including WETH +- `stores.sol` contains the global constants as well as methods `getId` & `setId` (`Stores`) +- `basic.sol` inherits `DSMath` & `Stores` contracts. This contains few details explained below + - Wrapping & unwrapping ETH (`convertEthToWeth` & `convertWethToEth`) + - Getting token & ETH balance of DSA Connectors are under `contracts/connectors` directory, and should be formatted as follows: -* Connector events should be in a separate contract: `events.sol` -* Interfaces should be defined in a seperate file: `interface.sol` -* If the connector has helper methods & constants (including interface instances), this should be defined in a separate file: `helpers.sol` - * `Helpers` contract should inherit `Basic` contract from common directory - * If the connector doesn't have any helper methods, the main contract should inherit `Basic` contract -* The main logic of the contract should be under `main.sol`, and the contract should inherit `Helpers` (if exists, otherwise `Basic`) & `Events` +- Connector events should be in a separate contract: `events.sol` +- Interfaces should be defined in a seperate file: `interface.sol` +- If the connector has helper methods & constants (including interface instances), this should be defined in a separate file: `helpers.sol` + - `Helpers` contract should inherit `Basic` contract from common directory + - If the connector doesn't have any helper methods, the main contract should inherit `Basic` contract +- The main logic of the contract should be under `main.sol`, and the contract should inherit `Helpers` (if exists, otherwise `Basic`) & `Events` Few things to consider while writing the connector: -* Connector should have a public constant string declared `name`, which will be the name of the connector. This will be versioned. Ex: `Compound-v1` -* Contract name should start with `ConnectV2` appended with protocol name. Eg: `ConnectV2Compound` -* User interacting methods (`external` methods) will not be emitting events, rather the methods will be returning 2 variables: - * `_eventName` of `string` type: This will be the event signture defined in the `Events` contract. Ex: `LogDeposit(address,address,uint256,uint256,uint256)` - * `_eventParam` of `bytes` type: This will be the abi encoded event parameters -* The contracts should not have `selfdestruct()` -* The contracts should not have `delegatecall()` -* Use `uint(-1)` of `type(uint256).max` for maximum amount everywhere -* Use `ethAddr` (declared in `Stores`) to denote Ethereum (non-ERC20) -* Use `address(this)` instead of `msg.sender` for fetching balance on-chain, etc -* Only `approve()` (declared in `Basic`) limited amount while giving ERC20 allowance, which strictly needs to be 0 by the end of the spell. -* User interacting functions should have natspec comments(@dev, @notice, @param). -* Use `getUint()` (declared in `Stores`) for getting value that saved from previous spell -* Use `setUint()` (declared in `Stores`) for setting value to save for the future spell +- Connector should have a public constant string declared `name`, which will be the name of the connector. This will be versioned. Ex: `Compound-v1` +- Contract name should start with `ConnectV2` appended with protocol name. Eg: `ConnectV2Compound` +- User interacting methods (`external` methods) will not be emitting events, rather the methods will be returning 2 variables: + - `_eventName` of `string` type: This will be the event signture defined in the `Events` contract. Ex: `LogDeposit(address,address,uint256,uint256,uint256)` + - `_eventParam` of `bytes` type: This will be the abi encoded event parameters +- The contracts should not have `selfdestruct()` +- The contracts should not have `delegatecall()` +- Use `uint(-1)` of `type(uint256).max` for maximum amount everywhere +- Use `ethAddr` (declared in `Stores`) to denote Ethereum (non-ERC20) +- Use `address(this)` instead of `msg.sender` for fetching balance on-chain, etc +- Only `approve()` (declared in `Basic`) limited amount while giving ERC20 allowance, which strictly needs to be 0 by the end of the spell. +- User interacting functions should have natspec comments(@dev, @notice, @param). +- Use `getUint()` (declared in `Stores`) for getting value that saved from previous spell +- Use `setUint()` (declared in `Stores`) for setting value to save for the future spell ### Support From ea5e1a91066b96c3a785cb24e4547c82d84d3361 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 13:28:13 +0530 Subject: [PATCH 5/8] added basic deploy script --- scripts/deployment/deployManually.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 scripts/deployment/deployManually.ts diff --git a/scripts/deployment/deployManually.ts b/scripts/deployment/deployManually.ts new file mode 100644 index 00000000..fd91dd7b --- /dev/null +++ b/scripts/deployment/deployManually.ts @@ -0,0 +1,19 @@ +import { Contract } from "@ethersproject/contracts"; +import { ethers } from "hardhat"; + +import { Greeter__factory } from "../../typechain"; + +async function main(): Promise { + const Greeter: Greeter__factory = await ethers.getContractFactory("Greeter"); + const greeter: Contract = await Greeter.deploy("Hello, Buidler!"); + await greeter.deployed(); + + console.log("Greeter deployed to: ", greeter.address); +} + +main() + .then(() => process.exit(0)) + .catch((error: Error) => { + console.error(error); + process.exit(1); + }); From 5382f3d17cf916d13c86d94a29265029a06a7039 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 13:29:42 +0530 Subject: [PATCH 6/8] readme update --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0ce92cba..0b36d125 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,8 @@ To deploy a connector using interactive CLI $ npm run deploy:runner ``` +(To deploy script manually use `scripts/deployment/deployManually.ts` script) + ### checks To check that code is compatible with github actions From 80fcdec49c5218deea3958a962a09ad6b8367759 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 20:20:39 +0530 Subject: [PATCH 7/8] added hardhat verify:verify --- scripts/deployment/deployManually.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/deployment/deployManually.ts b/scripts/deployment/deployManually.ts index fd91dd7b..d60f73d5 100644 --- a/scripts/deployment/deployManually.ts +++ b/scripts/deployment/deployManually.ts @@ -1,5 +1,5 @@ import { Contract } from "@ethersproject/contracts"; -import { ethers } from "hardhat"; +import hre, { ethers } from "hardhat"; import { Greeter__factory } from "../../typechain"; @@ -9,6 +9,10 @@ async function main(): Promise { await greeter.deployed(); console.log("Greeter deployed to: ", greeter.address); + + await hre.run("verify:verify", { + address: greeter.address + }); } main() From 5dd5429d2992c7c69539e2905f8bc2d9a36281e2 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sat, 19 Mar 2022 20:24:43 +0530 Subject: [PATCH 8/8] added bigNumber.js in cofig --- hardhat.config.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 0406c6e5..e679a097 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -14,6 +14,7 @@ import { NetworkUserConfig } from "hardhat/types"; import { utils } from "ethers"; import Web3 from "web3"; import { network } from "hardhat"; +import bigNumber from "bignumber.js"; dotenvConfig({ path: resolve(__dirname, "./.env") }); @@ -34,12 +35,6 @@ if (!alchemyApiKey) { } const PRIVATE_KEY = process.env.PRIVATE_KEY; -const ETHERSCAN_API = process.env.ETHERSCAN_API_KEY; -const POLYGONSCAN_API = process.env.POLYGON_API_KEY; -const ARBISCAN_API = process.env.ARBISCAN_API_KEY; -const SNOWTRACE_API = process.env.SNOWTRACE_API_KEY; -const FANTOMSCAN_API = process.env.FANTOM_API_KEY; -const OPTIMISM_API = process.env.OPTIMISM_API_KEY; const mnemonic = process.env.MNEMONIC ?? "test test test test test test test test test test test junk"; const networkGasPriceConfig: Record = { @@ -55,7 +50,7 @@ function createConfig(network: string) { return { url: getNetworkUrl(network), accounts: !!PRIVATE_KEY ? [`0x${PRIVATE_KEY}`] : { mnemonic }, - gasPrice: networkGasPriceConfig[network] * 1e9 // Update the mapping above + gasPrice: new bigNumber(networkGasPriceConfig[network]).multipliedBy(1e9).toNumber() // Update the mapping above }; }