From a624b245e09c21aa46b0a458e0c06dcd57f26e5a Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 22 Aug 2023 13:23:07 +0200 Subject: [PATCH 01/18] Add support for deploying fee token based chains --- scripts/ethcommands.ts | 40 +++++++++++++++++++++++++++++++++++++++- scripts/index.ts | 1 + scripts/package.json | 1 + scripts/tsconfig.json | 3 ++- scripts/yarn.lock | 5 +++++ test-node.bash | 21 ++++++++++++++++++--- 6 files changed, 66 insertions(+), 5 deletions(-) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index b5572f4321..7ca51f6b53 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -1,5 +1,5 @@ import { runStress } from "./stress"; -import { ethers } from "ethers"; +import { ContractFactory, ethers, Wallet } from "ethers"; import * as consts from "./consts"; import { namedAccount, namedAddress } from "./accounts"; import * as fs from "fs"; @@ -116,6 +116,44 @@ export const bridgeToL3Command = { }, }; +export const createERC20Command = { + command: "create-erc20", + describe: "creates simple ERC20 on L1", + builder: { + deployerKey: { + string: true, + describe: "account (see general help)", + default: "funnel", + }, + mintTo: { + string: true, + describe: "account (see general help)", + default: "funnel", + }, + }, + handler: async (argv: any) => { + console.log("create-erc20"); + + argv.provider = new ethers.providers.WebSocketProvider(argv.l1url); + + const contractFactory = new ContractFactory( + ERC20PresetFixedSupplyArtifact.abi, + ERC20PresetFixedSupplyArtifact.bytecode, + new Wallet( + argv.deployerKey, + argv.provider + ) + ); + const contract = await contractFactory.deploy("AppTestToken", "APP", ethers.utils.parseEther("1000000000"), namedAccount(argv.mintTo).address); + await contract.deployTransaction.wait(); + + console.log("Contract deployed at address:", contract.address); + + argv.provider.destroy(); + }, +}; + + export const sendL1Command = { command: "send-l1", describe: "sends funds between l1 accounts", diff --git a/scripts/index.ts b/scripts/index.ts index 8e5e708680..a1ef817a67 100644 --- a/scripts/index.ts +++ b/scripts/index.ts @@ -11,6 +11,7 @@ import { import { bridgeFundsCommand, bridgeToL3Command, + createERC20Command, sendL1Command, sendL2Command, sendL3Command, diff --git a/scripts/package.json b/scripts/package.json index e6ab62ec98..49e8aed877 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -7,6 +7,7 @@ "license": "Apache-2.0", "dependencies": { "@node-redis/client": "^1.0.4", + "@openzeppelin/contracts": "^4.9.3", "@types/node": "^17.0.22", "@types/yargs": "^17.0.10", "ethers": "^5.6.1", diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index c90e21b482..fc6307bc96 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -4,7 +4,8 @@ "module": "CommonJS", "strict": true, "esModuleInterop": true, - "moduleResolution": "node" + "moduleResolution": "node", + "resolveJsonModule": true }, "files": ["index.ts"] } diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 624f5bcc28..eaeb8d5cab 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -352,6 +352,11 @@ redis-parser "3.0.0" yallist "4.0.0" +"@openzeppelin/contracts@^4.9.3": + version "4.9.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" + integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== + "@types/node@^17.0.22": version "17.0.22" resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.22.tgz#38b6c4b9b2f3ed9f2e376cce42a298fb2375251e" diff --git a/test-node.bash b/test-node.bash index ae61555b9e..c56ef015a8 100755 --- a/test-node.bash +++ b/test-node.bash @@ -40,6 +40,7 @@ consensusclient=false redundantsequencers=0 dev_build_nitro=false dev_build_blockscout=false +customFeeToken=false batchposters=1 devprivkey=b6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 l1chainid=1337 @@ -99,6 +100,10 @@ while [[ $# -gt 0 ]]; do detach=true shift ;; + --fee-token) + customFeeToken=true + shift + ;; --batchposters) batchposters=$2 if ! [[ $batchposters =~ [0-3] ]] ; then @@ -136,6 +141,7 @@ while [[ $# -gt 0 ]]; do echo --init: remove all data, rebuild, deploy new rollup echo --pos: l1 is a proof-of-stake chain \(using prysm for consensus\) echo --validate: heavy computation, validating all blocks in WASM + echo --fee-token: chain is set up to use custom fee token echo --batchposters: batch posters [0-3] echo --redundantsequencers redundant sequencers [0-3] echo --detach: detach from nodes after running them @@ -300,11 +306,18 @@ if $force_init; then echo == Writing l2 chain config docker-compose run scripts write-l2-chain-config - echo == Deploying L2 sequenceraddress=`docker-compose run scripts print-address --account sequencer | tail -n 1 | tr -d '\r\n'` - docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json + deployL2Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json" + if $customFeeToken; then + echo == Deploying custom fee token + nativeTokenAddress=`docker-compose run testnode-scripts create-erc20 --deployerKey $devprivkey --mintTo user_l1user | tail -n 1 | awk '{ print $NF }'` + deployL2Command+=" --nativeERC20TokenAddress $nativeTokenAddress" + fi + echo == Deploying L2 + eval $deployL2Command docker-compose run --entrypoint sh poster -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json" + echo == Writing configs docker-compose run scripts write-config @@ -313,7 +326,9 @@ if $force_init; then echo == Funding l2 funnel docker-compose up -d $INITIAL_SEQ_NODES - docker-compose run scripts bridge-funds --ethamount 100000 --wait + if ! $customFeeToken; then + docker-compose run scripts bridge-funds --ethamount 100000 --wait + fi if $tokenbridge; then echo == Deploying token bridge From 109b7f9506f95e69c019cb2c0032f1a0dc11fb70 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 22 Aug 2023 13:29:17 +0200 Subject: [PATCH 02/18] Add missing import --- scripts/ethcommands.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index 7ca51f6b53..690a588c39 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -2,6 +2,7 @@ import { runStress } from "./stress"; import { ContractFactory, ethers, Wallet } from "ethers"; import * as consts from "./consts"; import { namedAccount, namedAddress } from "./accounts"; +import * as ERC20PresetFixedSupplyArtifact from "@openzeppelin/contracts/build/contracts/ERC20PresetFixedSupply.json"; import * as fs from "fs"; const path = require("path"); From 3c780e305b8a0f9897263c3aca88112243890427 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 22 Aug 2023 13:33:20 +0200 Subject: [PATCH 03/18] Service renamed --- test-node.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-node.bash b/test-node.bash index c56ef015a8..6256af5e11 100755 --- a/test-node.bash +++ b/test-node.bash @@ -311,7 +311,7 @@ if $force_init; then deployL2Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json" if $customFeeToken; then echo == Deploying custom fee token - nativeTokenAddress=`docker-compose run testnode-scripts create-erc20 --deployerKey $devprivkey --mintTo user_l1user | tail -n 1 | awk '{ print $NF }'` + nativeTokenAddress=`docker-compose run scripts create-erc20 --deployerKey $devprivkey --mintTo user_l1user | tail -n 1 | awk '{ print $NF }'` deployL2Command+=" --nativeERC20TokenAddress $nativeTokenAddress" fi echo == Deploying L2 From faf4fff6f89176f8c160ad847ce9f6b59bfa66b6 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 22 Aug 2023 13:35:41 +0200 Subject: [PATCH 04/18] Add missing command --- scripts/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/index.ts b/scripts/index.ts index a1ef817a67..969e104e43 100644 --- a/scripts/index.ts +++ b/scripts/index.ts @@ -30,6 +30,7 @@ async function main() { .options(stressOptions) .command(bridgeFundsCommand) .command(bridgeToL3Command) + .command(createERC20Command) .command(sendL1Command) .command(sendL2Command) .command(sendL3Command) From 441166624c54857a11c0a880f12e19d7dbeebc69 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 22 Sep 2023 19:23:57 +0200 Subject: [PATCH 05/18] Refactor how native token is provided. iAlso don't deploy token bridge in fee token mode --- test-node.bash | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/test-node.bash b/test-node.bash index 6256af5e11..af171e49bb 100755 --- a/test-node.bash +++ b/test-node.bash @@ -308,14 +308,15 @@ if $force_init; then sequenceraddress=`docker-compose run scripts print-address --account sequencer | tail -n 1 | tr -d '\r\n'` - deployL2Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json" if $customFeeToken; then echo == Deploying custom fee token nativeTokenAddress=`docker-compose run scripts create-erc20 --deployerKey $devprivkey --mintTo user_l1user | tail -n 1 | awk '{ print $NF }'` - deployL2Command+=" --nativeERC20TokenAddress $nativeTokenAddress" + else + nativeTokenAddress="0x0000000000000000000000000000000000000000" fi + echo == Deploying L2 - eval $deployL2Command + docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json --nativeTokenAddress $nativeTokenAddress docker-compose run --entrypoint sh poster -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json" echo == Writing configs @@ -328,13 +329,14 @@ if $force_init; then docker-compose up -d $INITIAL_SEQ_NODES if ! $customFeeToken; then docker-compose run scripts bridge-funds --ethamount 100000 --wait - fi - - if $tokenbridge; then - echo == Deploying token bridge - docker-compose run -e ARB_KEY=$devprivkey -e ETH_KEY=$devprivkey tokenbridge gen:network - docker-compose run --entrypoint sh tokenbridge -c "cat localNetwork.json" - echo + if $tokenbridge; then + echo == Deploying token bridge + docker-compose run -e ARB_KEY=$devprivkey -e ETH_KEY=$devprivkey tokenbridge gen:network + docker-compose run --entrypoint sh tokenbridge -c "cat localNetwork.json" + echo + fi + else + echo == Skipping token bridge deployment when cusotm fee token is used fi if $l3node; then From d188a02a708d34f6b26f32871a32a1a4d10b49c4 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Mon, 9 Oct 2023 15:49:40 +0200 Subject: [PATCH 06/18] Create native token on L2 --- scripts/ethcommands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index 690a588c39..42f2094681 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -119,7 +119,7 @@ export const bridgeToL3Command = { export const createERC20Command = { command: "create-erc20", - describe: "creates simple ERC20 on L1", + describe: "creates simple ERC20 on L2", builder: { deployerKey: { string: true, @@ -135,7 +135,7 @@ export const createERC20Command = { handler: async (argv: any) => { console.log("create-erc20"); - argv.provider = new ethers.providers.WebSocketProvider(argv.l1url); + argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); const contractFactory = new ContractFactory( ERC20PresetFixedSupplyArtifact.abi, From 782280f22c87ebcd6ed9f1025a4a8c37aa95861d Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Mon, 9 Oct 2023 15:51:21 +0200 Subject: [PATCH 07/18] Deploy L3 with fee token --- test-node.bash | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/test-node.bash b/test-node.bash index af171e49bb..e92670c130 100755 --- a/test-node.bash +++ b/test-node.bash @@ -308,15 +308,8 @@ if $force_init; then sequenceraddress=`docker-compose run scripts print-address --account sequencer | tail -n 1 | tr -d '\r\n'` - if $customFeeToken; then - echo == Deploying custom fee token - nativeTokenAddress=`docker-compose run scripts create-erc20 --deployerKey $devprivkey --mintTo user_l1user | tail -n 1 | awk '{ print $NF }'` - else - nativeTokenAddress="0x0000000000000000000000000000000000000000" - fi - echo == Deploying L2 - docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json --nativeTokenAddress $nativeTokenAddress + docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://geth:8546 --l1keystore /home/user/l1keystore --sequencerAddress $sequenceraddress --ownerAddress $sequenceraddress --l1DeployAccount $sequenceraddress --l1deployment /config/deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=$l1chainid --l2chainconfig /config/l2_chain_config.json --l2chainname arb-dev-test --l2chaininfo /config/deployed_chain_info.json docker-compose run --entrypoint sh poster -c "jq [.[]] /config/deployed_chain_info.json > /config/l2_chain_info.json" echo == Writing configs @@ -327,16 +320,12 @@ if $force_init; then echo == Funding l2 funnel docker-compose up -d $INITIAL_SEQ_NODES - if ! $customFeeToken; then - docker-compose run scripts bridge-funds --ethamount 100000 --wait - if $tokenbridge; then - echo == Deploying token bridge - docker-compose run -e ARB_KEY=$devprivkey -e ETH_KEY=$devprivkey tokenbridge gen:network - docker-compose run --entrypoint sh tokenbridge -c "cat localNetwork.json" - echo - fi - else - echo == Skipping token bridge deployment when cusotm fee token is used + docker-compose run scripts bridge-funds --ethamount 100000 --wait + if $tokenbridge; then + echo == Deploying token bridge + docker-compose run -e ARB_KEY=$devprivkey -e ETH_KEY=$devprivkey tokenbridge gen:network + docker-compose run --entrypoint sh tokenbridge -c "cat localNetwork.json" + echo fi if $l3node; then @@ -354,16 +343,24 @@ if $force_init; then echo == Deploying L3 l3owneraddress=`docker-compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` - l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'` - docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json + deployL3Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json" + if $customFeeToken; then + echo == Deploying custom fee token + nativeTokenAddress=`docker-compose run scripts create-erc20 --deployerKey $devprivkey --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` + deployL3Command+=" --nativeTokenAddress $nativeTokenAddress" + fi + + eval $deployL3Command docker-compose run --entrypoint sh poster -c "jq [.[]] /config/deployed_l3_chain_info.json > /config/l3_chain_info.json" echo == Funding l3 funnel docker-compose up -d l3node poster - docker-compose run scripts bridge-to-l3 --ethamount 50000 --wait + if ! $customFeeToken; then + docker-compose run scripts bridge-to-l3 --ethamount 50000 --wait + fi fi fi From 2f8969b7144598c5447e5a24e559c7774816d8c1 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 10 Oct 2023 14:47:12 +0200 Subject: [PATCH 08/18] Provide maxDataSize --- test-node.bash | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-node.bash b/test-node.bash index f1848225cb..ff32296859 100755 --- a/test-node.bash +++ b/test-node.bash @@ -345,7 +345,7 @@ if $force_init; then l3owneraddress=`docker-compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'` - deployL3Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json" + deployL3Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857" if $customFeeToken; then echo == Deploying custom fee token nativeTokenAddress=`docker-compose run scripts create-erc20 --deployerKey $devprivkey --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` From 82a072dde9f82ac57bd9ff4306dae7c36c980dba Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 13 Oct 2023 10:25:42 +0200 Subject: [PATCH 09/18] Use different deployers to have consistent addresses --- scripts/ethcommands.ts | 15 ++++++++------- test-node.bash | 6 ++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index 42f2094681..d0832b7787 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -121,29 +121,30 @@ export const createERC20Command = { command: "create-erc20", describe: "creates simple ERC20 on L2", builder: { - deployerKey: { + deployer: { string: true, describe: "account (see general help)", - default: "funnel", + default: "user_l2user", }, mintTo: { string: true, describe: "account (see general help)", - default: "funnel", + default: "user_l2user", }, }, handler: async (argv: any) => { console.log("create-erc20"); argv.provider = new ethers.providers.WebSocketProvider(argv.l2url); + const deployerWallet = new Wallet( + ethers.utils.sha256(ethers.utils.toUtf8Bytes(argv.deployer)), + argv.provider + ); const contractFactory = new ContractFactory( ERC20PresetFixedSupplyArtifact.abi, ERC20PresetFixedSupplyArtifact.bytecode, - new Wallet( - argv.deployerKey, - argv.provider - ) + deployerWallet ); const contract = await contractFactory.deploy("AppTestToken", "APP", ethers.utils.parseEther("1000000000"), namedAccount(argv.mintTo).address); await contract.deployTransaction.wait(); diff --git a/test-node.bash b/test-node.bash index ff32296859..1cb97d7414 100755 --- a/test-node.bash +++ b/test-node.bash @@ -336,7 +336,9 @@ if $force_init; then echo == create l2 traffic docker-compose run scripts send-l2 --ethamount 100 --to user_l2user --wait - docker-compose run scripts send-l2 --ethamount 0.0001 --from user_l2user --to user_l2user_b --wait --delay 500 --times 500 > /dev/null & + docker-compose run scripts send-l2 --ethamount 100 --to user_l2user_b --wait + docker-compose run scripts send-l2 --ethamount 100 --to user_l2user_c --wait + docker-compose run scripts send-l2 --ethamount 0.0001 --from user_l2user_c --to user_l2user_b --wait --delay 500 --times 500 > /dev/null & echo == Writing l3 chain config docker-compose run scripts write-l3-chain-config @@ -348,7 +350,7 @@ if $force_init; then deployL3Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857" if $customFeeToken; then echo == Deploying custom fee token - nativeTokenAddress=`docker-compose run scripts create-erc20 --deployerKey $devprivkey --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` + nativeTokenAddress=`docker-compose run scripts create-erc20 --deployer user_l2user_b --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` deployL3Command+=" --nativeTokenAddress $nativeTokenAddress" fi From 9f2bd4b0743ad111a050371b4c5233744f0e4622 Mon Sep 17 00:00:00 2001 From: ganeshvanahalli Date: Fri, 13 Oct 2023 14:03:25 -0500 Subject: [PATCH 10/18] initialize required config fields wrt current nitro --- scripts/config.ts | 145 +++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 71 deletions(-) diff --git a/scripts/config.ts b/scripts/config.ts index 044f0d6177..f82c3314de 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -32,7 +32,7 @@ DEPOSIT_CONTRACT_ADDRESS: 0x4242424242424242424242424242424242424242 } function writeGethGenesisConfig(argv: any) { - const gethConfig = ` + const gethConfig = ` { "config": { "ChainName": "l1_chain", @@ -152,10 +152,10 @@ function writeGethGenesisConfig(argv: any) { function writeConfigs(argv: any) { const valJwtSecret = path.join(consts.configpath, "val_jwt.hex") - const chainInfoFile = path.join(consts.configpath, "l2_chain_info.json") + const chainInfoFile = path.join(consts.configpath, "l2_chain_info.json") const baseConfig = { "parent-chain": { - "connection" : { + "connection": { "url": argv.l1url, }, "wallet": { @@ -169,8 +169,6 @@ function writeConfigs(argv: any) { "info-files": [chainInfoFile], }, "node": { - "archive": true, - "forwarding-target": "null", "staker": { "dangerous": { "without-block-validator": false @@ -181,11 +179,9 @@ function writeConfigs(argv: any) { "make-assertion-interval": "10s", "strategy": "MakeNodes", }, - "sequencer": { - "enable": false, - "dangerous": { - "no-coordinator": false - } + "sequencer": false, + "dangerous": { + "no-sequencer-coordinator": false }, "delayed-sequencer": { "enable": false @@ -206,18 +202,23 @@ function writeConfigs(argv: any) { "max-delay": "30s", "data-poster": { "redis-signer": { - "signing-key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" + "signing-key": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" }, "wait-for-l1-finality": false } }, "block-validator": { - "validation-server" : { - "url": argv.validationNodeUrl, - "jwtsecret": valJwtSecret, - } + "validation-server": { + "url": argv.validationNodeUrl, + "jwtsecret": valJwtSecret, + } } }, + "execution": { + "sequencer": { + "enable": false, + }, + }, "persistent": { "chain": "local" }, @@ -246,8 +247,9 @@ function writeConfigs(argv: any) { fs.writeFileSync(path.join(consts.configpath, "unsafe_staker_config.json"), JSON.stringify(unsafeStakerConfig)) let sequencerConfig = JSON.parse(baseConfJSON) - sequencerConfig.node.sequencer.enable = true + sequencerConfig.node.sequencer = true sequencerConfig.node["seq-coordinator"].enable = true + sequencerConfig.execution["sequencer"].enable = true sequencerConfig.node["delayed-sequencer"].enable = true fs.writeFileSync(path.join(consts.configpath, "sequencer_config.json"), JSON.stringify(sequencerConfig)) @@ -258,15 +260,16 @@ function writeConfigs(argv: any) { fs.writeFileSync(path.join(consts.configpath, "poster_config.json"), JSON.stringify(posterConfig)) let l3Config = JSON.parse(baseConfJSON) - l3Config["parent-chain"].connection.url = argv.l2url + l3Config["parent-chain"].connection.url = argv.l2url l3Config["parent-chain"].wallet.account = namedAccount("l3sequencer").address l3Config.chain.id = 333333 const l3ChainInfoFile = path.join(consts.configpath, "l3_chain_info.json") l3Config.chain["info-files"] = [l3ChainInfoFile] l3Config.node.staker.enable = true l3Config.node.staker["use-smart-contract-wallet"] = true - l3Config.node.sequencer.enable = true - l3Config.node.sequencer.dangerous["no-coordinator"] = true + l3Config.node.sequencer = true + l3Config.execution["sequencer"].enable = true + l3Config.node["dangerous"]["no-sequencer-coordinator"] = true l3Config.node["delayed-sequencer"].enable = true l3Config.node["batch-poster"].enable = true l3Config.node["batch-poster"]["redis-url"] = "" @@ -296,32 +299,32 @@ function writeConfigs(argv: any) { function writeL2ChainConfig(argv: any) { const l2ChainConfig = { - "chainId": 412346, - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "clique": { - "period": 0, - "epoch": 0 - }, - "arbitrum": { - "EnableArbOS": true, - "AllowDebugPrecompiles": true, - "DataAvailabilityCommittee": false, - "InitialArbOSVersion": 11, - "InitialChainOwner": argv.l2owner, - "GenesisBlockNum": 0 - } + "chainId": 412346, + "homesteadBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "clique": { + "period": 0, + "epoch": 0 + }, + "arbitrum": { + "EnableArbOS": true, + "AllowDebugPrecompiles": true, + "DataAvailabilityCommittee": false, + "InitialArbOSVersion": 11, + "InitialChainOwner": argv.l2owner, + "GenesisBlockNum": 0 + } } const l2ChainConfigJSON = JSON.stringify(l2ChainConfig) fs.writeFileSync(path.join(consts.configpath, "l2_chain_config.json"), l2ChainConfigJSON) @@ -329,32 +332,32 @@ function writeL2ChainConfig(argv: any) { function writeL3ChainConfig(argv: any) { const l3ChainConfig = { - "chainId": 333333, - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "clique": { - "period": 0, - "epoch": 0 - }, - "arbitrum": { - "EnableArbOS": true, - "AllowDebugPrecompiles": true, - "DataAvailabilityCommittee": false, - "InitialArbOSVersion": 11, - "InitialChainOwner": "0x0000000000000000000000000000000000000000", - "GenesisBlockNum": 0 - } + "chainId": 333333, + "homesteadBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "clique": { + "period": 0, + "epoch": 0 + }, + "arbitrum": { + "EnableArbOS": true, + "AllowDebugPrecompiles": true, + "DataAvailabilityCommittee": false, + "InitialArbOSVersion": 11, + "InitialChainOwner": "0x0000000000000000000000000000000000000000", + "GenesisBlockNum": 0 + } } const l3ChainConfigJSON = JSON.stringify(l3ChainConfig) fs.writeFileSync(path.join(consts.configpath, "l3_chain_config.json"), l3ChainConfigJSON) From f6306a59e05e44deeb893049232877bbb8ea6112 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Thu, 19 Oct 2023 13:57:13 +0200 Subject: [PATCH 11/18] Rename fee token flag, exit script if L3 node is not being deployed --- test-node.bash | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test-node.bash b/test-node.bash index 44fd19621c..c82364bfd4 100755 --- a/test-node.bash +++ b/test-node.bash @@ -40,7 +40,7 @@ consensusclient=false redundantsequencers=0 dev_build_nitro=false dev_build_blockscout=false -customFeeToken=false +l3CustomFeeToken=false batchposters=1 devprivkey=b6b15c8cb491557369f3c7d2c287b053eb229daa9c22138887752191c9520659 l1chainid=1337 @@ -100,10 +100,6 @@ while [[ $# -gt 0 ]]; do detach=true shift ;; - --fee-token) - customFeeToken=true - shift - ;; --batchposters) batchposters=$2 if ! [[ $batchposters =~ [0-3] ]] ; then @@ -122,6 +118,14 @@ while [[ $# -gt 0 ]]; do l3node=true shift ;; + --l3-fee-token) + if ! $l3node; then + echo "Error: --l3-fee-token requires --l3node to be provided." + exit 1 + fi + l3CustomFeeToken=true + shift + ;; --redundantsequencers) redundantsequencers=$2 if ! [[ $redundantsequencers =~ [0-3] ]] ; then @@ -141,7 +145,7 @@ while [[ $# -gt 0 ]]; do echo --init: remove all data, rebuild, deploy new rollup echo --pos: l1 is a proof-of-stake chain \(using prysm for consensus\) echo --validate: heavy computation, validating all blocks in WASM - echo --fee-token: chain is set up to use custom fee token + echo --l3-fee-token: L3 chain is set up to use custom fee token. Only valid if also '--l3node' is provided echo --batchposters: batch posters [0-3] echo --redundantsequencers redundant sequencers [0-3] echo --detach: detach from nodes after running them @@ -350,7 +354,7 @@ if $force_init; then l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'` deployL3Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857" - if $customFeeToken; then + if $l3CustomFeeToken; then echo == Deploying custom fee token nativeTokenAddress=`docker-compose run scripts create-erc20 --deployer user_l2user_b --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` deployL3Command+=" --nativeTokenAddress $nativeTokenAddress" @@ -362,7 +366,7 @@ if $force_init; then echo == Funding l3 funnel and dev key docker-compose up -d l3node poster - if ! $customFeeToken; then + if ! $l3CustomFeeToken; then docker-compose run scripts bridge-to-l3 --ethamount 50000 --wait docker-compose run scripts bridge-to-l3 --ethamount 500 --wait --from "key_0x$devprivkey" fi From 1e2a56d2775c3d398058aff8c08a8743523f52ba Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 20 Oct 2023 10:38:17 +0200 Subject: [PATCH 12/18] Don't use eval --- test-node.bash | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test-node.bash b/test-node.bash index c82364bfd4..ed94248526 100755 --- a/test-node.bash +++ b/test-node.bash @@ -349,17 +349,17 @@ if $force_init; then echo == Writing l3 chain config docker-compose run scripts write-l3-chain-config - echo == Deploying L3 - l3owneraddress=`docker-compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` - l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'` - - deployL3Command="docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857" if $l3CustomFeeToken; then echo == Deploying custom fee token nativeTokenAddress=`docker-compose run scripts create-erc20 --deployer user_l2user_b --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` - deployL3Command+=" --nativeTokenAddress $nativeTokenAddress" + EXTRA_L3_DEPLOY_FLAG="--nativeTokenAddress $nativeTokenAddress" fi + echo == Deploying L3 + l3owneraddress=`docker-compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` + l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'` + docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857 $EXTRA_L3_DEPLOY_FLAG + eval $deployL3Command docker-compose run --entrypoint sh poster -c "jq [.[]] /config/deployed_l3_chain_info.json > /config/l3_chain_info.json" From 11ed8e9d4ff845826e055d6e7b2385508e2fdb42 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 20 Oct 2023 11:24:48 +0200 Subject: [PATCH 13/18] Rename test accounts --- test-node.bash | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test-node.bash b/test-node.bash index ed94248526..ba2b832d34 100755 --- a/test-node.bash +++ b/test-node.bash @@ -339,19 +339,20 @@ if $force_init; then docker-compose run scripts send-l2 --ethamount 1000 --to l3owner --wait docker-compose run scripts send-l2 --ethamount 1000 --to l3sequencer --wait + echo == Funding l2 deployers + docker-compose run scripts send-l2 --ethamount 100 --to user_token_bridge_deployer --wait + docker-compose run scripts send-l2 --ethamount 100 --to user_fee_token_deployer --wait echo == create l2 traffic - docker-compose run scripts send-l2 --ethamount 100 --to user_l2user --wait - docker-compose run scripts send-l2 --ethamount 100 --to user_l2user_b --wait - docker-compose run scripts send-l2 --ethamount 100 --to user_l2user_c --wait - docker-compose run scripts send-l2 --ethamount 0.0001 --from user_l2user_c --to user_l2user_b --wait --delay 500 --times 500 > /dev/null & + docker-compose run scripts send-l2 --ethamount 100 --to user_traffic_generator --wait + docker-compose run scripts send-l2 --ethamount 0.0001 --from user_traffic_generator --to user_fee_token_deployer --wait --delay 500 --times 500 > /dev/null & echo == Writing l3 chain config docker-compose run scripts write-l3-chain-config if $l3CustomFeeToken; then echo == Deploying custom fee token - nativeTokenAddress=`docker-compose run scripts create-erc20 --deployer user_l2user_b --mintTo user_l2user | tail -n 1 | awk '{ print $NF }'` + nativeTokenAddress=`docker-compose run scripts create-erc20 --deployer user_fee_token_deployer --mintTo user_token_bridge_deployer | tail -n 1 | awk '{ print $NF }'` EXTRA_L3_DEPLOY_FLAG="--nativeTokenAddress $nativeTokenAddress" fi From 11170fe36318991973bea632d9f348816a64a974 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 20 Oct 2023 13:06:00 +0200 Subject: [PATCH 14/18] Update L3 config so that finalization of L2 delayed msgs is not required --- scripts/config.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/config.ts b/scripts/config.ts index f82c3314de..9aa1045914 100644 --- a/scripts/config.ts +++ b/scripts/config.ts @@ -271,6 +271,8 @@ function writeConfigs(argv: any) { l3Config.execution["sequencer"].enable = true l3Config.node["dangerous"]["no-sequencer-coordinator"] = true l3Config.node["delayed-sequencer"].enable = true + l3Config.node["delayed-sequencer"]["finalize-distance"] = 0 + l3Config.node["delayed-sequencer"]["require-full-finality"] = false l3Config.node["batch-poster"].enable = true l3Config.node["batch-poster"]["redis-url"] = "" fs.writeFileSync(path.join(consts.configpath, "l3node_config.json"), JSON.stringify(l3Config)) From d4e23402d8d8dcefacb40fac73b1d5fd39bdbf24 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 20 Oct 2023 16:52:06 +0200 Subject: [PATCH 15/18] Remove leftover --- test-node.bash | 2 -- 1 file changed, 2 deletions(-) diff --git a/test-node.bash b/test-node.bash index ba2b832d34..355d622add 100755 --- a/test-node.bash +++ b/test-node.bash @@ -360,8 +360,6 @@ if $force_init; then l3owneraddress=`docker-compose run scripts print-address --account l3owner | tail -n 1 | tr -d '\r\n'` l3sequenceraddress=`docker-compose run scripts print-address --account l3sequencer | tail -n 1 | tr -d '\r\n'` docker-compose run --entrypoint /usr/local/bin/deploy poster --l1conn ws://sequencer:8548 --l1keystore /home/user/l1keystore --sequencerAddress $l3sequenceraddress --ownerAddress $l3owneraddress --l1DeployAccount $l3owneraddress --l1deployment /config/l3deployment.json --authorizevalidators 10 --wasmrootpath /home/user/target/machines --l1chainid=412346 --l2chainconfig /config/l3_chain_config.json --l2chainname orbit-dev-test --l2chaininfo /config/deployed_l3_chain_info.json --maxDataSize 104857 $EXTRA_L3_DEPLOY_FLAG - - eval $deployL3Command docker-compose run --entrypoint sh poster -c "jq [.[]] /config/deployed_l3_chain_info.json > /config/l3_chain_info.json" echo == Funding l3 funnel and dev key From 51ebfd5377e4af809dd601426d7d816fdd059448 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 27 Oct 2023 12:45:50 +0200 Subject: [PATCH 16/18] Fix BigNUmber comparison --- scripts/ethcommands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index d0832b7787..a3157e32be 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -44,7 +44,7 @@ async function bridgeFunds(argv: any, parentChainUrl: string, chainUrl: string, const sleep = (ms: number) => new Promise(r => setTimeout(r, ms)); while (true) { const balance = await account.getBalance() - if (balance >= ethers.utils.parseEther(argv.ethamount)) { + if (balance.gt(ethers.utils.parseEther(argv.ethamount))) { return } await sleep(100) From 3a7b2cee29cf591cc4c3f6c5ddc00bf5be367bd9 Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Fri, 27 Oct 2023 13:41:01 +0200 Subject: [PATCH 17/18] Mint fee tokens to funnel account to use for retryable fees --- scripts/ethcommands.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index a3157e32be..11386af4fc 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -44,7 +44,7 @@ async function bridgeFunds(argv: any, parentChainUrl: string, chainUrl: string, const sleep = (ms: number) => new Promise(r => setTimeout(r, ms)); while (true) { const balance = await account.getBalance() - if (balance.gt(ethers.utils.parseEther(argv.ethamount))) { + if (balance.gte(ethers.utils.parseEther(argv.ethamount))) { return } await sleep(100) @@ -149,6 +149,11 @@ export const createERC20Command = { const contract = await contractFactory.deploy("AppTestToken", "APP", ethers.utils.parseEther("1000000000"), namedAccount(argv.mintTo).address); await contract.deployTransaction.wait(); + // transfer some tokens to funnel account + const mintTo = namedAccount(argv.mintTo).connect(argv.provider); + const funnel = namedAccount("funnel"); + await contract.connect(mintTo).transfer(funnel.address, ethers.utils.parseEther("200000000")); + console.log("Contract deployed at address:", contract.address); argv.provider.destroy(); From fe900a5ae2f4dbcb769e717b86a5818ba129619a Mon Sep 17 00:00:00 2001 From: Goran Vladika Date: Tue, 31 Oct 2023 12:39:00 +0100 Subject: [PATCH 18/18] Mint tokens to initial receiver only --- scripts/ethcommands.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/ethcommands.ts b/scripts/ethcommands.ts index 11386af4fc..7442fb4764 100644 --- a/scripts/ethcommands.ts +++ b/scripts/ethcommands.ts @@ -149,11 +149,6 @@ export const createERC20Command = { const contract = await contractFactory.deploy("AppTestToken", "APP", ethers.utils.parseEther("1000000000"), namedAccount(argv.mintTo).address); await contract.deployTransaction.wait(); - // transfer some tokens to funnel account - const mintTo = namedAccount(argv.mintTo).connect(argv.provider); - const funnel = namedAccount("funnel"); - await contract.connect(mintTo).transfer(funnel.address, ethers.utils.parseEther("200000000")); - console.log("Contract deployed at address:", contract.address); argv.provider.destroy();