diff --git a/README.md b/README.md index 49b0e9c8..d9e81ffc 100644 --- a/README.md +++ b/README.md @@ -104,30 +104,89 @@ Follow below steps to execute script and start interacting Note: bridge address will be picked from `deploymentAddress[network].new.bridge` (from `spectre-bridge-protocol/eth/scripts/deployment/deploymentAddresses.json`) ### To interact with FastBridge using hardhat task -To call any method of EthErc20FastBridge use hardhat task `method` -Run command `npx hardhat method --jsonstring ` -``` -to create `json_string_input` -1. create json with `signature` and `arguments` properties in below example format - - { - "signature": "setWhitelistedTokens(address[],bool[])", - "argcount": "2", - "arguments": { - "arg1": [ - "0xdAC17F958D2ee523a2206206994597C13D831ec7", - "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", - "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" - ], - "arg2": [ - true, - true, - true - ] +1. To call any method of EthErc20FastBridge use hardhat task `method` + Run command `npx hardhat method --jsonstring ` + + to create `json_string_input` + 1. create json with `signature` and `arguments` properties in below example format + ``` bash + { + "signature": "setWhitelistedTokens(address[],bool[])", + "argcount": "2", + "arguments": { + "arg1": [ + "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "0xB8c77482e45F1F44dE1745F52C74426C631bDD52", + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" + ], + "arg2": [ + true, + true, + true + ] + } } -} - -2. pass below json to JSON.stringify() and use output as `json_string_input` - -``` -example: to call `setWhitelistedTokens` method run command `npx hardhat method --jsonstring '{"signature":"setWhitelistedTokens","arguments":{"arg1":["0xdAC17F958D2ee523a2206206994597C13D831ec7"],"arg2":[true]}}'` \ No newline at end of file + ``` + 2. pass below json to JSON.stringify() and use output as `json_string_input` + + + For example: to call `setWhitelistedTokens` method run command + ``` bash + npx hardhat method --jsonstring '{"signature":"setWhitelistedTokens","arguments":{"arg1":["0xdAC17F958D2ee523a2206206994597C13D831ec7"],"arg2":[true]}}' + ``` + +2. To deploy fast-bridge run + ``` bash + npx hardhat deploy_fastbridge --verification --network + ``` + here `--verification` is an optional parameter with default value `false` if passed `true` than contract is verified just after the deployment. +3. To verify already deployed contract on same network run + ``` bash + npx hardhat verify_bridge --proxyaddress --network + ``` +4. To whitelists single erc20 token in fast-bridge run `npx hardhat whitelists_token --tokenaddress --network `, here the pvt key of signer need to have the authorised role to make successful txn and key is picked from .env file so you need to setup it before running the cmd. +
For example: + ``` bash + npx hardhat whitelists_token --tokenaddress 0xb2d75C5a142A68BDA438e6a318C7FBB2242f9693 --network mumbai + ``` +5. To whitelists token in bulk run + ``` bash + npx hardhat whitelists_token_in_bulk --tokenaddresses --whiteliststatus --network + ``` + *For example*:- + ``` bash + npx hardhat whitelists_token_in_bulk --tokenaddresses 0xF0b0c5E2c3A35213992bD9b45Af352D6D4035203,0xaa2D6608241B6B930BCcaFE245eFDf052e46C9aA --whiteliststatus true,true,true --network mumbai + ``` + Here also signer need to have the access role to make txn successful. +6. To check whether the token is whitelisted or not run + ``` bash + npx hardhat is_token_whitelisted --tokenaddress --bridgeproxyaddress --network + ``` +7. To remove token from whitelists run + ``` bash + npx hardhat remove_token_from_whitelists --tokenaddress --network + ``` + For example: + ``` bash + npx hardhat remove_token_from_whitelists --tokenaddress 0xb2d75C5a142A68BDA438e6a318C7FBB2242f9693 --network mumbai + ``` +8. To pause fast_bridge run + ``` bash + npx hardhat pause_fastbridge --network + ``` + here the signer needs to have desired role to do so. +9. To unpause fast_bridge run + ``` bash + npx hardhat unpause_fastbridge --network + ``` + here also the signer needs to have proper access role to do so. +10. To upgrade the fastbridge run + ``` bash + npx hardhat upgrade_fastbridge --network + ``` + here the signer needs to have the proper admin role to upgrade the fast-bridge contract. +11. To withdraw stucked erc-20 tokens on fastbridge run:- + ``` bash + npx hardhat withdraw_stuck_tokens --tokenaddress --network + ``` + Here, the caller must have `DEFAULT_ADMIN_ROLE` to make withdraw success. \ No newline at end of file diff --git a/eth/hardhat.config.js b/eth/hardhat.config.js index 8408c462..e1fc31ca 100644 --- a/eth/hardhat.config.js +++ b/eth/hardhat.config.js @@ -6,12 +6,8 @@ require("@nomicfoundation/hardhat-network-helpers"); require("hardhat-contract-sizer"); require("hardhat-abi-exporter"); require("@openzeppelin/hardhat-upgrades"); -const { ethers } = require("ethers"); -const { task } = require("hardhat/config"); -const deploymentAddress = require("./scripts/deployment/deploymentAddresses.json"); -const bridgeArtifacts = require("./artifacts/contracts/EthErc20FastBridge.sol/EthErc20FastBridge.json"); -require('hardhat-storage-layout'); - +require("./scripts/EthErc20FastBridge/tasks.js"); +require("hardhat-storage-layout"); const PRIVATE_KEYS = process.env.PRIVATE_KEYS ? process.env.PRIVATE_KEYS.split(",") : []; const PRIVATE_KEY = process.env.PRIVATE_KEY || "11".repeat(32); @@ -23,35 +19,6 @@ const FORKING = true; const ENABLED_OPTIMIZER = true; const OPTIMIZER_RUNS = 200; -task("method", "Execute Fastbridge methods") - .addParam("jsonstring", "JSON string with function signature and arguments") - .setAction(async (taskArgs) => { - const network = (await ethers.getDefaultProvider().getNetwork()).name; - const bridgeAddress = deploymentAddress[network].new.bridge; - const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_TASK); - const signer = new ethers.Wallet(process.env.PRIVATE_KEY, provider); - - const jsonString = taskArgs.jsonstring; - const json = JSON.parse(jsonString); - const arg = json.arguments; - const functionSignature = json.signature; - console.log(arg); - const functionArguments = Object.values(arg); - console.log(functionSignature, functionArguments); - const iface = new ethers.utils.Interface(bridgeArtifacts.abi); - // Send the transaction - const txdata = iface.encodeFunctionData(functionSignature, functionArguments); - const tx = await signer.sendTransaction({ - to: bridgeAddress, - data: txdata, - gasLimit: 999999 - }); - console.log(tx); - await tx.wait(); - - console.log("Transaction mined!"); - }); - module.exports = { solidity: { version: "0.8.11", @@ -97,6 +64,12 @@ module.exports = { ? `https://goerli.infura.io/v3/${INFURA_API_KEY}` : `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`, accounts: [`${PRIVATE_KEY}`] + }, + mumbai: { + url: INFURA_API_KEY + ? `https://mumbai.infura.io/v3/${INFURA_API_KEY}` + : `https://polygon-mumbai.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, + accounts: [`${PRIVATE_KEY}`] } }, gasReporter: { @@ -120,5 +93,4 @@ module.exports = { if (process.env.FORKING_BLOCK_NUMBER) module.exports.networks.hardhat.forking.blockNumber = +process.env.FORKING_BLOCK_NUMBER; -if (process.env.HARDFORK) - module.exports.networks.hardhat.hardfork = process.env.HARDFORK; +if (process.env.HARDFORK) module.exports.networks.hardhat.hardfork = process.env.HARDFORK; diff --git a/eth/package-lock.json b/eth/package-lock.json index 2c340c8b..de9c2c0d 100644 --- a/eth/package-lock.json +++ b/eth/package-lock.json @@ -37,6 +37,7 @@ "mocha": "^10.2.0", "prettier": "^2.8.1", "prettier-plugin-solidity": "^1.1.0", + "prompt-sync": "^4.2.0", "shx": "^0.3.4", "solc": "0.8.17", "solhint": "^3.3.7", @@ -12438,6 +12439,36 @@ "asap": "~2.0.6" } }, + "node_modules/prompt-sync": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", + "integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==", + "dev": true, + "dependencies": { + "strip-ansi": "^5.0.0" + } + }, + "node_modules/prompt-sync/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/prompt-sync/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", @@ -27039,6 +27070,32 @@ "asap": "~2.0.6" } }, + "prompt-sync": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/prompt-sync/-/prompt-sync-4.2.0.tgz", + "integrity": "sha512-BuEzzc5zptP5LsgV5MZETjDaKSWfchl5U9Luiu8SKp7iZWD5tZalOxvNcZRwv+d2phNFr8xlbxmFNcRKfJOzJw==", + "dev": true, + "requires": { + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "proper-lockfile": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", diff --git a/eth/package.json b/eth/package.json index 75b672b5..49f41482 100644 --- a/eth/package.json +++ b/eth/package.json @@ -15,9 +15,9 @@ "dev:size-contracts": "npm run compile-all && npx hardhat size-contracts", "deploy:all": "npx hardhat run scripts/deployment/", "deploy:test-tokens": "npm run compile-all && npx hardhat run scripts/deployment/deploy-test-tokens.js --network goerli", - "deploy:bridge": "npm run compile-all && npx hardhat run scripts/deployment/deploy-bridge.js --network ", - "deploy:verify:bridge": "npm run compile-all && npx hardhat run scripts/EthErc20FastBridge/deploy_and_verify_bridge.js --network", - "upgrade:bridge": "npm run compile-all && npx hardhat run scripts/EthErc20FastBridge/upgrade_bridge.js --network ", + "deploy:bridge": "npx hardhat deploy_fastbridge --network ", + "deploy:verify:bridge": "npx hardhat deploy_fastbridge --verification true --network ", + "upgrade:bridge": "npx hardhat upgrade_fastbridge --network ", "dev:abi": "npx hardhat clear-abi && npx hardhat export-abi", "dev:coverage": "npx hardhat coverage", "docgen": "npx shx rm -rf docs && npx solidity-docgen --solc-module solc -t docgen -H docgen/helpers.js -o docs/", @@ -69,16 +69,17 @@ "hardhat": "^2.12.4", "hardhat-abi-exporter": "^2.10.1", "hardhat-contract-sizer": "^2.6.1", + "hardhat-storage-layout": "^0.1.7", "mocha": "^10.2.0", "prettier": "^2.8.1", "prettier-plugin-solidity": "^1.1.0", + "prompt-sync": "^4.2.0", "shx": "^0.3.4", "solc": "0.8.17", "solhint": "^3.3.7", "solhint-plugin-prettier": "^0.0.5", "solidity-docgen": "0.5.17", - "web3": "^1.8.1", - "hardhat-storage-layout": "^0.1.7" + "web3": "^1.8.1" }, "engines": { "node": ">= 16.0.0", diff --git a/eth/scripts/EthErc20FastBridge/deploy_and_verify_bridge.js b/eth/scripts/EthErc20FastBridge/deploy_and_verify_bridge.js deleted file mode 100644 index b4bc48bc..00000000 --- a/eth/scripts/EthErc20FastBridge/deploy_and_verify_bridge.js +++ /dev/null @@ -1,36 +0,0 @@ -const { ethers, upgrades } = require("hardhat"); -const { getAddressSaver, verify } = require("../deployment/utilities/helpers"); -const { getImplementationAddress } = require("@openzeppelin/upgrades-core"); -const path = require("path"); - -const main = async () => { - const [deployer] = await ethers.getSigners(); - const network = (await ethers.getDefaultProvider().getNetwork()).name; - const addressesPath = path.join(__dirname, "../deployment/deploymentAddresses.json"); - const saveAddress = getAddressSaver(addressesPath, network, true); - - const tokensAddresses = Object.values(require("../deployment/deploymentAddresses.json").tokens); - const whitelistedTokens = Object.values(require("../deployment/deploymentAddresses.json").whitelisted_tokens); - - const bridge = await ethers.getContractFactory("EthErc20FastBridge", deployer); - const Bridge = await upgrades.deployProxy(bridge, [tokensAddresses, whitelistedTokens], { - unsafeAllow: ["delegatecall"] - }); - await Bridge.deployed(); - - saveAddress("bridge_proxy", Bridge.address); // save bridge address - - const currentImplAddress = await getImplementationAddress(ethers.provider, Bridge.address); - - saveAddress("bridge_Implementation", currentImplAddress); // save implementation address - - // verify - console.log("Verifing Contract"); - await verify(Bridge.address, [tokensAddresses, whitelistedTokens]); - console.log("Verified."); -}; - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/eth/scripts/EthErc20FastBridge/interact_with_bridge.js b/eth/scripts/EthErc20FastBridge/interact_with_bridge.js index cd49c153..82350a7f 100644 --- a/eth/scripts/EthErc20FastBridge/interact_with_bridge.js +++ b/eth/scripts/EthErc20FastBridge/interact_with_bridge.js @@ -28,7 +28,7 @@ async function main() { console.log("to execute bulkWhitelistStatusUpdate(tokensArray, statusArray, signer)"); const inputTokens = prompt("please enter space separated token addresses : "); let addressArray = inputTokens.trim().split(" "); - const inputStatuses = prompt("please enter space separated token addresses : "); + const inputStatuses = prompt("please enter space separated token whitelists status in bool : "); let statusArray = inputStatuses.trim().split(" "); console.log(addressArray); diff --git a/eth/scripts/EthErc20FastBridge/tasks.js b/eth/scripts/EthErc20FastBridge/tasks.js new file mode 100644 index 00000000..24022407 --- /dev/null +++ b/eth/scripts/EthErc20FastBridge/tasks.js @@ -0,0 +1,146 @@ +const { task } = require("hardhat/config"); +const { boolean } = require("hardhat/internal/core/params/argumentTypes"); +const deploymentAddress = require("../deployment/deploymentAddresses.json"); +const bridgeArtifacts = require("../../artifacts/contracts/EthErc20FastBridge.sol/EthErc20FastBridge.json"); + +task("method", "Execute Fastbridge methods") + .addParam("jsonstring", "JSON string with function signature and arguments") + .setAction(async (taskArgs, hre) => { + const network_name = hre.network.name; + const bridgeAddress = deploymentAddress[network_name].new.bridge; + const provider = new hre.ethers.providers.JsonRpcProvider(process.env.RPC_TASK); + const signer = new hre.ethers.Wallet(process.env.PRIVATE_KEY, provider); + + const jsonString = taskArgs.jsonstring; + const json = JSON.parse(jsonString); + const arg = json.arguments; + const functionSignature = json.signature; + console.log(arg); + const functionArguments = Object.values(arg); + console.log(functionSignature, functionArguments); + const iface = new hre.ethers.utils.Interface(bridgeArtifacts.abi); + // Send the transaction + const txdata = iface.encodeFunctionData(functionSignature, functionArguments); + const tx = await signer.sendTransaction({ + to: bridgeAddress, + data: txdata, + gasLimit: 999999 + }); + console.log(tx); + await tx.wait(); + + console.log("Transaction mined!"); + }); + +task("deploy_fastbridge", "Deploys Eth-Erc20 Fastbridge and whitelists tokens in deploymentAddress.json") + .addParam("verification", "Verify the deployed fastbridge on same network", false, boolean) + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const deploy_fast_bridge = require("../deployment/deploy-bridge.js"); + await deploy_fast_bridge(taskArgs.verification); + }); + +task("verify_bridge", "verifies the already deployed contract on same network") + .addParam("proxyaddress", "Proxy address of already deployed fast-bridge contract") + .setAction(async (taskArgs) => { + const { verify } = require("../deployment/utilities/helpers.js"); + await verify(taskArgs.proxyaddress, []); + }); + +task("whitelists_token", "Whitelists erc-20 token in fast-bridge by authorised whitelisting-admin-signer") + .addParam("tokenaddress", "Address of token to be whitelisted") + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const { addTokenToWhitelist } = require("./whitelistTokens.js"); + const [whitelistingAdminSigner] = await hre.ethers.getSigners(); + await addTokenToWhitelist(taskArgs.tokenaddress, whitelistingAdminSigner); + }); + +task("is_token_whitelisted", "Check if token is whitelisted or not") + .addParam("tokenaddress", "Token address to check for whitelist") + .addParam("bridgeproxyaddress", "Fast-bridge proxy contract address") + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const { isTokenInWhitelist } = require("./whitelistTokens.js"); + await isTokenInWhitelist(taskArgs.tokenaddress, taskArgs.bridgeproxyaddress); + }); + +task("remove_token_from_whitelists", "Removes erc-20 token from whitelists") + .addParam("tokenaddress", "Token address to remove from whitelists") + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const [whitelistingAdminSigner] = await hre.ethers.getSigners(); + const { removeTokenFromWhitelist } = require("./whitelistTokens.js"); + await removeTokenFromWhitelist(taskArgs.tokenaddress, whitelistingAdminSigner); + }); + +task( + "whitelists_token_in_bulk", + "Whitelists erc-20 tokens in fast-bridge by authorised whitelisting-admin-signer in bulk" +) + .addParam("tokenaddresses", "Comma separated token addresses to whitelists") + .addParam("whiteliststatus", "Comma separated bool values for associated tokens whitelist status") + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const [whitelistingAdminSigner] = await hre.ethers.getSigners(); + const tokenAddresses = taskArgs.tokenaddresses.split(","); + const whitelistsStatus = taskArgs.whiteliststatus.split(","); + const { bulkWhitelistStatusUpdate } = require("./whitelistTokens.js"); + await bulkWhitelistStatusUpdate(tokenAddresses, whitelistsStatus, whitelistingAdminSigner); + }); + +task("withdraw_stuck_tokens", "Withdraw stucked erc-20 tokens in fast bridge (caller with DEFAULT_ADMIN_ROLE)") + .addParam("tokenaddress", "Address of stucked token") + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const [defaultAdminSigner] = await hre.ethers.getSigners(); + const { withdrawStuckTokens } = require("./withdraw_Stuck_tokens.js"); + await withdrawStuckTokens(taskArgs.tokenaddress, defaultAdminSigner); + }); + +task("pause_fastbridge", "Pause all user-accessible operations in fast-bridge").setAction(async (_taskArgs, hre) => { + await hre.run("compile"); + const [pauseableAdminSigner] = await hre.ethers.getSigners(); + const { pauseTransfer } = require("./pause_unpause.js"); + await pauseTransfer(pauseableAdminSigner); +}); + +task("unpause_fastbridge", "Unpause all user-accessible operations in fast-bridge").setAction( + async (_taskArgs, hre) => { + await hre.run("compile"); + const [unPauseableAdminSigner] = await hre.ethers.getSigners(); + const { unpauseTransfer } = require("./pause_unpause.js"); + await unpauseTransfer(unPauseableAdminSigner); + } +); + +task("upgrade_fastbridge", "Upgrade fast-bridge contract (Only signer with DEFAULT_ADMIN_ROLE can do this)").setAction( + async (_taskArgs, hre) => { + await hre.run("compile"); + const [defaultAdminSigner] = await hre.ethers.getSigners(); + const { upgradeFastBridge } = require("./upgrade_bridge.js"); + await upgradeFastBridge(defaultAdminSigner); + } +); + +task("transfer_token", "transfer erc-20 token to fast bridge") + .addParam("tokenaddress", "erc-20 token address which is to be transfer") + .addParam("recipient", "Address of token receiver") + .addParam("nonce", "nonce of transfer") + .addParam("amount", "Amount of erc-20 token to transfer") + .addParam("unlockrecipient", "Near side unlock recipient: relayer address") + .addParam("validtillblockheight", "Block height till which near side unlock is to be made") + .setAction(async (taskArgs, hre) => { + await hre.run("compile"); + const [signer] = await hre.ethers.getSigners(); + const { transferTokens } = require("./transfer_token.js"); + await transferTokens( + signer, + taskArgs.tokenaddress, + taskArgs.recipient, + taskArgs.nonce, + taskArgs.amount, + taskArgs.unlockrecipient, + taskArgs.validtillblockheight + ); + }); diff --git a/eth/scripts/EthErc20FastBridge/transfer_token.js b/eth/scripts/EthErc20FastBridge/transfer_token.js new file mode 100644 index 00000000..7cbb66e2 --- /dev/null +++ b/eth/scripts/EthErc20FastBridge/transfer_token.js @@ -0,0 +1,16 @@ +const { getBridge } = require("./whitelistTokens"); + +async function transferTokens(signer, token, recipient, nonce, amount, unlock_recipient, valid_till_block_height) { + let bridge; + try { + bridge = await getBridge(); + await bridge + .connect(signer) + .transferTokens(token, recipient, nonce, amount, unlock_recipient, valid_till_block_height); + } catch (error) { + console.log("Failed to transfer tokens", error); + } +} +module.exports = { + transferTokens +}; diff --git a/eth/scripts/EthErc20FastBridge/upgrade_bridge.js b/eth/scripts/EthErc20FastBridge/upgrade_bridge.js index 4038611d..72173219 100644 --- a/eth/scripts/EthErc20FastBridge/upgrade_bridge.js +++ b/eth/scripts/EthErc20FastBridge/upgrade_bridge.js @@ -1,11 +1,12 @@ -const { ethers, upgrades } = require("hardhat"); +const { ethers, upgrades, network } = require("hardhat"); const { getImplementationAddress } = require("@openzeppelin/upgrades-core"); +const deploymentAddress = require("../deployment/deploymentAddresses.json"); +const { getAddressSaver } = require("../deployment/utilities/helpers.js"); +const path = require("path"); require("dotenv"); -async function main() { - const [deployer] = await ethers.getSigners(); - - const EthErc20FastBridge = await ethers.getContractFactory("EthErc20FastBridge", deployer); +async function main(defaultAdminSigner) { + const EthErc20FastBridge = await ethers.getContractFactory("EthErc20FastBridge", defaultAdminSigner); const bridgeProxyAddress = process.env.BRIDGE_PROXY_ADDRESS; console.log("Need to upgrade bridge?"); console.log("Proxy provided : ", bridgeProxyAddress); @@ -19,9 +20,12 @@ async function main() { // Perform the upgrade console.log("Performing the upgrade..."); if (process.env.FORCE_IMPORT_PROXY) { - // FORCE_IMPORT_PROXY must be the contract factory of the current implementation + // FORCE_IMPORT_PROXY must be the contract factory of the current implementation // contract version that is being used, not the version that you are planning to upgrade to. - const EthErc20FastBridgeV1 = await ethers.getContractFactory(process.env.FORCE_IMPORT_PROXY, deployer); + const EthErc20FastBridgeV1 = await ethers.getContractFactory( + process.env.FORCE_IMPORT_PROXY, + defaultAdminSigner + ); await upgrades.forceImport(bridgeProxyAddress, EthErc20FastBridgeV1); } const proxy = await upgrades.upgradeProxy( @@ -30,7 +34,7 @@ async function main() { ); await proxy.deployed(); - const currentImplAddress = await getImplementationAddress(ethers.provider, bridgeProxyAddress); + const currentImplAddress = await getImplementationAddress(ethers.provider, proxy.address); console.log("EthErc20FastBridge upgraded"); console.log("Current implementation address is ", currentImplAddress); } else if (userInput === "n") { @@ -44,7 +48,18 @@ async function main() { }); } -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); +async function upgradeFastBridge(defaultAdminSigner) { + const EthErc20FastBridge = await ethers.getContractFactory("EthErc20FastBridge", defaultAdminSigner); + const network_name = network.name; + const bridgeProxyAddress = deploymentAddress[network_name].new.bridge_proxy; + const addressesPath = path.join(__dirname, "../deployment/deploymentAddresses.json"); + const saveAddress = getAddressSaver(addressesPath, network_name, true); + const newBridge = await upgrades.upgradeProxy(bridgeProxyAddress, EthErc20FastBridge); + await newBridge.deployed(); + saveAddress("bridge_proxy", newBridge.address); + console.log("Fast-Bridge upgraded"); + const newBridgeImplementationAddress = await getImplementationAddress(ethers.provider, newBridge.address); + saveAddress("bridge_Implementation", newBridgeImplementationAddress); +} + +module.exports = { upgradeFastBridge }; diff --git a/eth/scripts/EthErc20FastBridge/whitelistTokens.js b/eth/scripts/EthErc20FastBridge/whitelistTokens.js index 0e95edf9..b84f7ccf 100644 --- a/eth/scripts/EthErc20FastBridge/whitelistTokens.js +++ b/eth/scripts/EthErc20FastBridge/whitelistTokens.js @@ -1,11 +1,11 @@ -const { ethers } = require("hardhat"); +const { ethers, network } = require("hardhat"); const deploymentAddress = require("../deployment/deploymentAddresses.json"); async function getBridgeContract() { console.log("Connecting with bridge..."); - const network = (await ethers.getDefaultProvider().getNetwork()).name; - const bridgeAddress = deploymentAddress[network].new.bridge_proxy; - const bridge = ethers.getContractAt("/contracts/EthErc20FastBridge.sol:EthErc20FastBridge", bridgeAddress); + const network_name = network.name; + const bridgeProxyAddress = deploymentAddress[network_name].new.bridge_proxy; + const bridge = ethers.getContractAt("/contracts/EthErc20FastBridge.sol:EthErc20FastBridge", bridgeProxyAddress); console.log("Connected !"); return bridge; } @@ -43,10 +43,10 @@ async function removeTokenFromWhitelist(token, signer) { } } -async function isTokenInWhitelist(token) { - let bridge; +async function isTokenInWhitelist(token, bridgeProxyAddress) { try { - bridge = await getBridgeContract(); + const bridge = ethers.getContractAt("/contracts/EthErc20FastBridge.sol:EthErc20FastBridge", bridgeProxyAddress); + (await bridge.isTokenInWhitelist(token)) ? console.log(token, "is whitelisted") : console.log(token, "is not whitelisted"); diff --git a/eth/scripts/EthErc20FastBridge/withdraw_Stuck_tokens.js b/eth/scripts/EthErc20FastBridge/withdraw_Stuck_tokens.js index 7f14553f..7aecd657 100644 --- a/eth/scripts/EthErc20FastBridge/withdraw_Stuck_tokens.js +++ b/eth/scripts/EthErc20FastBridge/withdraw_Stuck_tokens.js @@ -1,10 +1,10 @@ const { getBridge } = require("./whitelistTokens"); -async function withdrawStuckTokens(signer) { +async function withdrawStuckTokens(token, signer) { let bridge; try { bridge = await getBridge(); - await bridge.connect(signer).withdrawStuckTokens(); + await bridge.connect(signer).withdrawStuckTokens(token); } catch (error) { console.log("Failed to withdraw", error); } diff --git a/eth/scripts/deployment/deploy-bridge.js b/eth/scripts/deployment/deploy-bridge.js index 7ed2de2d..ad7b9b95 100644 --- a/eth/scripts/deployment/deploy-bridge.js +++ b/eth/scripts/deployment/deploy-bridge.js @@ -1,26 +1,34 @@ -const { ethers, upgrades } = require("hardhat"); +const { ethers, upgrades, network } = require("hardhat"); const { verify, getAddressSaver } = require("./utilities/helpers"); +const { getImplementationAddress } = require("@openzeppelin/upgrades-core"); const path = require("path"); -async function main() { +async function deploy_fast_bridge(verification) { const [deployer] = await ethers.getSigners(); - const network = (await ethers.getDefaultProvider().getNetwork()).name; + const network_name = network.name; + const addressesPath = path.join(__dirname, "./deploymentAddresses.json"); - const saveAddress = getAddressSaver(addressesPath, network, true); + const saveAddress = getAddressSaver(addressesPath, network_name, true); const tokensAddresses = Object.values(require("./deploymentAddresses.json").tokens); const whitelistedTokens = Object.values(require("./deploymentAddresses.json").whitelisted_tokens); const bridge = (await ethers.getContractFactory("EthErc20FastBridge")).connect(deployer); - let proxy = await upgrades.deployProxy(bridge, [tokensAddresses, whitelistedTokens], { - initializer: "initialize" + let proxy = await upgrades.deployProxy(bridge, [tokensAddresses, whitelistedTokens], { + initializer: "initialize" }); await proxy.deployed(); - saveAddress("bridge", proxy.address); + saveAddress("bridge_proxy", proxy.address); console.log("Deployment is completed."); + const currentImplAddress = await getImplementationAddress(ethers.provider, proxy.address); + saveAddress("bridge_Implementation", currentImplAddress); // save implementation address + + if (verification) { + // verify-contract + console.log("Verifing Contract"); + await verify(proxy.address, []); + console.log("<< Contract Verified Successfully >>."); + } } -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); +module.exports = deploy_fast_bridge; diff --git a/eth/scripts/deployment/utilities/helpers.js b/eth/scripts/deployment/utilities/helpers.js index f4f5565f..90ae22a1 100644 --- a/eth/scripts/deployment/utilities/helpers.js +++ b/eth/scripts/deployment/utilities/helpers.js @@ -1,6 +1,7 @@ const hre = require("hardhat"); const fs = require("fs"); const { ethers } = hre; +const deploymentAddress = require("../deploymentAddresses.json"); function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms));