From 0b0458bb431c10726d1d0348e5b3e2546f72298f Mon Sep 17 00:00:00 2001 From: Tilak Madichetti Date: Mon, 10 Mar 2025 18:07:33 +0530 Subject: [PATCH] Add env variable support to `aderyn.toml` (#820) --- .github/workflows/reports.yml | 5 ++ .gitmodules | 6 ++ aderyn/templates/aderyn.toml | 6 ++ aderyn_driver/src/config_helpers.rs | 27 +++++++- cli/reportgen.sh | 2 + reports/nft-report-icm.md | 37 +++++++++++ .../.github/workflows/test.yml | 34 ++++++++++ tests/foundry-nft-f23-icm/.gitignore | 15 +++++ tests/foundry-nft-f23-icm/README.md | 66 +++++++++++++++++++ tests/foundry-nft-f23-icm/aderyn.toml | 8 +++ tests/foundry-nft-f23-icm/foundry.toml | 13 ++++ tests/foundry-nft-f23-icm/lib/forge-std | 1 + .../lib/openzeppelin-contracts | 1 + tests/foundry-nft-f23-icm/remappings | 7 ++ tests/foundry-nft-f23-icm/src/BasicNft.sol | 23 +++++++ tests/foundry-nft-f23-icm/src/F1.sol | 9 +++ tests/foundry-nft-f23-icm/src/F2.sol | 7 ++ tests/foundry-nft-f23-icm/src/Initializer.sol | 11 ++++ .../src/inner-core-modules/ICM.sol | 8 +++ 19 files changed, 284 insertions(+), 2 deletions(-) create mode 100644 reports/nft-report-icm.md create mode 100644 tests/foundry-nft-f23-icm/.github/workflows/test.yml create mode 100644 tests/foundry-nft-f23-icm/.gitignore create mode 100644 tests/foundry-nft-f23-icm/README.md create mode 100644 tests/foundry-nft-f23-icm/aderyn.toml create mode 100644 tests/foundry-nft-f23-icm/foundry.toml create mode 160000 tests/foundry-nft-f23-icm/lib/forge-std create mode 160000 tests/foundry-nft-f23-icm/lib/openzeppelin-contracts create mode 100644 tests/foundry-nft-f23-icm/remappings create mode 100644 tests/foundry-nft-f23-icm/src/BasicNft.sol create mode 100644 tests/foundry-nft-f23-icm/src/F1.sol create mode 100644 tests/foundry-nft-f23-icm/src/F2.sol create mode 100644 tests/foundry-nft-f23-icm/src/Initializer.sol create mode 100644 tests/foundry-nft-f23-icm/src/inner-core-modules/ICM.sol diff --git a/.github/workflows/reports.yml b/.github/workflows/reports.yml index 011bed438..74d9beda7 100644 --- a/.github/workflows/reports.yml +++ b/.github/workflows/reports.yml @@ -22,6 +22,7 @@ jobs: - sablier - adhoc-sol-files-workflow - nft-workflow + - nft-workflow-env - ccip-functions-report - hardhat-playground-report - prb-math-report @@ -95,6 +96,10 @@ jobs: cargo run -- -o ./reports/nft-workflow-report.md --src src/ ./tests/foundry-nft-f23 --skip-update-check diff ./reports/nft-report.md ./reports/nft-workflow-report.md ;; + nft-workflow-env) + cargo run -- -o ./reports/nft-workflow-report-icm.md ./tests/foundry-nft-f23-icm --skip-update-check + diff ./reports/nft-report-icm.md ./reports/nft-workflow-report-icm.md + ;; ccip-functions-report) cargo run -- -o reports/ccip-functions-report-workflow.md tests/ccip-contracts/contracts --src src/v0.8/functions/ -x "tests/,test/,mocks/" --skip-update-check diff ./reports/ccip-functions-report.md ./reports/ccip-functions-report-workflow.md diff --git a/.gitmodules b/.gitmodules index b0a34e89e..c1fc6702e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,9 @@ [submodule "tests/2024-07-templegold"] path = tests/2024-07-templegold url = https://github.com/Cyfrin/2024-07-templegold.git +[submodule "tests/foundry-nft-f23-icm/lib/forge-std"] + path = tests/foundry-nft-f23-icm/lib/forge-std + url = https://github.com/foundry-rs/forge-std +[submodule "tests/foundry-nft-f23-icm/lib/openzeppelin-contracts"] + path = tests/foundry-nft-f23-icm/lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts diff --git a/aderyn/templates/aderyn.toml b/aderyn/templates/aderyn.toml index a16394cb0..3cea87c9f 100644 --- a/aderyn/templates/aderyn.toml +++ b/aderyn/templates/aderyn.toml @@ -40,3 +40,9 @@ root = "." # That would be the result of calling `foundry remappings` # Example: # remappings = ["@oz/contracts=lib/openzeppelin-contracts/contracts"] + +# Environment variables that would help aderyn detect src, etc. +# In a medium sized foundry project, the profile can determine the values to be read from `foundry.toml`. For example, if different profiles have different src declaration in `foundry.toml`, these env variables can help decide which ones to read. + +[env] +# FOUNDRY_PROFILE = "profile_name" diff --git a/aderyn_driver/src/config_helpers.rs b/aderyn_driver/src/config_helpers.rs index bd4de5aa8..be8e06f8a 100644 --- a/aderyn_driver/src/config_helpers.rs +++ b/aderyn_driver/src/config_helpers.rs @@ -1,5 +1,6 @@ use std::{ - fs, + collections::HashMap, + env, fs, path::{Path, PathBuf}, }; @@ -16,6 +17,7 @@ pub struct AderynConfig { pub exclude: Option>, pub remappings: Option>, pub include: Option>, + pub env: Option>, } /// Load the aderyn.toml file and deserialize it to AderynConfig @@ -38,9 +40,20 @@ fn load_aderyn_config(root: &Path) -> Result { clear_empty_vectors(&mut config.remappings); clear_empty_vectors(&mut config.include); + load_env_variables_from_config(&config); + Ok(config) } +fn load_env_variables_from_config(config: &AderynConfig) { + // Load env variables + if let Some(map) = config.env.clone() { + map.iter().for_each(|(k, v)| { + env::set_var(k, v); + }) + } +} + fn clear_empty_vectors(vec: &mut Option>) { if let Some(v) = vec { if v.is_empty() { @@ -216,12 +229,17 @@ fn interpret_foundry_config( #[cfg(test)] mod tests { - use std::path::PathBuf; + use std::{collections::HashMap, env, path::PathBuf}; use cyfrin_foundry_config::RelativeRemapping; + use crate::config_helpers::load_env_variables_from_config; + #[test] fn test_interpret_aderyn_config_correctly_appends_and_replaces() { + let env = + HashMap::from_iter(vec![("FOUNDRY_PROFILE".to_string(), "ENV_VAR_VALUE".to_string())]); + let config = super::AderynConfig { version: 1, root: Some("CONFIG_ROOT".to_string()), @@ -229,6 +247,7 @@ mod tests { exclude: Some(vec!["CONFIG_EXCLUDE".to_string()]), remappings: Some(vec!["CONFIG_REMAPPINGS".to_string()]), include: Some(vec!["CONFIG_SCOPE".to_string()]), + env: Some(env), }; let root = std::path::Path::new("ARG_ROOT"); @@ -236,6 +255,8 @@ mod tests { let exclude = Some(vec!["ARG_EXCLUDE_1".to_string(), "ARG_EXCLUDE_2".to_string()]); let remappings = Some(vec!["ARG_REMAPPINGS_1".to_string(), "ARG_REMAPPINGS_2".to_string()]); let include = Some(vec!["ARG_SCOPE_1".to_string(), "ARG_SCOPE_2".to_string()]); + + load_env_variables_from_config(&config); let result = super::interpret_aderyn_config(config, root, &src, &exclude, &remappings, &include); assert_eq!(result.0, std::path::Path::new("ARG_ROOT/CONFIG_ROOT")); @@ -264,6 +285,8 @@ mod tests { "CONFIG_SCOPE".to_string() ]) ); + + assert_eq!(env::var("FOUNDRY_PROFILE").unwrap(), "ENV_VAR_VALUE"); } #[test] diff --git a/cli/reportgen.sh b/cli/reportgen.sh index b89a2a6b4..797c1a04e 100755 --- a/cli/reportgen.sh +++ b/cli/reportgen.sh @@ -29,6 +29,8 @@ cargo run -- tests/2024-07-templegold/protocol -o reports/templegold-report.md - cargo run -- tests/hardhat-js-playground -o reports/hardhat-playground-report.md --skip-update-check & +cargo run -- ./tests/foundry-nft-f23-icm -o ./reports/nft-report-icm.md --skip-update-check & + ##### JSON REPORTS ######## # Basic report.json diff --git a/reports/nft-report-icm.md b/reports/nft-report-icm.md new file mode 100644 index 000000000..668914676 --- /dev/null +++ b/reports/nft-report-icm.md @@ -0,0 +1,37 @@ +# Aderyn Analysis Report + +This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a static analysis tool built by [Cyfrin](https://cyfrin.io), a blockchain security company. This report is not a substitute for manual audit or security review. It should not be relied upon for any purpose other than to assist in the identification of potential security vulnerabilities. +# Table of Contents + +- [Summary](#summary) + - [Files Summary](#files-summary) + - [Files Details](#files-details) + - [Issue Summary](#issue-summary) + + +# Summary + +## Files Summary + +| Key | Value | +| --- | --- | +| .sol Files | 1 | +| Total nSLOC | 5 | + + +## Files Details + +| Filepath | nSLOC | +| --- | --- | +| src/inner-core-modules/ICM.sol | 5 | +| **Total** | **5** | + + +## Issue Summary + +| Category | No. of Issues | +| --- | --- | +| High | 0 | +| Low | 0 | + + diff --git a/tests/foundry-nft-f23-icm/.github/workflows/test.yml b/tests/foundry-nft-f23-icm/.github/workflows/test.yml new file mode 100644 index 000000000..9282e8294 --- /dev/null +++ b/tests/foundry-nft-f23-icm/.github/workflows/test.yml @@ -0,0 +1,34 @@ +name: test + +on: workflow_dispatch + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + strategy: + fail-fast: true + + name: Foundry project + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Run Forge build + run: | + forge --version + forge build --sizes + id: build + + - name: Run Forge tests + run: | + forge test -vvv + id: test diff --git a/tests/foundry-nft-f23-icm/.gitignore b/tests/foundry-nft-f23-icm/.gitignore new file mode 100644 index 000000000..8d6f4732f --- /dev/null +++ b/tests/foundry-nft-f23-icm/.gitignore @@ -0,0 +1,15 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env +broadcast diff --git a/tests/foundry-nft-f23-icm/README.md b/tests/foundry-nft-f23-icm/README.md new file mode 100644 index 000000000..9265b4558 --- /dev/null +++ b/tests/foundry-nft-f23-icm/README.md @@ -0,0 +1,66 @@ +## Foundry + +**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** + +Foundry consists of: + +- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). +- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. +- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. +- **Chisel**: Fast, utilitarian, and verbose solidity REPL. + +## Documentation + +https://book.getfoundry.sh/ + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +```shell +$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/tests/foundry-nft-f23-icm/aderyn.toml b/tests/foundry-nft-f23-icm/aderyn.toml new file mode 100644 index 000000000..e6bc33c83 --- /dev/null +++ b/tests/foundry-nft-f23-icm/aderyn.toml @@ -0,0 +1,8 @@ +# Aderyn Configuration File +# Help Aderyn work with more granular control + +# DO NOT CHANGE version below. As of now, only 1 is supported +version = 1 + +[env] +FOUNDRY_PROFILE = "icm" diff --git a/tests/foundry-nft-f23-icm/foundry.toml b/tests/foundry-nft-f23-icm/foundry.toml new file mode 100644 index 000000000..1463fd659 --- /dev/null +++ b/tests/foundry-nft-f23-icm/foundry.toml @@ -0,0 +1,13 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] +remappings = ["@oz/contracts=lib/openzeppelin-contracts/contracts", "icm/=src/inner-core-modules"] + +[profile.icm] +src = "src/inner-core-modules" +out = "out" +libs = ["lib"] +remappings = ["@oz/contracts=lib/openzeppelin-contracts/contracts", "icm/=src/inner-core-modules"] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/tests/foundry-nft-f23-icm/lib/forge-std b/tests/foundry-nft-f23-icm/lib/forge-std new file mode 160000 index 000000000..3b20d60d1 --- /dev/null +++ b/tests/foundry-nft-f23-icm/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 3b20d60d14b343ee4f908cb8079495c07f5e8981 diff --git a/tests/foundry-nft-f23-icm/lib/openzeppelin-contracts b/tests/foundry-nft-f23-icm/lib/openzeppelin-contracts new file mode 160000 index 000000000..acd4ff74d --- /dev/null +++ b/tests/foundry-nft-f23-icm/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit acd4ff74de833399287ed6b31b4debf6b2b35527 diff --git a/tests/foundry-nft-f23-icm/remappings b/tests/foundry-nft-f23-icm/remappings new file mode 100644 index 000000000..7f65b75f4 --- /dev/null +++ b/tests/foundry-nft-f23-icm/remappings @@ -0,0 +1,7 @@ +@oz/contracts/=lib/openzeppelin-contracts/contracts/ +icm/=src/inner-core-modules/ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ +ds-test/=lib/openzeppelin-contracts/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/ diff --git a/tests/foundry-nft-f23-icm/src/BasicNft.sol b/tests/foundry-nft-f23-icm/src/BasicNft.sol new file mode 100644 index 000000000..c6fe8ccf1 --- /dev/null +++ b/tests/foundry-nft-f23-icm/src/BasicNft.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.25; + +import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import "icm/ICM.sol"; // icm is remapped to src/inner-core-modules +import "./Initializer.sol"; + +contract BasicNft is ICM, ERC721 { + + uint256 public s_tokenId; + + constructor() ERC721(PROJECT_NAME, PROJECT_SYMBOL) { + Initializer initializer = new Initializer(); + s_tokenId = initializer.get_start_token_id(); + } + + function mint() public { + _safeMint(msg.sender, s_tokenId); + s_tokenId++; + } + +} \ No newline at end of file diff --git a/tests/foundry-nft-f23-icm/src/F1.sol b/tests/foundry-nft-f23-icm/src/F1.sol new file mode 100644 index 000000000..c463654cc --- /dev/null +++ b/tests/foundry-nft-f23-icm/src/F1.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.10; + +import "./F2.sol"; + +contract F1 { + +} \ No newline at end of file diff --git a/tests/foundry-nft-f23-icm/src/F2.sol b/tests/foundry-nft-f23-icm/src/F2.sol new file mode 100644 index 000000000..b2483c83a --- /dev/null +++ b/tests/foundry-nft-f23-icm/src/F2.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.21; + +contract F2 { + +} \ No newline at end of file diff --git a/tests/foundry-nft-f23-icm/src/Initializer.sol b/tests/foundry-nft-f23-icm/src/Initializer.sol new file mode 100644 index 000000000..463028755 --- /dev/null +++ b/tests/foundry-nft-f23-icm/src/Initializer.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.25; + +import "@oz/contracts/token/ERC721/ERC721.sol"; + +contract Initializer { + function get_start_token_id() public pure returns(uint256) { + return 10; + } +} \ No newline at end of file diff --git a/tests/foundry-nft-f23-icm/src/inner-core-modules/ICM.sol b/tests/foundry-nft-f23-icm/src/inner-core-modules/ICM.sol new file mode 100644 index 000000000..9f1a95803 --- /dev/null +++ b/tests/foundry-nft-f23-icm/src/inner-core-modules/ICM.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.25; + +contract ICM { + string public PROJECT_NAME = "Dogie"; + string public PROJECT_SYMBOL = "DOG"; +} \ No newline at end of file