From 1b60ecc1f50d318023c6735243a0064b2962ffc5 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Wed, 2 Aug 2023 16:32:08 -0500 Subject: [PATCH 01/24] feat : add error msg when invalid private key --- packages/foundry/script/Deploy.s.sol | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/foundry/script/Deploy.s.sol b/packages/foundry/script/Deploy.s.sol index 4fe248469..de140534c 100644 --- a/packages/foundry/script/Deploy.s.sol +++ b/packages/foundry/script/Deploy.s.sol @@ -5,9 +5,15 @@ import "../contracts/YourContract.sol"; import "./DeployHelpers.s.sol"; contract DeployScript is ScaffoldETHDeploy { + error InvalidPrivateKey(string); + function run() external { uint256 deployerPrivateKey = setupLocalhostEnv(); - + if (deployerPrivateKey == 0) { + revert InvalidPrivateKey( + "Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new key" + ); + } vm.startBroadcast(deployerPrivateKey); YourContract yourContract = new YourContract( vm.addr(deployerPrivateKey) From 9cd4439536545c0209e9294274ba2a647b8bd5c7 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Wed, 2 Aug 2023 17:20:26 -0500 Subject: [PATCH 02/24] feat : simulate hardhat way --network on deploy --- packages/foundry/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/foundry/package.json b/packages/foundry/package.json index f5fdea96a..de953217e 100644 --- a/packages/foundry/package.json +++ b/packages/foundry/package.json @@ -7,8 +7,8 @@ "fork": "anvil --fork-url ${0:-mainnet} --config-out localhost.json", "compile": "forge compile", "generate": "node script/generateAccount.js", - "deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${0:-default_network} --broadcast && node script/generateTsAbis.js", - "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${0:-default_network} --broadcast --verify && node script/generateTsAbis.js", + "deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast && node script/generateTsAbis.js", + "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --verify && node script/generateTsAbis.js", "lint": "forge fmt", "test": "forge test" }, From 02157e2b5fbba83f20232cee77d31fbda009e13a Mon Sep 17 00:00:00 2001 From: CarlosR Date: Wed, 2 Aug 2023 18:16:24 -0500 Subject: [PATCH 03/24] feat : find network name in foundry.toml --- packages/foundry/package.json | 4 +- packages/foundry/script/Deploy.s.sol | 3 -- packages/foundry/script/DeployHelpers.s.sol | 47 +++++++++++---------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/packages/foundry/package.json b/packages/foundry/package.json index de953217e..68ee14f1b 100644 --- a/packages/foundry/package.json +++ b/packages/foundry/package.json @@ -7,8 +7,8 @@ "fork": "anvil --fork-url ${0:-mainnet} --config-out localhost.json", "compile": "forge compile", "generate": "node script/generateAccount.js", - "deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast && node script/generateTsAbis.js", - "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --verify && node script/generateTsAbis.js", + "deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy && node script/generateTsAbis.js", + "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --verify && node script/generateTsAbis.js", "lint": "forge fmt", "test": "forge test" }, diff --git a/packages/foundry/script/Deploy.s.sol b/packages/foundry/script/Deploy.s.sol index de140534c..0c1c0fc05 100644 --- a/packages/foundry/script/Deploy.s.sol +++ b/packages/foundry/script/Deploy.s.sol @@ -32,9 +32,6 @@ contract DeployScript is ScaffoldETHDeploy { * This function should be called last. */ exportDeployments(); - - // If your chain is not present in foundry's stdChain, then you need to call function with chainName: - // exportDeployments("chiado") } function test() public {} diff --git a/packages/foundry/script/DeployHelpers.s.sol b/packages/foundry/script/DeployHelpers.s.sol index 5ea27e077..824d007dc 100644 --- a/packages/foundry/script/DeployHelpers.s.sol +++ b/packages/foundry/script/DeployHelpers.s.sol @@ -5,6 +5,8 @@ import "forge-std/Script.sol"; import "forge-std/Vm.sol"; contract ScaffoldETHDeploy is Script { + error InvalidChain(); + struct Deployment { string name; address addr; @@ -49,34 +51,33 @@ contract ScaffoldETHDeploy is Script { ); } - string memory chainName = getChain(block.chainid).name; + string memory chainName; + + try this.getChain() returns (Chain memory chain) { + chainName = chain.name; + } catch { + chainName = findChainName(); + } jsonWrite = vm.serializeString(jsonWrite, "networkName", chainName); vm.writeJson(jsonWrite, path); } - function exportDeployments(string memory customChainName) internal { - // fetch already existing contracts - root = vm.projectRoot(); - path = string.concat(root, "/deployments/"); - string memory chainIdStr = vm.toString(block.chainid); - path = string.concat(path, string.concat(chainIdStr, ".json")); - - string memory jsonWrite; - - uint256 len = deployments.length; + function getChain() public returns (Chain memory) { + return getChain(block.chainid); + } - for (uint256 i = 0; i < len; i++) { - vm.serializeString( - jsonWrite, - vm.toString(deployments[i].addr), - deployments[i].name - ); + function findChainName() public returns (string memory) { + uint256 thisChainId = block.chainid; + string[2][] memory allRpcUrls = vm.rpcUrls(); + for (uint256 i = 0; i < allRpcUrls.length; i++) { + try vm.createSelectFork(allRpcUrls[i][1]) { + if (block.chainid == thisChainId) { + return allRpcUrls[i][0]; + } + } catch { + continue; + } } - jsonWrite = vm.serializeString( - jsonWrite, - "networkName", - customChainName - ); - vm.writeJson(jsonWrite, path); + revert InvalidChain(); } } From 9ad78cbda471a074cbc2d72cd747df60abf0070b Mon Sep 17 00:00:00 2001 From: CarlosR Date: Thu, 3 Aug 2023 08:45:58 -0500 Subject: [PATCH 04/24] chor : change error msg in script --- packages/foundry/script/Deploy.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/foundry/script/Deploy.s.sol b/packages/foundry/script/Deploy.s.sol index 0c1c0fc05..48a156512 100644 --- a/packages/foundry/script/Deploy.s.sol +++ b/packages/foundry/script/Deploy.s.sol @@ -11,7 +11,7 @@ contract DeployScript is ScaffoldETHDeploy { uint256 deployerPrivateKey = setupLocalhostEnv(); if (deployerPrivateKey == 0) { revert InvalidPrivateKey( - "Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new key" + "You don't have a deployer account. Make sure you have set DEPLOYER_PRIVATE_KEY in .env or use `yarn generate` to generate a new random account" ); } vm.startBroadcast(deployerPrivateKey); From b2c7c30175776f1fb5b78bdc27b43fa07994605d Mon Sep 17 00:00:00 2001 From: CarlosR Date: Thu, 3 Aug 2023 10:53:10 -0500 Subject: [PATCH 05/24] forge install: openzeppelin-contracts v4.9.3 --- .gitmodules | 3 +++ packages/foundry/lib/openzeppelin-contracts | 1 + 2 files changed, 4 insertions(+) create mode 160000 packages/foundry/lib/openzeppelin-contracts diff --git a/.gitmodules b/.gitmodules index 7f935dbc8..583bbd267 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,3 +3,6 @@ url = https://github.com/foundry-rs/forge-std [submodule "lib/forge-std"] branch = v1.5.5 +[submodule "packages/foundry/lib/openzeppelin-contracts"] + path = packages/foundry/lib/openzeppelin-contracts + url = https://github.com/openzeppelin/openzeppelin-contracts diff --git a/packages/foundry/lib/openzeppelin-contracts b/packages/foundry/lib/openzeppelin-contracts new file mode 160000 index 000000000..fd81a96f0 --- /dev/null +++ b/packages/foundry/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit fd81a96f01cc42ef1c9a5399364968d0e07e9e90 From 7030a2fc8fe99550a1b624c847ecb8bc2c20679e Mon Sep 17 00:00:00 2001 From: CarlosR Date: Thu, 3 Aug 2023 10:54:12 -0500 Subject: [PATCH 06/24] add remappings --- packages/foundry/remappings.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 packages/foundry/remappings.txt diff --git a/packages/foundry/remappings.txt b/packages/foundry/remappings.txt new file mode 100644 index 000000000..d969660d3 --- /dev/null +++ b/packages/foundry/remappings.txt @@ -0,0 +1,10 @@ +ds-test/=lib/forge-std/lib/ds-test/src/ +erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ +forge-std/=lib/forge-std/src/ +openzeppelin-contracts/=lib/openzeppelin-contracts/ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts +lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/ +lib/openzeppelin-contracts:ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/ +lib/openzeppelin-contracts:erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ +lib/openzeppelin-contracts:forge-std/=lib/openzeppelin-contracts/lib/forge-std/src/ +lib/openzeppelin-contracts:openzeppelin/=lib/openzeppelin-contracts/contracts/ From 720fcca3068108c4cc8aa9f88b008bb33bd1bd2d Mon Sep 17 00:00:00 2001 From: CarlosR Date: Mon, 7 Aug 2023 11:13:08 -0500 Subject: [PATCH 07/24] chor : clean up remappings --- packages/foundry/remappings.txt | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/foundry/remappings.txt b/packages/foundry/remappings.txt index d969660d3..273f2dd6e 100644 --- a/packages/foundry/remappings.txt +++ b/packages/foundry/remappings.txt @@ -1,10 +1 @@ -ds-test/=lib/forge-std/lib/ds-test/src/ -erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ -forge-std/=lib/forge-std/src/ -openzeppelin-contracts/=lib/openzeppelin-contracts/ -@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts -lib/forge-std:ds-test/=lib/forge-std/lib/ds-test/src/ -lib/openzeppelin-contracts:ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/ -lib/openzeppelin-contracts:erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/ -lib/openzeppelin-contracts:forge-std/=lib/openzeppelin-contracts/lib/forge-std/src/ -lib/openzeppelin-contracts:openzeppelin/=lib/openzeppelin-contracts/contracts/ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts \ No newline at end of file From e19e9ceda6f6b67b64e0876ff9501e8e7207899a Mon Sep 17 00:00:00 2001 From: CarlosR Date: Mon, 7 Aug 2023 11:16:08 -0500 Subject: [PATCH 08/24] merge conflict --- .gitmodules | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6e6a6bd46..fdf71eafc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,8 +5,4 @@ branch = v1.5.5 [submodule "packages/foundry/lib/openzeppelin-contracts"] path = packages/foundry/lib/openzeppelin-contracts -<<<<<<< HEAD - url = https://github.com/openzeppelin/openzeppelin-contracts -======= - url = https://github.com/OpenZeppelin/openzeppelin-contracts ->>>>>>> upstream/foundry + url = https://github.com/openzeppelin/openzeppelin-contracts \ No newline at end of file From 4eda578b1512e0933a0a085ee01eddeefd7e56cb Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Tue, 8 Aug 2023 12:51:35 +0530 Subject: [PATCH 09/24] update OZ gh URL to use capitalize O --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index fdf71eafc..e0c28cd58 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,4 @@ branch = v1.5.5 [submodule "packages/foundry/lib/openzeppelin-contracts"] path = packages/foundry/lib/openzeppelin-contracts - url = https://github.com/openzeppelin/openzeppelin-contracts \ No newline at end of file + url = https://github.com/Openzeppelin/openzeppelin-contracts From f8906faa26d290409d5a8d334b36e20edd503248 Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Tue, 8 Aug 2023 14:00:34 +0530 Subject: [PATCH 10/24] update readme --- README.md | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1fa8d5eec..a0aa39223 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Before you begin, you need to install the following tools: - [Node (v18 LTS)](https://nodejs.org/en/download/) - Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install)) - [Git](https://git-scm.com/downloads) +- [Foundryup](https://book.getfoundry.sh/getting-started/installation) ## Quickstart @@ -43,7 +44,7 @@ yarn install foundryup ``` -2. Create your .env file +2. Create your `.env` file inside `packages/foundry`: ``` (echo "DEPLOYER_PRIVATE_KEY="; echo "ALCHEMY_API_KEY=oKxs-03sij-U_N0iOlrSsZFr29-IqbuF"; echo "ETHERSCAN_API_KEY=DNXJA8RX2Q3VZ4URQIWP7Z68CJXQZSC6AW") >> packages/foundry/.env @@ -85,18 +86,41 @@ Once you are ready to deploy your smart contracts, there are a few things you ne 1. Select the network -By default, `yarn deploy` will deploy the contract to the local network. You can change the defaultNetwork in `packages/foundry/foundry.toml`. +By default, `yarn deploy` will deploy the contract to the local network. You can change the defaultNetwork in `packages/foundry/foundry.toml`.You could also simply run `yarn deploy --network target_network` to deploy to another network -Check the `foundry.toml` for the networks that are pre-configured. You can also add other network settings to the `foundry.toml file`. Here are the [Alchemy docs](https://docs.alchemy.com/docs/how-to-add-alchemy-rpc-endpoints-to-metamask) for information on specific networks. +Check the `foundry.toml` for the networks that are pre-configured. You can also add other network settings to the `foundry.toml`. Here are the [Alchemy docs](https://docs.alchemy.com/docs/how-to-add-alchemy-rpc-endpoints-to-metamask) for information on specific networks. + +Example: To deploy the contract to the Sepolia network, run the command below: + +``` +yarn deploy --network sepolia +``` + +2. Generate a new account or add one to deploy the contract(s) from. Additionally you will need to add your Alchemy API key. Rename `.env.example` to `.env` and fill the required keys. + +``` +ALCHEMY_API_KEY="", +DEPLOYER_PRIVATE_KEY="" +``` The deployer account is the account that will deploy your contracts. Additionally, the deployer account will be used to execute any function calls that are part of your deployment script. You can generate a random account / private key with `yarn generate` or add the private key of your crypto wallet. `yarn generate` will create a random account and add the `DEPLOYER_PRIVATE_KEY` to the `.env` file. You can check the generated account with `yarn account`. -2. To deploy and verify : +3. Deploy your smart contract(s) + +Run the command below to deploy the smart contract to the target network. Make sure to have some funds in your deployer account to pay for the transaction. + +``` +yarn deploy --network network_name +``` + +4. Deploy and verify your smart contract(s) + +You can deploy & verify your smart contract on Etherscan by running: ``` -yarn deploy:verify +yarn deploy:verify --network network_name ``` ## Deploying your NextJS App From d3a177d9ede4171c043c9b350ea17b97c0494bd9 Mon Sep 17 00:00:00 2001 From: Shiv Bhonde Date: Tue, 8 Aug 2023 14:06:29 +0530 Subject: [PATCH 11/24] update OZ gitmodule name to match org name --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index e0c28cd58..d78ff238b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,4 @@ branch = v1.5.5 [submodule "packages/foundry/lib/openzeppelin-contracts"] path = packages/foundry/lib/openzeppelin-contracts - url = https://github.com/Openzeppelin/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts From 697613518415e01c9a4351574e190200eb6ba385 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Sun, 13 Aug 2023 21:09:12 -0500 Subject: [PATCH 12/24] fix : error handling --- packages/foundry/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/foundry/package.json b/packages/foundry/package.json index 68ee14f1b..1e22be2fb 100644 --- a/packages/foundry/package.json +++ b/packages/foundry/package.json @@ -8,7 +8,7 @@ "compile": "forge compile", "generate": "node script/generateAccount.js", "deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy && node script/generateTsAbis.js", - "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --verify && node script/generateTsAbis.js", + "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --verify ; node script/generateTsAbis.js", "lint": "forge fmt", "test": "forge test" }, From 7f2b037f8889e6044f03969ac8c4b4a214a7f2a9 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Mon, 14 Aug 2023 00:48:17 -0500 Subject: [PATCH 13/24] feat : use watch to get the final result --- packages/foundry/script/VerifyAll.s.sol | 132 ++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 packages/foundry/script/VerifyAll.s.sol diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol new file mode 100644 index 000000000..e87b536f6 --- /dev/null +++ b/packages/foundry/script/VerifyAll.s.sol @@ -0,0 +1,132 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "forge-std/Script.sol"; +import "forge-std/Vm.sol"; + +contract VerifyAll is Script { + uint96 currTransactionIdx; + + function run() external { + string memory root = vm.projectRoot(); + string memory path = string.concat( + root, + "/broadcast/Deploy.s.sol/80001/run-latest.json" + ); + string memory content = vm.readFile(path); + + while (this.nextTransaction(content)) { + _verifyIfContractDeployment(content); + currTransactionIdx++; + } + } + + function _verifyIfContractDeployment(string memory content) internal { + string memory txType = abi.decode( + vm.parseJson( + content, + searchStr(currTransactionIdx, "transactionType") + ), + (string) + ); + if (keccak256(bytes(txType)) == keccak256(bytes("CREATE"))) { + _verifyContract(content); + } + } + + function _verifyContract(string memory content) internal { + string memory contractName = abi.decode( + vm.parseJson( + content, + searchStr(currTransactionIdx, "contractName") + ), + (string) + ); + address contractAddr = abi.decode( + vm.parseJson( + content, + searchStr(currTransactionIdx, "contractAddress") + ), + (address) + ); + bytes32[] memory arguments = abi.decode( + vm.parseJson(content, searchStr(currTransactionIdx, "arguments")), + (bytes32[]) + ); + string memory args; + for (uint i = 0; i < arguments.length; i++) { + args = string.concat(args, vm.toString(arguments[i])); + } + string[] memory inputs = new string[](18); + inputs[0] = "forge"; + inputs[1] = "verify-contract"; + inputs[2] = vm.toString(contractAddr); + inputs[3] = contractName; + inputs[4] = "--chain"; + inputs[5] = vm.toString(block.chainid); + inputs[6] = "--constructor-args"; + inputs[7] = args; + inputs[8] = "--watch 2>&1 >/dev/null"; + // inputs[9] = "2>&1"; + // inputs[10] = ">/dev/null"; + inputs[9] = "|"; + inputs[10] = "grep"; + inputs[11] = "-E"; + inputs[12] = "-q"; + inputs[13] = "'already verified|Pass'"; + inputs[14] = "&&"; + inputs[15] = "echo"; + inputs[16] = "-n"; + inputs[ + 17 + ] = "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002676d000000000000000000000000000000000000000000000000000000000000"; + + bytes memory res = vm.ffi(inputs); + // string memory output = abi.decode(res, (string)); + + // if (keccak256(bytes(output)) != keccak256(bytes("SUCCESS"))) { + // string memory errMsg = string.concat( + // "Failed to verify contract ", + // contractName, + // " at address ", + // vm.toString(contractAddr) + // ); + // console.logString(errMsg); + // return; + // } + // string memory resultMsg = string.concat( + // "Successfully verified contract ", + // contractName, + // " at address ", + // vm.toString(contractAddr) + // ); + // console.logString(resultMsg); + // return; + } + + function nextTransaction(string memory content) external returns (bool) { + try this.getTransactionFromRaw(content, currTransactionIdx) { + return true; + } catch { + return false; + } + } + + function getTransactionFromRaw( + string memory content, + uint96 idx + ) external view { + bytes32 hash = abi.decode( + vm.parseJson(content, searchStr(idx, "hash")), + (bytes32) + ); + } + + function searchStr( + uint96 idx, + string memory searchKey + ) internal pure returns (string memory) { + return + string.concat(".transactions[", vm.toString(idx), "].", searchKey); + } +} From 582214a23e70a3efc7635022ba320984beff7013 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Mon, 14 Aug 2023 00:49:13 -0500 Subject: [PATCH 14/24] fix : reduce complexity --- packages/foundry/script/VerifyAll.s.sol | 44 +++++-------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index e87b536f6..bb6c83a1f 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -66,42 +66,14 @@ contract VerifyAll is Script { inputs[5] = vm.toString(block.chainid); inputs[6] = "--constructor-args"; inputs[7] = args; - inputs[8] = "--watch 2>&1 >/dev/null"; - // inputs[9] = "2>&1"; - // inputs[10] = ">/dev/null"; - inputs[9] = "|"; - inputs[10] = "grep"; - inputs[11] = "-E"; - inputs[12] = "-q"; - inputs[13] = "'already verified|Pass'"; - inputs[14] = "&&"; - inputs[15] = "echo"; - inputs[16] = "-n"; - inputs[ - 17 - ] = "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002676d000000000000000000000000000000000000000000000000000000000000"; - - bytes memory res = vm.ffi(inputs); - // string memory output = abi.decode(res, (string)); - - // if (keccak256(bytes(output)) != keccak256(bytes("SUCCESS"))) { - // string memory errMsg = string.concat( - // "Failed to verify contract ", - // contractName, - // " at address ", - // vm.toString(contractAddr) - // ); - // console.logString(errMsg); - // return; - // } - // string memory resultMsg = string.concat( - // "Successfully verified contract ", - // contractName, - // " at address ", - // vm.toString(contractAddr) - // ); - // console.logString(resultMsg); - // return; + string memory resultMsg = string.concat( + "Successfully submitted verification for contract ", + contractName, + " at address ", + vm.toString(contractAddr) + ); + console.logString(resultMsg); + return; } function nextTransaction(string memory content) external returns (bool) { From 4227258a4758b8e9b6aa28aaa310ca6a7614dd5c Mon Sep 17 00:00:00 2001 From: CarlosR Date: Mon, 14 Aug 2023 00:51:14 -0500 Subject: [PATCH 15/24] feat : verify after deployment done --- package.json | 2 +- packages/foundry/package.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index fdd33aaa7..1e37943b0 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "scripts": { "account": "yarn workspace @se-2/foundry account", "fork": "yarn workspace @se-2/foundry fork", - "verify": "yarn workspace @se-2/hardhat verify", + "verify": "yarn workspace @se-2/foundry verify", "compile": "yarn workspace @se-2/foundry compile", "chain": "yarn workspace @se-2/foundry chain", "deploy": "yarn workspace @se-2/foundry deploy", diff --git a/packages/foundry/package.json b/packages/foundry/package.json index 1e22be2fb..f6d403dc3 100644 --- a/packages/foundry/package.json +++ b/packages/foundry/package.json @@ -9,6 +9,7 @@ "generate": "node script/generateAccount.js", "deploy": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy && node script/generateTsAbis.js", "deploy:verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/Deploy.s.sol --rpc-url ${1:-default_network} --broadcast --legacy --verify ; node script/generateTsAbis.js", + "verify": "forge build --build-info --build-info-path out/build-info/ && forge script script/VerifyAll.s.sol --ffi --rpc-url ${1:-default_network}", "lint": "forge fmt", "test": "forge test" }, From fdde500e95a6c66ba21acb298afb943cfe709741 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Mon, 14 Aug 2023 00:53:44 -0500 Subject: [PATCH 16/24] fix typo --- packages/foundry/script/VerifyAll.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index bb6c83a1f..f3ea939f6 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -57,7 +57,7 @@ contract VerifyAll is Script { for (uint i = 0; i < arguments.length; i++) { args = string.concat(args, vm.toString(arguments[i])); } - string[] memory inputs = new string[](18); + string[] memory inputs = new string[](8); inputs[0] = "forge"; inputs[1] = "verify-contract"; inputs[2] = vm.toString(contractAddr); From 8be4f5452506307e8976a6d56722042ad65314c5 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Tue, 15 Aug 2023 10:45:45 -0500 Subject: [PATCH 17/24] fix : delete hardcoded value --- packages/foundry/script/VerifyAll.s.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index f3ea939f6..3f5668fa7 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -11,7 +11,9 @@ contract VerifyAll is Script { string memory root = vm.projectRoot(); string memory path = string.concat( root, - "/broadcast/Deploy.s.sol/80001/run-latest.json" + "/broadcast/Deploy.s.sol/", + vm.toString(block.chainid), + "/run-latest.json" ); string memory content = vm.readFile(path); From ef7ba9d3d5d375325bc00183dff49018d258e754 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Tue, 15 Aug 2023 11:16:03 -0500 Subject: [PATCH 18/24] fix : add ffi call --- packages/foundry/script/VerifyAll.s.sol | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index 3f5668fa7..6e145beb9 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -68,6 +68,8 @@ contract VerifyAll is Script { inputs[5] = vm.toString(block.chainid); inputs[6] = "--constructor-args"; inputs[7] = args; + + bytes memory res = vm.ffi(inputs); string memory resultMsg = string.concat( "Successfully submitted verification for contract ", contractName, From db7424240bf70e0e71f16890f93da7d03678d817 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Tue, 15 Aug 2023 11:44:42 -0500 Subject: [PATCH 19/24] feat : better logging' --- packages/foundry/script/VerifyAll.s.sol | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index 6e145beb9..8a626139b 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -59,7 +59,7 @@ contract VerifyAll is Script { for (uint i = 0; i < arguments.length; i++) { args = string.concat(args, vm.toString(arguments[i])); } - string[] memory inputs = new string[](8); + string[] memory inputs = new string[](9); inputs[0] = "forge"; inputs[1] = "verify-contract"; inputs[2] = vm.toString(contractAddr); @@ -68,15 +68,12 @@ contract VerifyAll is Script { inputs[5] = vm.toString(block.chainid); inputs[6] = "--constructor-args"; inputs[7] = args; + inputs[8] = "--watch"; bytes memory res = vm.ffi(inputs); - string memory resultMsg = string.concat( - "Successfully submitted verification for contract ", - contractName, - " at address ", - vm.toString(contractAddr) - ); - console.logString(resultMsg); + + console.logString(string(res)); + console.logString("\n"); return; } From 67552630aca79289f4fdc5e78aed755585db7f67 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Tue, 15 Aug 2023 14:28:29 -0500 Subject: [PATCH 20/24] enh : try diff constructors --- packages/foundry/script/VerifyAll.s.sol | 112 ++++++++++++++++++++---- 1 file changed, 93 insertions(+), 19 deletions(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index 8a626139b..57412da66 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.19; import "forge-std/Script.sol"; import "forge-std/Vm.sol"; +import "../contracts/YourContract.sol"; contract VerifyAll is Script { uint96 currTransactionIdx; @@ -55,28 +56,89 @@ contract VerifyAll is Script { vm.parseJson(content, searchStr(currTransactionIdx, "arguments")), (bytes32[]) ); - string memory args; - for (uint i = 0; i < arguments.length; i++) { - args = string.concat(args, vm.toString(arguments[i])); - } - string[] memory inputs = new string[](9); - inputs[0] = "forge"; - inputs[1] = "verify-contract"; - inputs[2] = vm.toString(contractAddr); - inputs[3] = contractName; - inputs[4] = "--chain"; - inputs[5] = vm.toString(block.chainid); - inputs[6] = "--constructor-args"; - inputs[7] = args; - inputs[8] = "--watch"; - - bytes memory res = vm.ffi(inputs); - - console.logString(string(res)); - console.logString("\n"); + + console.logUint(arguments.length); + + // string[] memory castInputs = new string[](5); + // castInputs[0] = ("cast"); + // castInputs[1] = ("abi-encode"); + // castInputs[2] = ("constructor(address,uint256)"); + // castInputs[3] = ("0xDe3089d40F3491De794fBb1ECA109fAc36F889d0"); + // castInputs[4] = ("15"); + // bytes memory castArgs = vm.ffi(castInputs); + // console.logBytes(castArgs); + + // bytes memory argsBytes = _getArgsBytesFromContract( + // contractName, + // arguments + // ); + + // console.logBytes(argsBytes); + + // string[] memory Verifyinputs = new string[](9); + // Verifyinputs[0] = "forge"; + // Verifyinputs[1] = "verify-contract"; + // Verifyinputs[2] = vm.toString(contractAddr); + // Verifyinputs[3] = contractName; + // Verifyinputs[4] = "--chain"; + // Verifyinputs[5] = vm.toString(block.chainid); + // Verifyinputs[6] = "--constructor-args"; + // Verifyinputs[7] = argsBytes; + // Verifyinputs[8] = "--watch"; + + // bytes memory res = vm.ffi(Verifyinputs); + + // console.logString(string(res)); + // console.logString("\n"); return; } + function _getArgsBytesFromContract( + string memory contractName, + string[] memory args + ) internal returns (bytes memory) { + string memory path = string.concat( + vm.projectRoot(), + "/out/", + contractName, + ".sol/", + contractName, + ".json" + ); + string memory abiContent = vm.readFile(path); + uint96 searchIdx = 0; + string memory constructorStr = "constructor("; + while (this.nextInput(abiContent, searchIdx)) { + if (searchIdx != 0) + constructorStr = string.concat(constructorStr, ","); + constructorStr = string.concat( + constructorStr, + this.getInputFromRaw(abiContent, searchIdx) + ); + searchIdx++; + } + constructorStr = string.concat(constructorStr, ")"); + string[] memory castInputs = new string[](args.length + 3); + castInputs[0] = "cast"; + castInputs[1] = "abi-encode"; + castInputs[2] = constructorStr; + for (uint96 i = 0; i < args.length; i++) { + castInputs[i + 3] = args[i]; + } + return vm.ffi(castInputs); + } + + function nextInput( + string memory content, + uint96 idx + ) external returns (bool) { + try this.getInputFromRaw(content, idx) { + return true; + } catch { + return false; + } + } + function nextTransaction(string memory content) external returns (bool) { try this.getTransactionFromRaw(content, currTransactionIdx) { return true; @@ -85,6 +147,18 @@ contract VerifyAll is Script { } } + function getInputFromRaw( + string memory content, + uint96 idx + ) external view returns (string memory) { + string memory search = string.concat( + ".abi[0].inputs[", + vm.toString(idx), + "].type" + ); + return abi.decode(vm.parseJson(content, search), (string)); + } + function getTransactionFromRaw( string memory content, uint96 idx From fabcfc0f0bb75d28583f8cd9138b743787e72e27 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Tue, 15 Aug 2023 15:29:26 -0500 Subject: [PATCH 21/24] feat : support for all types of constrcutors --- .gitmodules | 3 + packages/foundry/lib/solidity-bytes-utils | 1 + packages/foundry/script/VerifyAll.s.sol | 138 ++++++++-------------- 3 files changed, 50 insertions(+), 92 deletions(-) create mode 160000 packages/foundry/lib/solidity-bytes-utils diff --git a/.gitmodules b/.gitmodules index d78ff238b..b15e197af 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,3 +6,6 @@ [submodule "packages/foundry/lib/openzeppelin-contracts"] path = packages/foundry/lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts +[submodule "packages/foundry/lib/solidity-bytes-utils"] + path = packages/foundry/lib/solidity-bytes-utils + url = https://github.com/gnsps/solidity-bytes-utils diff --git a/packages/foundry/lib/solidity-bytes-utils b/packages/foundry/lib/solidity-bytes-utils new file mode 160000 index 000000000..6458fb278 --- /dev/null +++ b/packages/foundry/lib/solidity-bytes-utils @@ -0,0 +1 @@ +Subproject commit 6458fb2780a3092bc756e737f246be1de6d3d362 diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index 57412da66..fd347e6be 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.19; import "forge-std/Script.sol"; import "forge-std/Vm.sol"; -import "../contracts/YourContract.sol"; +import "solidity-bytes-utils/BytesLib.sol"; contract VerifyAll is Script { uint96 currTransactionIdx; @@ -52,91 +52,42 @@ contract VerifyAll is Script { ), (address) ); - bytes32[] memory arguments = abi.decode( - vm.parseJson(content, searchStr(currTransactionIdx, "arguments")), - (bytes32[]) + bytes memory deployedBytecode = abi.decode( + vm.parseJson( + content, + searchStr(currTransactionIdx, "transaction.data") + ), + (bytes) ); - - console.logUint(arguments.length); - - // string[] memory castInputs = new string[](5); - // castInputs[0] = ("cast"); - // castInputs[1] = ("abi-encode"); - // castInputs[2] = ("constructor(address,uint256)"); - // castInputs[3] = ("0xDe3089d40F3491De794fBb1ECA109fAc36F889d0"); - // castInputs[4] = ("15"); - // bytes memory castArgs = vm.ffi(castInputs); - // console.logBytes(castArgs); - - // bytes memory argsBytes = _getArgsBytesFromContract( - // contractName, - // arguments - // ); - - // console.logBytes(argsBytes); - - // string[] memory Verifyinputs = new string[](9); - // Verifyinputs[0] = "forge"; - // Verifyinputs[1] = "verify-contract"; - // Verifyinputs[2] = vm.toString(contractAddr); - // Verifyinputs[3] = contractName; - // Verifyinputs[4] = "--chain"; - // Verifyinputs[5] = vm.toString(block.chainid); - // Verifyinputs[6] = "--constructor-args"; - // Verifyinputs[7] = argsBytes; - // Verifyinputs[8] = "--watch"; - - // bytes memory res = vm.ffi(Verifyinputs); - - // console.logString(string(res)); - // console.logString("\n"); - return; - } - - function _getArgsBytesFromContract( - string memory contractName, - string[] memory args - ) internal returns (bytes memory) { - string memory path = string.concat( - vm.projectRoot(), - "/out/", - contractName, - ".sol/", - contractName, - ".json" + bytes memory compiledBytecode = abi.decode( + vm.parseJson( + _getCompiledBytecode(contractName), + ".bytecode.object" + ), + (bytes) + ); + bytes memory constructorArgs = BytesLib.slice( + deployedBytecode, + compiledBytecode.length, + deployedBytecode.length - compiledBytecode.length ); - string memory abiContent = vm.readFile(path); - uint96 searchIdx = 0; - string memory constructorStr = "constructor("; - while (this.nextInput(abiContent, searchIdx)) { - if (searchIdx != 0) - constructorStr = string.concat(constructorStr, ","); - constructorStr = string.concat( - constructorStr, - this.getInputFromRaw(abiContent, searchIdx) - ); - searchIdx++; - } - constructorStr = string.concat(constructorStr, ")"); - string[] memory castInputs = new string[](args.length + 3); - castInputs[0] = "cast"; - castInputs[1] = "abi-encode"; - castInputs[2] = constructorStr; - for (uint96 i = 0; i < args.length; i++) { - castInputs[i + 3] = args[i]; - } - return vm.ffi(castInputs); - } - function nextInput( - string memory content, - uint96 idx - ) external returns (bool) { - try this.getInputFromRaw(content, idx) { - return true; - } catch { - return false; - } + string[] memory inputs = new string[](9); + inputs[0] = "forge"; + inputs[1] = "verify-contract"; + inputs[2] = vm.toString(contractAddr); + inputs[3] = contractName; + inputs[4] = "--chain"; + inputs[5] = vm.toString(block.chainid); + inputs[6] = "--constructor-args"; + inputs[7] = vm.toString(constructorArgs); + inputs[8] = "--watch"; + + bytes memory res = vm.ffi(inputs); + + console.logString(string(res)); + console.logString("\n"); + return; } function nextTransaction(string memory content) external returns (bool) { @@ -147,16 +98,19 @@ contract VerifyAll is Script { } } - function getInputFromRaw( - string memory content, - uint96 idx - ) external view returns (string memory) { - string memory search = string.concat( - ".abi[0].inputs[", - vm.toString(idx), - "].type" + function _getCompiledBytecode( + string memory contractName + ) internal view returns (string memory compiledBytecode) { + string memory root = vm.projectRoot(); + string memory path = string.concat( + root, + "/out/", + contractName, + ".sol/", + contractName, + ".json" ); - return abi.decode(vm.parseJson(content, search), (string)); + compiledBytecode = vm.readFile(path); } function getTransactionFromRaw( From 4cf3b512a7d642c2d8b585912326042f97ffa432 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Sun, 20 Aug 2023 15:13:11 -0500 Subject: [PATCH 22/24] feat : cleaner loggin using tryffi --- packages/foundry/script/VerifyAll.s.sol | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index fd347e6be..94fbf4b73 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -5,6 +5,22 @@ import "forge-std/Script.sol"; import "forge-std/Vm.sol"; import "solidity-bytes-utils/BytesLib.sol"; +/** + * @dev Temp Vm implementation + * @notice calls the tryffi function on the Vm contract + * @notice will be deleted once the forge/std is updated + */ + +struct FfiResult { + int32 exit_code; + bytes stdout; + bytes stderr; +} + +interface tempVm { + function tryFfi(string[] calldata) external returns (FfiResult memory); +} + contract VerifyAll is Script { uint96 currTransactionIdx; @@ -83,10 +99,13 @@ contract VerifyAll is Script { inputs[7] = vm.toString(constructorArgs); inputs[8] = "--watch"; - bytes memory res = vm.ffi(inputs); + FfiResult memory f = tempVm(address(vm)).tryFfi(inputs); - console.logString(string(res)); - console.logString("\n"); + if (f.stderr.length != 0) { + console.logString(string(f.stderr)); + } else { + console.logString(string(f.stdout)); + } return; } From cebd002849fa9ed4766645ad22e72203c1a7c828 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Sun, 27 Aug 2023 16:15:54 +0800 Subject: [PATCH 23/24] handle warning --- packages/foundry/script/VerifyAll.s.sol | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index 94fbf4b73..8f00dd5af 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -109,7 +109,9 @@ contract VerifyAll is Script { return; } - function nextTransaction(string memory content) external returns (bool) { + function nextTransaction( + string memory content + ) external view returns (bool) { try this.getTransactionFromRaw(content, currTransactionIdx) { return true; } catch { @@ -135,11 +137,8 @@ contract VerifyAll is Script { function getTransactionFromRaw( string memory content, uint96 idx - ) external view { - bytes32 hash = abi.decode( - vm.parseJson(content, searchStr(idx, "hash")), - (bytes32) - ); + ) external pure { + abi.decode(vm.parseJson(content, searchStr(idx, "hash")), (bytes32)); } function searchStr( From 0333a5716480f4a6854b1c117f8f5eaa75b4f764 Mon Sep 17 00:00:00 2001 From: CarlosR Date: Sun, 27 Aug 2023 16:24:56 +0800 Subject: [PATCH 24/24] add logging for contract address --- packages/foundry/script/VerifyAll.s.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/foundry/script/VerifyAll.s.sol b/packages/foundry/script/VerifyAll.s.sol index 8f00dd5af..9a6ff02d3 100644 --- a/packages/foundry/script/VerifyAll.s.sol +++ b/packages/foundry/script/VerifyAll.s.sol @@ -102,6 +102,12 @@ contract VerifyAll is Script { FfiResult memory f = tempVm(address(vm)).tryFfi(inputs); if (f.stderr.length != 0) { + console.logString( + string.concat( + "Submitting verification for contract: ", + vm.toString(contractAddr) + ) + ); console.logString(string(f.stderr)); } else { console.logString(string(f.stdout));