From 8afcd4048e0260c0582a356583c7686f7d4fdea3 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Thu, 16 May 2024 13:42:36 +0200 Subject: [PATCH 01/35] chore: setup --- README.md | 14 +++++++++++++- package.json | 3 +++ remappings.txt | 1 + yarn.lock | 4 ++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c0f8467..b2fd374a 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@
Deployment scripts
Sample scripts to deploy contracts on both mainnet and testnet.
-
Sample Integration & Unit tests
+
Sample Integration, Unit, Property-based fuzzed and symbolic tests
Example tests showcasing mocking, assertions and configuration for mainnet forking. As well it includes everything needed in order to check code coverage.
Linter
@@ -78,6 +78,18 @@ In order to just run integration tests, run: yarn test:integration ``` +In order to just run the echidna fuzzing campaign (requires [Echidna](https://github.com/crytic/building-secure-contracts/blob/master/program-analysis/echidna/introduction/installation.md) installed), run: + +```bash +yarn test:fuzz +``` + +In order to just run the symbolic execution tests (requires [Halmos](https://github.com/a16z/halmos/blob/main/README.md#installation) installed), run: + +```bash +yarn test:symbolic +``` + In order to check your current code coverage, run: ```bash diff --git a/package.json b/package.json index a1866656..47caadac 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,9 @@ "lint:sol-tests": "solhint -c .solhint.tests.json 'test/**/*.sol'", "prepare": "husky install", "test": "forge test -vvv", + "test:fuzz": "echidna test/invariants/Greeter.invariants.t.sol --contract GreeterInvariant --corpus-dir test/invariants/echidna_coverage/", "test:integration": "forge test --match-contract Integration -vvv", + "test:symbolic": "halmos", "test:unit": "forge test --match-contract Unit -vvv", "test:unit:deep": "FOUNDRY_FUZZ_RUNS=5000 yarn test:unit" }, @@ -37,6 +39,7 @@ "@commitlint/config-conventional": "19.2.2", "@defi-wonderland/natspec-smells": "1.1.1", "forge-std": "github:foundry-rs/forge-std#1.8.2", + "halmos-cheatcodes": "github:a16z/halmos-cheatcodes#c0d8655", "husky": ">=8", "lint-staged": ">=10", "solhint-community": "4.0.0", diff --git a/remappings.txt b/remappings.txt index 4a7cbdf9..0ba2eecd 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,4 +1,5 @@ forge-std/=node_modules/forge-std/src +halmos-cheatcodes=node_modules/halmos-cheatcodes contracts/=src/contracts interfaces/=src/interfaces diff --git a/yarn.lock b/yarn.lock index 490e8a4d..ecc94089 100644 --- a/yarn.lock +++ b/yarn.lock @@ -962,6 +962,10 @@ graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +"halmos-cheatcodes@github:a16z/halmos-cheatcodes#c0d8655": + version "0.0.0" + resolved "https://codeload.github.com/a16z/halmos-cheatcodes/tar.gz/c0d865508c0fee0a11b97732c5e90f9cad6b65a5" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" From 3c278998f24c453b430d91afb0dee8d31349c8a1 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Thu, 16 May 2024 13:47:07 +0200 Subject: [PATCH 02/35] feat: echidna --- test/invariants/Greeter.invariants.t.sol | 24 ++++++++++++++++++++++++ test/invariants/PROPERTIES.md | 4 ++++ 2 files changed, 28 insertions(+) create mode 100644 test/invariants/Greeter.invariants.t.sol create mode 100644 test/invariants/PROPERTIES.md diff --git a/test/invariants/Greeter.invariants.t.sol b/test/invariants/Greeter.invariants.t.sol new file mode 100644 index 00000000..5489d2d5 --- /dev/null +++ b/test/invariants/Greeter.invariants.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {Greeter, IERC20} from '../../src/contracts/Greeter.sol'; + +contract GreeterInvariant is Greeter { + constructor() Greeter('a', IERC20(address(1))) {} + + function echidna_greeterNeverEmpty() public view returns (bool) { + return keccak256(bytes(greeting)) != keccak256(''); + } + + function echidna_onlyOwnerSetsGreeting() public returns (bool) { + // new greeting set, is the sender the owner? + try this.setGreeting('hello') { + if (msg.sender != OWNER) return false; + return true; + } catch { + // new greeting failed, is the sender not the owner? + if (msg.sender == OWNER) return false; + return true; + } + } +} diff --git a/test/invariants/PROPERTIES.md b/test/invariants/PROPERTIES.md new file mode 100644 index 00000000..e48439c9 --- /dev/null +++ b/test/invariants/PROPERTIES.md @@ -0,0 +1,4 @@ +| Properties | Type | +|---------------------------------------------------|------------| +| Greeting should never be empty | Valid state | +| Only the owner can set the greeting | State transition | \ No newline at end of file From ed45d893798fa2beaafb866d71d8b7e8c202283b Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Thu, 16 May 2024 13:47:25 +0200 Subject: [PATCH 03/35] feat: symb exec halmos --- test/invariants/Greeter.symbolic.t.sol | 55 ++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 test/invariants/Greeter.symbolic.t.sol diff --git a/test/invariants/Greeter.symbolic.t.sol b/test/invariants/Greeter.symbolic.t.sol new file mode 100644 index 00000000..25fe7303 --- /dev/null +++ b/test/invariants/Greeter.symbolic.t.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {Greeter, IERC20} from 'contracts/Greeter.sol'; + +import {Test} from 'forge-std/Test.sol'; +import {SymTest} from 'halmos-cheatcodes/src/SymTest.sol'; + +contract GreeterSymbolic is SymTest, Test { + Greeter public targetContract; + + function setUp() public { + string memory _initialGreeting = svm.createString(64, 'initial greeting'); + address _token = svm.createAddress('token'); + + targetContract = new Greeter(_initialGreeting, IERC20(_token)); + } + + function check_validState_greeterNeverEmpty(address caller, bytes4 selector) public { + // Input conditions: any caller + vm.prank(caller); + + // Execution + (bool success,) = address(targetContract).call(gen_calldata(selector)); + + // Output condition check + vm.assume(success); // discard failing calls + assert(keccak256(bytes(targetContract.greeting())) != keccak256('')); + } + + function check_setGreeting_onlyOwnerSetsGreeting(address caller) public { + // Input conditions + string memory newGreeting = svm.createString(64, 'new greeting'); + + // Execution + vm.prank(caller); + (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (newGreeting))); + + // Output condition check + if (success) { + assert(caller == targetContract.OWNER()); + assert(keccak256(bytes(targetContract.greeting())) == keccak256(bytes(newGreeting))); + } else { + assert(caller != targetContract.OWNER() || keccak256(bytes(newGreeting)) == keccak256('')); + } + } + + // either return a valid call to setGreeting or nothing (avoid halmos panicking on unknown contract call) + function gen_calldata(bytes4 selector) public view returns (bytes memory newCalldata) { + if (selector == targetContract.setGreeting.selector) { + string memory greeting = svm.createString(64, 'greeting'); + newCalldata = abi.encodeWithSelector(selector, greeting); + } + } +} From d9eed8c9fb2c164ae12b6bd8f4b44f71e563aee5 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Thu, 16 May 2024 15:02:16 +0200 Subject: [PATCH 04/35] fix: invariant + optim --- package.json | 2 +- test/invariants/Greeter.invariants.t.sol | 36 +++++++++++++++--------- test/invariants/Greeter.symbolic.t.sol | 34 +++++++++++----------- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 47caadac..b9de5ca0 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "lint:sol-tests": "solhint -c .solhint.tests.json 'test/**/*.sol'", "prepare": "husky install", "test": "forge test -vvv", - "test:fuzz": "echidna test/invariants/Greeter.invariants.t.sol --contract GreeterInvariant --corpus-dir test/invariants/echidna_coverage/", + "test:fuzz": "echidna test/invariants/Greeter.invariants.t.sol --contract GreeterInvariant --corpus-dir test/invariants/echidna_coverage/ --test-mode assertion", "test:integration": "forge test --match-contract Integration -vvv", "test:symbolic": "halmos", "test:unit": "forge test --match-contract Unit -vvv", diff --git a/test/invariants/Greeter.invariants.t.sol b/test/invariants/Greeter.invariants.t.sol index 5489d2d5..b1737420 100644 --- a/test/invariants/Greeter.invariants.t.sol +++ b/test/invariants/Greeter.invariants.t.sol @@ -3,22 +3,30 @@ pragma solidity 0.8.23; import {Greeter, IERC20} from '../../src/contracts/Greeter.sol'; -contract GreeterInvariant is Greeter { - constructor() Greeter('a', IERC20(address(1))) {} +interface IHevm { + function prank(address) external; +} + +contract GreeterInvariant { + address constant HEVM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; + IHevm hevm = IHevm(HEVM_ADDRESS); + Greeter public targetContract; - function echidna_greeterNeverEmpty() public view returns (bool) { - return keccak256(bytes(greeting)) != keccak256(''); + constructor() { + targetContract = new Greeter('a', IERC20(address(1))); } - function echidna_onlyOwnerSetsGreeting() public returns (bool) { - // new greeting set, is the sender the owner? - try this.setGreeting('hello') { - if (msg.sender != OWNER) return false; - return true; - } catch { - // new greeting failed, is the sender not the owner? - if (msg.sender == OWNER) return false; - return true; - } + function checkGreeterNeverEmpty(string memory newGreeting) public { + (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, newGreeting)); + + assert((success && keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))) || !success); + } + + function checkOnlyOwnerSetsGreeting(address caller) public { + hevm.prank(caller); + + (bool success,) = address(this).call(abi.encodeCall(Greeter.setGreeting, 'hello')); + + assert((success && msg.sender == targetContract.OWNER()) || (!success && msg.sender != targetContract.OWNER())); } } diff --git a/test/invariants/Greeter.symbolic.t.sol b/test/invariants/Greeter.symbolic.t.sol index 25fe7303..0527373d 100644 --- a/test/invariants/Greeter.symbolic.t.sol +++ b/test/invariants/Greeter.symbolic.t.sol @@ -10,22 +10,32 @@ contract GreeterSymbolic is SymTest, Test { Greeter public targetContract; function setUp() public { - string memory _initialGreeting = svm.createString(64, 'initial greeting'); - address _token = svm.createAddress('token'); + string memory initialGreeting = svm.createString(64, 'initial greeting'); + address token = svm.createAddress('token'); - targetContract = new Greeter(_initialGreeting, IERC20(_token)); + targetContract = new Greeter(initialGreeting, IERC20(token)); } - function check_validState_greeterNeverEmpty(address caller, bytes4 selector) public { + function check_validState_greeterNeverEmpty(address caller) public { // Input conditions: any caller vm.prank(caller); - // Execution - (bool success,) = address(targetContract).call(gen_calldata(selector)); + // Execution: Halmos cannot use a dynamic-sized array, iterate over multiple string lengths + for (uint256 i = 1; i < 3; i++) { + string memory greeting = svm.createString(i, 'greeting'); + (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (greeting))); + + // Output condition check + vm.assume(success); // discard failing calls + assert(keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))); + } + + // Add the empty string (bypass the non-empty check of svm.createString) + (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (''))); // Output condition check vm.assume(success); // discard failing calls - assert(keccak256(bytes(targetContract.greeting())) != keccak256('')); + assert(keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))); } function check_setGreeting_onlyOwnerSetsGreeting(address caller) public { @@ -41,15 +51,7 @@ contract GreeterSymbolic is SymTest, Test { assert(caller == targetContract.OWNER()); assert(keccak256(bytes(targetContract.greeting())) == keccak256(bytes(newGreeting))); } else { - assert(caller != targetContract.OWNER() || keccak256(bytes(newGreeting)) == keccak256('')); - } - } - - // either return a valid call to setGreeting or nothing (avoid halmos panicking on unknown contract call) - function gen_calldata(bytes4 selector) public view returns (bytes memory newCalldata) { - if (selector == targetContract.setGreeting.selector) { - string memory greeting = svm.createString(64, 'greeting'); - newCalldata = abi.encodeWithSelector(selector, greeting); + assert(caller != targetContract.OWNER() || keccak256(bytes(newGreeting)) == keccak256(bytes(''))); } } } From 1601c6c5e6485f1c4d13ca1cd8a6584f3743b4d2 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Fri, 17 May 2024 10:22:51 +0200 Subject: [PATCH 05/35] chore: dir reorg --- package.json | 2 +- .../{Greeter.invariants.t.sol => fuzz/Greeter.t.sol} | 7 ++++++- .../{Greeter.symbolic.t.sol => symbolic/Greeter.t.sol} | 5 +++-- 3 files changed, 10 insertions(+), 4 deletions(-) rename test/invariants/{Greeter.invariants.t.sol => fuzz/Greeter.t.sol} (84%) rename test/invariants/{Greeter.symbolic.t.sol => symbolic/Greeter.t.sol} (90%) diff --git a/package.json b/package.json index b9de5ca0..0c743777 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "lint:sol-tests": "solhint -c .solhint.tests.json 'test/**/*.sol'", "prepare": "husky install", "test": "forge test -vvv", - "test:fuzz": "echidna test/invariants/Greeter.invariants.t.sol --contract GreeterInvariant --corpus-dir test/invariants/echidna_coverage/ --test-mode assertion", + "test:fuzz": "echidna test/invariants/fuzz/Greeter.t.sol --contract GreeterInvariant --corpus-dir test/invariants/fuzz/echidna_coverage/ --test-mode assertion", "test:integration": "forge test --match-contract Integration -vvv", "test:symbolic": "halmos", "test:unit": "forge test --match-contract Unit -vvv", diff --git a/test/invariants/Greeter.invariants.t.sol b/test/invariants/fuzz/Greeter.t.sol similarity index 84% rename from test/invariants/Greeter.invariants.t.sol rename to test/invariants/fuzz/Greeter.t.sol index b1737420..b8182fcc 100644 --- a/test/invariants/Greeter.invariants.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.23; -import {Greeter, IERC20} from '../../src/contracts/Greeter.sol'; +import {Greeter, IERC20} from 'contracts/Greeter.sol'; interface IHevm { function prank(address) external; @@ -17,16 +17,21 @@ contract GreeterInvariant { } function checkGreeterNeverEmpty(string memory newGreeting) public { + // Execution (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, newGreeting)); + // Check output condition assert((success && keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))) || !success); } function checkOnlyOwnerSetsGreeting(address caller) public { + // Input conditions hevm.prank(caller); + // Execution (bool success,) = address(this).call(abi.encodeCall(Greeter.setGreeting, 'hello')); + // Check output condition assert((success && msg.sender == targetContract.OWNER()) || (!success && msg.sender != targetContract.OWNER())); } } diff --git a/test/invariants/Greeter.symbolic.t.sol b/test/invariants/symbolic/Greeter.t.sol similarity index 90% rename from test/invariants/Greeter.symbolic.t.sol rename to test/invariants/symbolic/Greeter.t.sol index 0527373d..525e055e 100644 --- a/test/invariants/Greeter.symbolic.t.sol +++ b/test/invariants/symbolic/Greeter.t.sol @@ -21,9 +21,10 @@ contract GreeterSymbolic is SymTest, Test { vm.prank(caller); // Execution: Halmos cannot use a dynamic-sized array, iterate over multiple string lengths + bool success; for (uint256 i = 1; i < 3; i++) { string memory greeting = svm.createString(i, 'greeting'); - (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (greeting))); + (success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (greeting))); // Output condition check vm.assume(success); // discard failing calls @@ -31,7 +32,7 @@ contract GreeterSymbolic is SymTest, Test { } // Add the empty string (bypass the non-empty check of svm.createString) - (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (''))); + (success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (''))); // Output condition check vm.assume(success); // discard failing calls From 4c17acfb11f5571fb1d9ac9a03026b04513f3491 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Fri, 17 May 2024 11:09:10 +0200 Subject: [PATCH 06/35] feat: bulloak and .tree for unit tests --- README.md | 2 + test/unit/Greeter.t.sol | 111 +++++++++++++++++++--------------------- test/unit/Greeter.tree | 25 +++++++++ 3 files changed, 79 insertions(+), 59 deletions(-) create mode 100644 test/unit/Greeter.tree diff --git a/README.md b/README.md index b2fd374a..7f350720 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@
Sample Integration, Unit, Property-based fuzzed and symbolic tests
Example tests showcasing mocking, assertions and configuration for mainnet forking. As well it includes everything needed in order to check code coverage.
+
Unit tests are built based on the Branched-Tree Technique, using Bulloak. +
Formal verification and property-based fuzzing are achieved with Halmos and Echidna (resp.).
Linter
Simple and fast solidity linting thanks to forge fmt.
diff --git a/test/unit/Greeter.t.sol b/test/unit/Greeter.t.sol index 65efebb4..2c855bf3 100644 --- a/test/unit/Greeter.t.sol +++ b/test/unit/Greeter.t.sol @@ -1,101 +1,94 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.23; import {Greeter, IGreeter} from 'contracts/Greeter.sol'; import {Test} from 'forge-std/Test.sol'; import {IERC20} from 'forge-std/interfaces/IERC20.sol'; -abstract contract Base is Test { +contract UnitGreeter is Test { address internal _owner = makeAddr('owner'); - IERC20 internal _token = IERC20(makeAddr('token')); + uint256 internal _initialBalance = 100; string internal _initialGreeting = 'hola'; - bytes32 internal _emptyString = keccak256(bytes('')); + Greeter internal _greeter; - function setUp() public virtual { - vm.etch(address(_token), new bytes(0x1)); // etch bytecode to avoid address collision problems + event GreetingSet(string _greeting); + + function setUp() external { vm.prank(_owner); _greeter = new Greeter(_initialGreeting, _token); + + vm.etch(address(_token), new bytes(0x1)); } -} -contract UnitGreeterConstructor is Base { - function test_OwnerSet(address _owner) public { + function test_ConstructorWhenPassingValidGreetingString() external { vm.prank(_owner); + + // it deploys _greeter = new Greeter(_initialGreeting, _token); - assertEq(_greeter.OWNER(), _owner); - } + // it sets the greeting string + assertEq(_greeter.greeting(), _initialGreeting); - function test_TokenSet(IERC20 _token) public { - _greeter = new Greeter(_initialGreeting, _token); + // it sets the owner as sender + assertEq(_greeter.OWNER(), _owner); + // it sets the token used assertEq(address(_greeter.token()), address(_token)); } - function test_GreetingSet(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); + function test_ConstructorWhenPassingAnEmptyGreetingString() external { + vm.prank(_owner); - _greeter = new Greeter(_greeting, _token); - assertEq(_greeting, _greeter.greeting()); + // it reverts + vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); + _greeter = new Greeter('', _token); } -} - -contract UnitGreeterSetGreeting is Base { - event GreetingSet(string _greeting); - function setUp() public override { - super.setUp(); - vm.startPrank(_owner); - } + function test_GreetWhenCalled() external { + vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(_initialBalance)); + vm.expectCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector)); + (string memory _greet, uint256 _balance) = _greeter.greet(); - function test_RevertIfNotOwner(address _caller, string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - vm.assume(_caller != _owner); + // it returns the greeting string + assertEq(_greet, _initialGreeting); - vm.stopPrank(); - vm.prank(_caller); - - vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); - _greeter.setGreeting(_greeting); - } - - function test_RevertIfEmptyGreeting() public { - vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); - _greeter.setGreeting(''); + // it returns the token balance of the contract + assertEq(_balance, _initialBalance); } - function test_SetGreeting(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); - _greeter.setGreeting(_greeting); - - assertEq(_greeting, _greeter.greeting()); + modifier whenCalledByTheOwner() { + vm.startPrank(_owner); + _; + vm.stopPrank(); } - function test_EmitEvent(string memory _greeting) public { - vm.assume(keccak256(bytes(_greeting)) != _emptyString); + function test_SetGreetingWhenPassingAValidGreetingString() external whenCalledByTheOwner { + string memory _newGreeting = 'hello'; + // it emit GreetingSet vm.expectEmit(true, true, true, true, address(_greeter)); - emit GreetingSet(_greeting); + emit GreetingSet(_newGreeting); - _greeter.setGreeting(_greeting); - } -} - -contract UnitGreeterGreet is Base { - function test_GetGreeting() public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector), abi.encode(0)); + _greeter.setGreeting(_newGreeting); - (string memory _greeting,) = _greeter.greet(); - assertEq(_initialGreeting, _greeting); + // it sets the greeting string + assertEq(_greeter.greeting(), _newGreeting); } - function test_GetTokenBalance(address _caller, uint256 _balance) public { - vm.mockCall(address(_token), abi.encodeWithSelector(IERC20.balanceOf.selector, _caller), abi.encode(_balance)); + function test_SetGreetingWhenPassingAnEmptyGreetingString() external whenCalledByTheOwner { + // it reverts + vm.expectRevert(IGreeter.Greeter_InvalidGreeting.selector); + _greeter.setGreeting(''); + } + function test_SetGreetingWhenCalledByANon_owner(address _caller) external { + vm.assume(_caller != _owner); vm.prank(_caller); - (, uint256 _greetBalance) = _greeter.greet(); - assertEq(_balance, _greetBalance); + + // it reverts + vm.expectRevert(IGreeter.Greeter_OnlyOwner.selector); + _greeter.setGreeting('new greeting'); } } diff --git a/test/unit/Greeter.tree b/test/unit/Greeter.tree new file mode 100644 index 00000000..bbc74ea5 --- /dev/null +++ b/test/unit/Greeter.tree @@ -0,0 +1,25 @@ +Greeter::constructor +├── when passing valid greeting string +│ ├── it deploys +│ ├── it sets the greeting string +│ ├── it sets the owner as sender +│ └── it sets the token used +└── when passing an empty greeting string + └── it reverts + + +Greeter::greet +└── when called + ├── it returns the greeting string + └── it returns the token balance of the contract + + +Greeter::setGreeting +├── when called by the owner +│ ├── when passing a valid greeting string +│ │ ├── it sets the greeting string +│ │ └── it emit GreetingSet +│ └── when passing an empty greeting string +│ └── it reverts +└── when called by a non-owner + └── it reverts \ No newline at end of file From fcadbe4037b46e75315a47feb045ef00317432d2 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Fri, 17 May 2024 11:09:27 +0200 Subject: [PATCH 07/35] feat: slither CI --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e7b79eeb..78094509 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,28 @@ env: SEPOLIA_RPC: ${{ secrets.SEPOLIA_RPC }} jobs: + static-test: + name: slither + runs-on: ubuntu-latest + env: + NODE_ENV: production + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions/setup-node@v4 + with: + node-version: latest + - name: Install npm dependencies + run: npm ci --production + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + - name: Run slither + uses: crytic/slither-action@v0.3.1 + with: + slither-config: slither-ci.config.json + fail-on: medium + unit-tests: name: Run Unit Tests runs-on: ubuntu-latest @@ -64,6 +86,8 @@ jobs: - name: Run tests run: yarn test:integration + + lint: name: Lint Commit Messages runs-on: ubuntu-latest From fdc7473a8ed1a7a3f90f9b0a17b37be28cc16153 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Fri, 17 May 2024 17:58:41 +0200 Subject: [PATCH 08/35] chore: ci test and cov prototype --- .github/workflows/check_coverage_ci.yml | 70 ++++++++++++++++++++++++ .github/workflows/ci.yml | 52 +++++++++++++++++- .github/workflows/upload_coverage_ci.yml | 39 +++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/check_coverage_ci.yml create mode 100644 .github/workflows/upload_coverage_ci.yml diff --git a/.github/workflows/check_coverage_ci.yml b/.github/workflows/check_coverage_ci.yml new file mode 100644 index 00000000..3bd93de4 --- /dev/null +++ b/.github/workflows/check_coverage_ci.yml @@ -0,0 +1,70 @@ +name: Upload coverage on merge + +on: + push: + branches: + - main + +jobs: + upload-coverage: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'yarn' + - name: Install dependencies + run: yarn --frozen-lockfile --network-concurrency 1 + - name: Precompile using 0.8.14 and via-ir=false + run: yarn build + - name: Run coverage + shell: bash + run: forge coverage --report summary --report lcov + - name: Setup LCOV + uses: hrishikesh-kadam/setup-lcov@v1 + - name: Filter directories + run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcovNew.info --rc lcov_branch_coverage=1 + + - name: Retrieve previous coverage + uses: actions/download-artifact@v2 + with: + name: coverage + path: lcov.info + + - name: Verify previous coverage + uses: zgosalvez/github-actions-report-lcov@v4 + with: + coverage-files: ./lcov.info + + - name: Verify new coverage + uses: zgosalvez/github-actions-report-lcov@v4 + with: + coverage-files: ./lcovNew.info + + - name: Check if new >= old + run: | + old=$(awk -F" " '/lines/ {print $3}' lcov.info) + new=$(awk -F" " '/lines/ {print $3}' lcovNew.info) + if [ "$new" -lt "$old" ]; then + echo "Coverage decreased from $old to $new" + exit 1 + fi + + - name: Cleanup + run: | + rm lcov.info + mv lcovNew.info lcov.info + + - name: Upload new coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: lcovNew.info \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 78094509..7c848905 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,7 +86,57 @@ jobs: - name: Run tests run: yarn test:integration - + echidna-tests: + name: Echidna Test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Compile contracts + run: | + forge build --build-info + + - name: Run Echidna + uses: crytic/echidna-action@v2 + with: + files: . + contract: GreeterInvariant + crytic-args: --ignore-compile + + halmos-tests: + name: Run symbolic execution tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'yarn' + + - name: Install dependencies + run: yarn --frozen-lockfile --network-concurrency 1 + + - name: Precompile using 0.8.14 and via-ir=false + run: yarn build + + - name: Run tests + run: yarn test:integration lint: name: Lint Commit Messages diff --git a/.github/workflows/upload_coverage_ci.yml b/.github/workflows/upload_coverage_ci.yml new file mode 100644 index 00000000..8bde798a --- /dev/null +++ b/.github/workflows/upload_coverage_ci.yml @@ -0,0 +1,39 @@ +name: Upload coverage on merge + +on: + push: + branches: + - main + +jobs: + upload-coverage: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'yarn' + - name: Install dependencies + run: yarn --frozen-lockfile --network-concurrency 1 + - name: Precompile using 0.8.14 and via-ir=false + run: yarn build + - name: Run coverage + shell: bash + run: forge coverage --report summary --report lcov + - name: Setup LCOV + uses: hrishikesh-kadam/setup-lcov@v1 + - name: Filter directories + run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc lcov_branch_coverage=1 + - name: Upload coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: lcov.info \ No newline at end of file From 9a51d1f8b02df65663886eeea09850b517479def Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Sat, 18 May 2024 15:26:34 +0200 Subject: [PATCH 09/35] feat: coverage check CI --- ...eck_coverage_ci.yml => coverage_check.yml} | 52 ++++++++++--------- .github/workflows/upload_coverage_ci.yml | 39 -------------- 2 files changed, 27 insertions(+), 64 deletions(-) rename .github/workflows/{check_coverage_ci.yml => coverage_check.yml} (57%) delete mode 100644 .github/workflows/upload_coverage_ci.yml diff --git a/.github/workflows/check_coverage_ci.yml b/.github/workflows/coverage_check.yml similarity index 57% rename from .github/workflows/check_coverage_ci.yml rename to .github/workflows/coverage_check.yml index 3bd93de4..5c035f5a 100644 --- a/.github/workflows/check_coverage_ci.yml +++ b/.github/workflows/coverage_check.yml @@ -1,4 +1,4 @@ -name: Upload coverage on merge +name: Coverage check on main push on: push: @@ -16,55 +16,57 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 with: version: nightly + - name: Use Node.js uses: actions/setup-node@v3 with: node-version: 18.x cache: 'yarn' + - name: Install dependencies run: yarn --frozen-lockfile --network-concurrency 1 - - name: Precompile using 0.8.14 and via-ir=false - run: yarn build + - name: Run coverage shell: bash run: forge coverage --report summary --report lcov + - name: Setup LCOV uses: hrishikesh-kadam/setup-lcov@v1 + - name: Filter directories - run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcovNew.info --rc lcov_branch_coverage=1 + run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 + + - name: Capture coverage output + id: capture-coverage + run: | + COVERAGE_OUTPUT=$(zgosalvez/github-actions-report-lcov@v3 --coverage-files lcov.info) + echo "new_coverage=$COVERAGE_OUTPUT" >> $GITHUB_ENV - name: Retrieve previous coverage uses: actions/download-artifact@v2 with: name: coverage - path: lcov.info + path: coverage.info + continue-on-error: true - - name: Verify previous coverage - uses: zgosalvez/github-actions-report-lcov@v4 - with: - coverage-files: ./lcov.info + - name: Check if a previous coverage exists + run: | + if [ ! -f lcov.info ]; then + echo "Artifact not found. Initializing at 0" + echo "0" >> coverage.info + fi - - name: Verify new coverage - uses: zgosalvez/github-actions-report-lcov@v4 - with: - coverage-files: ./lcovNew.info - - - name: Check if new >= old + - name: Compare previous coverage run: | - old=$(awk -F" " '/lines/ {print $3}' lcov.info) - new=$(awk -F" " '/lines/ {print $3}' lcovNew.info) + old=$(cat coverage.info) + new=$(echo $COVERAGE_OUTPUT) if [ "$new" -lt "$old" ]; then echo "Coverage decreased from $old to $new" exit 1 fi - - - name: Cleanup - run: | - rm lcov.info - mv lcovNew.info lcov.info - - - name: Upload new coverage + + - name: Upload the new coverage uses: actions/upload-artifact@v2 with: name: coverage - path: lcovNew.info \ No newline at end of file + path: coverage.info \ No newline at end of file diff --git a/.github/workflows/upload_coverage_ci.yml b/.github/workflows/upload_coverage_ci.yml deleted file mode 100644 index 8bde798a..00000000 --- a/.github/workflows/upload_coverage_ci.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Upload coverage on merge - -on: - push: - branches: - - main - -jobs: - upload-coverage: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.x - cache: 'yarn' - - name: Install dependencies - run: yarn --frozen-lockfile --network-concurrency 1 - - name: Precompile using 0.8.14 and via-ir=false - run: yarn build - - name: Run coverage - shell: bash - run: forge coverage --report summary --report lcov - - name: Setup LCOV - uses: hrishikesh-kadam/setup-lcov@v1 - - name: Filter directories - run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc lcov_branch_coverage=1 - - name: Upload coverage - uses: actions/upload-artifact@v2 - with: - name: coverage - path: lcov.info \ No newline at end of file From 35351b383c98e43b2ac6bf91d2ed72dd35991956 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Sat, 18 May 2024 15:28:30 +0200 Subject: [PATCH 10/35] fix: ci trigger --- .github/workflows/coverage_check.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index 5c035f5a..d8151ff4 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -1,9 +1,6 @@ name: Coverage check on main push -on: - push: - branches: - - main +on: [push] jobs: upload-coverage: From a2a98b98d6f3c625c1617d1a26a7b47cec132780 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Sat, 18 May 2024 21:55:20 +0200 Subject: [PATCH 11/35] fix: coverage action --- .github/workflows/coverage_check.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index d8151ff4..0ba2ae5e 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -34,10 +34,10 @@ jobs: run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 - name: Capture coverage output - id: capture-coverage - run: | - COVERAGE_OUTPUT=$(zgosalvez/github-actions-report-lcov@v3 --coverage-files lcov.info) - echo "new_coverage=$COVERAGE_OUTPUT" >> $GITHUB_ENV + id: new-coverage + uses: zgosalvez/github-actions-report-lcov@v3 + with: + coverage-files: lcov.info - name: Retrieve previous coverage uses: actions/download-artifact@v2 @@ -56,7 +56,7 @@ jobs: - name: Compare previous coverage run: | old=$(cat coverage.info) - new=$(echo $COVERAGE_OUTPUT) + new=${{ steps.new-coverage.outputs.total-coverage }} if [ "$new" -lt "$old" ]; then echo "Coverage decreased from $old to $new" exit 1 From 16316809f19f43b2611cba4bd2a3146215c5d0a7 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Sat, 18 May 2024 21:59:15 +0200 Subject: [PATCH 12/35] fix: typo --- .github/workflows/coverage_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index 0ba2ae5e..38499935 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -48,7 +48,7 @@ jobs: - name: Check if a previous coverage exists run: | - if [ ! -f lcov.info ]; then + if [ ! -f coverage.info ]; then echo "Artifact not found. Initializing at 0" echo "0" >> coverage.info fi From 9f24c9bc0141d0aab74bb060b4f244b674cc3d97 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 13:41:59 +0200 Subject: [PATCH 13/35] feat: coverage check on push --- .github/workflows/coverage_check.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index 38499935..edb09c0d 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -2,6 +2,9 @@ name: Coverage check on main push on: [push] +env: + COVERAGE_SENSITIVITY_PERCENT: 1 + jobs: upload-coverage: runs-on: ubuntu-latest @@ -31,13 +34,13 @@ jobs: uses: hrishikesh-kadam/setup-lcov@v1 - name: Filter directories - run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 + run: lcov --remove lcov.info 'test/*' 'script/*' --output-file lcovNew.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 --ignore-errors unused - name: Capture coverage output id: new-coverage uses: zgosalvez/github-actions-report-lcov@v3 with: - coverage-files: lcov.info + coverage-files: lcovNew.info - name: Retrieve previous coverage uses: actions/download-artifact@v2 @@ -56,11 +59,12 @@ jobs: - name: Compare previous coverage run: | old=$(cat coverage.info) - new=${{ steps.new-coverage.outputs.total-coverage }} + new=$(( ${{ steps.new-coverage.outputs.total-coverage }} + ${{ env.COVERAGE_SENSITIVITY_PERCENT }} )) if [ "$new" -lt "$old" ]; then echo "Coverage decreased from $old to $new" exit 1 fi + mv lcovNew.info coverage.info - name: Upload the new coverage uses: actions/upload-artifact@v2 From 322c31776fce4e6285da40a0af597ddb660c3249 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 14:26:04 +0200 Subject: [PATCH 14/35] chore: slither config file --- .github/workflows/{ci.yml => tests.yml} | 2 +- slither.config.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) rename .github/workflows/{ci.yml => tests.yml} (98%) create mode 100644 slither.config.json diff --git a/.github/workflows/ci.yml b/.github/workflows/tests.yml similarity index 98% rename from .github/workflows/ci.yml rename to .github/workflows/tests.yml index 7c848905..09a2f59c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,7 @@ jobs: - name: Run slither uses: crytic/slither-action@v0.3.1 with: - slither-config: slither-ci.config.json + slither-config: slither.config.json fail-on: medium unit-tests: diff --git a/slither.config.json b/slither.config.json new file mode 100644 index 00000000..22ebc22f --- /dev/null +++ b/slither.config.json @@ -0,0 +1,10 @@ +{ + "detectors_to_exclude": "timestamp,uninitialized-local", + "exclude_informational": true, + "exclude_low": false, + "exclude_medium": false, + "exclude_high": false, + "disable_color": false, + "filter_paths": "(test/|node_modules/|script/)", + "legacy_ast": false +} \ No newline at end of file From 0a812acacb5030fc51f318c73691efdad7716311 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 16:08:56 +0200 Subject: [PATCH 15/35] chore: no empty block in tests --- .solhint.tests.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.solhint.tests.json b/.solhint.tests.json index e208b5f4..ecbf37ec 100644 --- a/.solhint.tests.json +++ b/.solhint.tests.json @@ -10,7 +10,7 @@ "var-name-mixedcase": "off", "const-name-snakecase": "off", "no-inline-assembly": "off", - "no-empty-blocks": "off", + "no-empty-blocks": "error", "definition-name-capwords": "off", "named-parameters-function": "off", "no-global-import": "off", From a5f2328d657e7d6129d4df3da59bef6514f9f38e Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 16:35:01 +0200 Subject: [PATCH 16/35] chore: naming --- test/invariants/fuzz/Greeter.t.sol | 2 +- test/invariants/symbolic/Greeter.t.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol index b8182fcc..2aa39942 100644 --- a/test/invariants/fuzz/Greeter.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -7,7 +7,7 @@ interface IHevm { function prank(address) external; } -contract GreeterInvariant { +contract InvariantGreeter { address constant HEVM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; IHevm hevm = IHevm(HEVM_ADDRESS); Greeter public targetContract; diff --git a/test/invariants/symbolic/Greeter.t.sol b/test/invariants/symbolic/Greeter.t.sol index 525e055e..763a99a7 100644 --- a/test/invariants/symbolic/Greeter.t.sol +++ b/test/invariants/symbolic/Greeter.t.sol @@ -6,7 +6,7 @@ import {Greeter, IERC20} from 'contracts/Greeter.sol'; import {Test} from 'forge-std/Test.sol'; import {SymTest} from 'halmos-cheatcodes/src/SymTest.sol'; -contract GreeterSymbolic is SymTest, Test { +contract SymbolicGreeter is SymTest, Test { Greeter public targetContract; function setUp() public { From acc98d4695136b0fccd18ed1eb88ee2cd7a0e6c3 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 16:40:07 +0200 Subject: [PATCH 17/35] chore: ci dep --- .github/workflows/tests.yml | 71 ++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 09a2f59c..70be1df4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -17,16 +17,22 @@ jobs: env: NODE_ENV: production steps: - - uses: actions/checkout@v4 - with: - submodules: recursive - - uses: actions/setup-node@v4 - with: - node-version: latest - - name: Install npm dependencies - run: npm ci --production + - uses: actions/checkout@v3 + - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'yarn' + + - name: Install dependencies + run: yarn --frozen-lockfile --network-concurrency 1 + - name: Run slither uses: crytic/slither-action@v0.3.1 with: @@ -91,26 +97,35 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v3 - with: - submodules: recursive - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Compile contracts - run: | - forge build --build-info - - - name: Run Echidna - uses: crytic/echidna-action@v2 - with: - files: . - contract: GreeterInvariant - crytic-args: --ignore-compile + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Use Node.js + uses: actions/setup-node@v3 + with: + node-version: 18.x + cache: 'yarn' + + - name: Install dependencies + run: yarn --frozen-lockfile --network-concurrency 1 + + - name: Compile contracts + run: | + forge build --build-info + + - name: Run Echidna + uses: crytic/echidna-action@v2 + with: + files: . + contract: GreeterInvariant + crytic-args: --ignore-compile halmos-tests: name: Run symbolic execution tests From ac3d43899a6289ecfc9284fdf3a7675ac0fbd2c0 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 16:41:27 +0200 Subject: [PATCH 18/35] fix: typo echidna --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 70be1df4..c337f66a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: - name: Install dependencies run: yarn --frozen-lockfile --network-concurrency 1 - + - name: Run slither uses: crytic/slither-action@v0.3.1 with: @@ -124,7 +124,7 @@ jobs: uses: crytic/echidna-action@v2 with: files: . - contract: GreeterInvariant + contract: InvariantGreeter crytic-args: --ignore-compile halmos-tests: From f7884a03b8451f486370bfe50b58a72e4d539da3 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 17:48:04 +0200 Subject: [PATCH 19/35] fix: echidna test mode --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c337f66a..07fd7202 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -125,7 +125,7 @@ jobs: with: files: . contract: InvariantGreeter - crytic-args: --ignore-compile + crytic-args: --ignore-compile --test-mode assertion halmos-tests: name: Run symbolic execution tests From 9d512ba4b1a0bf9bf6c358086f814e22921b21a9 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 17:52:10 +0200 Subject: [PATCH 20/35] fix: test mode --- .github/workflows/tests.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 07fd7202..326e88c1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,6 +33,9 @@ jobs: - name: Install dependencies run: yarn --frozen-lockfile --network-concurrency 1 + - name: Compile contracts + run: yarn build + - name: Run slither uses: crytic/slither-action@v0.3.1 with: @@ -125,7 +128,8 @@ jobs: with: files: . contract: InvariantGreeter - crytic-args: --ignore-compile --test-mode assertion + test-mode: assertion + crytic-args: --ignore-compile halmos-tests: name: Run symbolic execution tests From 55f839cd864dfdbb9843c2a9e133a52040412447 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 17:55:22 +0200 Subject: [PATCH 21/35] chore: lock bump --- yarn.lock | 277 ++++++++++++++++++++++++++---------------------------- 1 file changed, 131 insertions(+), 146 deletions(-) diff --git a/yarn.lock b/yarn.lock index ecc94089..7cdad647 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,26 +3,27 @@ "@babel/code-frame@^7.0.0": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.4.tgz#03ae5af150be94392cb5c7ccd97db5a19a5da6aa" - integrity sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA== + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== +"@babel/highlight@^7.24.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" + integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== dependencies: - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-validator-identifier" "^7.24.5" chalk "^2.4.2" js-tokens "^4.0.0" + picocolors "^1.0.0" "@commitlint/cli@19.3.0": version "19.3.0" @@ -259,9 +260,9 @@ "@types/node" "*" "@types/node@*": - version "20.9.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.4.tgz#cc8f970e869c26834bdb7ed480b30ede622d74c7" - integrity sha512-wmyg8HUhcn6ACjsn8oKYjkN/zUzQeNtMy44weTJSM6p4MMzEOuKbA3OjJ267uPCOW7Xex9dyrNTful8XTQYoDA== + version "20.12.12" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.12.tgz#7cbecdf902085cec634fdb362172dfe12b8f2050" + integrity sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw== dependencies: undici-types "~5.26.4" @@ -288,17 +289,7 @@ ajv@^6.12.6: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^8.11.0: +ajv@^8.0.1, ajv@^8.11.0: version "8.13.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91" integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== @@ -308,12 +299,10 @@ ajv@^8.11.0: require-from-string "^2.0.2" uri-js "^4.4.1" -ansi-escapes@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6" - integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA== - dependencies: - type-fest "^1.0.2" +ansi-escapes@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-6.2.1.tgz#76c54ce9b081dad39acec4b5d53377913825fb0f" + integrity sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig== ansi-regex@^5.0.1: version "5.0.1" @@ -339,7 +328,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-styles@^6.0.0, ansi-styles@^6.1.0: +ansi-styles@^6.0.0, ansi-styles@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== @@ -387,9 +376,9 @@ available-typed-arrays@^1.0.7: possible-typed-array-names "^1.0.0" axios@^1.6.7: - version "1.6.8" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" - integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== + version "1.7.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.1.tgz#522145622a09dfaf49359837db9649ff245a35b9" + integrity sha512-+LV37nQcd1EpFalkXksWNBiA17NZ5m5/WspmHGmZmdx1qBOg/VNq/c4eRJiA9VQQHBOs+N0ZhhdU10h2TyNK7Q== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" @@ -459,13 +448,13 @@ cli-cursor@^4.0.0: dependencies: restore-cursor "^4.0.0" -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== +cli-truncate@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-4.0.0.tgz#6cc28a2924fee9e25ce91e973db56c7066e6172a" + integrity sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA== dependencies: slice-ansi "^5.0.0" - string-width "^5.0.0" + string-width "^7.0.0" cliui@^8.0.1: version "8.0.1" @@ -523,9 +512,9 @@ commander@11.1.0, commander@^11.1.0: integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== commander@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-12.0.0.tgz#b929db6df8546080adfd004ab215ed48cf6f2592" - integrity sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA== + version "12.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" + integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA== commander@^8.1.0: version "8.3.0" @@ -660,21 +649,16 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +emoji-regex@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-10.3.0.tgz#76998b9268409eb3dae3de989254d456e70cfe23" + integrity sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw== emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - env-paths@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -773,9 +757,9 @@ fast-json-stable-stringify@^2.0.0: integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -805,12 +789,7 @@ findup-sync@^5.0.0: micromatch "^4.0.4" resolve-dir "^1.0.1" -follow-redirects@^1.12.1: - version "1.15.5" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" - integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== - -follow-redirects@^1.15.6: +follow-redirects@^1.12.1, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -859,6 +838,11 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-east-asian-width@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz#5e6ebd9baee6fb8b7b6bd505221065f0cd91f64e" + integrity sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA== + get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" @@ -1020,14 +1004,14 @@ human-signals@^5.0.0: integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== husky@>=8: - version "8.0.3" - resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" - integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== + version "9.0.11" + resolved "https://registry.yarnpkg.com/husky/-/husky-9.0.11.tgz#fc91df4c756050de41b3e478b2158b87c1e79af9" + integrity sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw== ignore@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== import-fresh@^3.3.0: version "3.3.0" @@ -1038,9 +1022,9 @@ import-fresh@^3.3.0: resolve-from "^4.0.0" import-meta-resolve@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz#0b1195915689f60ab00f830af0f15cc841e8919e" - integrity sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA== + version "4.1.0" + resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz#f9db8bead9fafa61adb811db77a2bf22c5399706" + integrity sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw== inflight@^1.0.4: version "1.0.6" @@ -1098,6 +1082,13 @@ is-fullwidth-code-point@^4.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== +is-fullwidth-code-point@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz#9609efced7c2f97da7b60145ef481c787c7ba704" + integrity sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA== + dependencies: + get-east-asian-width "^1.0.0" + is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" @@ -1212,10 +1203,10 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -lilconfig@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== +lilconfig@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc" + integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g== lines-and-columns@^1.1.6: version "1.2.4" @@ -1223,32 +1214,32 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lint-staged@>=10: - version "15.1.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.1.0.tgz#c0f8e4d96ac3c09beac5c76d08524d6000c207b4" - integrity sha512-ZPKXWHVlL7uwVpy8OZ7YQjYDAuO5X4kMh0XgZvPNxLcCCngd0PO5jKQyy3+s4TL2EnHoIXIzP1422f/l3nZKMw== + version "15.2.2" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.2.2.tgz#ad7cbb5b3ab70e043fa05bff82a09ed286bc4c5f" + integrity sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw== dependencies: chalk "5.3.0" commander "11.1.0" debug "4.3.4" execa "8.0.1" - lilconfig "2.1.0" - listr2 "7.0.2" + lilconfig "3.0.0" + listr2 "8.0.1" micromatch "4.0.5" pidtree "0.6.0" string-argv "0.3.2" yaml "2.3.4" -listr2@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-7.0.2.tgz#3aa3e1549dfaf3c57ab5eeaba754da3b87f33063" - integrity sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g== +listr2@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-8.0.1.tgz#4d3f50ae6cec3c62bdf0e94f5c2c9edebd4b9c34" + integrity sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA== dependencies: - cli-truncate "^3.1.0" + cli-truncate "^4.0.0" colorette "^2.0.20" eventemitter3 "^5.0.1" - log-update "^5.0.1" + log-update "^6.0.0" rfdc "^1.3.0" - wrap-ansi "^8.1.0" + wrap-ansi "^9.0.0" locate-path@^7.2.0: version "7.2.0" @@ -1312,23 +1303,16 @@ lodash@^4.17.21: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-update@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-5.0.1.tgz#9e928bf70cb183c1f0c9e91d9e6b7115d597ce09" - integrity sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw== - dependencies: - ansi-escapes "^5.0.0" - cli-cursor "^4.0.0" - slice-ansi "^5.0.0" - strip-ansi "^7.0.1" - wrap-ansi "^8.0.1" - -lru-cache@^6.0.0: +log-update@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.0.0.tgz#0ddeb7ac6ad658c944c1de902993fce7c33f5e59" + integrity sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw== dependencies: - yallist "^4.0.0" + ansi-escapes "^6.2.0" + cli-cursor "^4.0.0" + slice-ansi "^7.0.0" + strip-ansi "^7.1.0" + wrap-ansi "^9.0.0" memorystream@^0.3.1: version "0.3.1" @@ -1398,9 +1382,9 @@ ms@2.1.2: integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== dependencies: path-key "^4.0.0" @@ -1486,6 +1470,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +picocolors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -1568,9 +1557,9 @@ reusify@^1.0.4: integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + version "1.3.1" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.1.tgz#2b6d4df52dffe8bb346992a10ea9451f24373a8f" + integrity sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg== run-parallel@^1.1.9: version "1.2.0" @@ -1590,11 +1579,9 @@ semver@^6.3.0: integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" + version "7.6.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.2.tgz#1e3b34759f896e8f14d6134732ce798aeb0c6e13" + integrity sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w== set-function-length@^1.2.1: version "1.2.2" @@ -1652,6 +1639,14 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +slice-ansi@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-7.1.0.tgz#cd6b4655e298a8d1bdeb04250a433094b347b9a9" + integrity sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg== + dependencies: + ansi-styles "^6.2.1" + is-fullwidth-code-point "^5.0.0" + solc-typed-ast@18.1.2: version "18.1.2" resolved "https://registry.yarnpkg.com/solc-typed-ast/-/solc-typed-ast-18.1.2.tgz#bc958fe3aead765cf6c2e06ce3d53c61fd06e70c" @@ -1749,14 +1744,14 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.0, string-width@^5.0.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== +string-width@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-7.1.0.tgz#d994252935224729ea3719c49f7206dc9c46550a" + integrity sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw== dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" + emoji-regex "^10.3.0" + get-east-asian-width "^1.0.0" + strip-ansi "^7.1.0" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" @@ -1765,7 +1760,7 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.1: +strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== @@ -1792,9 +1787,9 @@ supports-color@^7.1.0: has-flag "^4.0.0" table@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + version "6.8.2" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.2.tgz#c5504ccf201213fa227248bdc8c5569716ac6c58" + integrity sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA== dependencies: ajv "^8.0.1" lodash.truncate "^4.4.2" @@ -1831,11 +1826,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -type-fest@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" - integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== - undici-types@~5.26.4: version "5.26.5" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" @@ -1948,14 +1938,14 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== +wrap-ansi@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-9.0.0.tgz#1a3dc8b70d85eeb8398ddfb1e4a02cd186e58b3e" + integrity sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q== dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" + ansi-styles "^6.2.1" + string-width "^7.0.0" + strip-ansi "^7.1.0" wrappy@1: version "1.0.2" @@ -1967,11 +1957,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@2.3.4: version "2.3.4" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" @@ -2001,6 +1986,6 @@ yocto-queue@^1.0.0: integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== zod@^3.21.4: - version "3.23.6" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.6.tgz#c08a977e2255dab1fdba933651584a05fcbf19e1" - integrity sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA== + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== From db361f3bd74fdd96c6b45d54c2c6efc6f3006689 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 18:06:22 +0200 Subject: [PATCH 22/35] fix: rm slither from ci --- .github/workflows/tests.yml | 31 ------------------------------- slither.config.json | 10 ---------- 2 files changed, 41 deletions(-) delete mode 100644 slither.config.json diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 326e88c1..8e11c693 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,37 +11,6 @@ env: SEPOLIA_RPC: ${{ secrets.SEPOLIA_RPC }} jobs: - static-test: - name: slither - runs-on: ubuntu-latest - env: - NODE_ENV: production - steps: - - uses: actions/checkout@v3 - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.x - cache: 'yarn' - - - name: Install dependencies - run: yarn --frozen-lockfile --network-concurrency 1 - - - name: Compile contracts - run: yarn build - - - name: Run slither - uses: crytic/slither-action@v0.3.1 - with: - slither-config: slither.config.json - fail-on: medium - unit-tests: name: Run Unit Tests runs-on: ubuntu-latest diff --git a/slither.config.json b/slither.config.json deleted file mode 100644 index 22ebc22f..00000000 --- a/slither.config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "detectors_to_exclude": "timestamp,uninitialized-local", - "exclude_informational": true, - "exclude_low": false, - "exclude_medium": false, - "exclude_high": false, - "disable_color": false, - "filter_paths": "(test/|node_modules/|script/)", - "legacy_ast": false -} \ No newline at end of file From 53d12b9f0011bd784413921cba3cd7f559ce2fe2 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 23:09:55 +0200 Subject: [PATCH 23/35] feat: empty unit test example --- test/unit/Greeter.t.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/unit/Greeter.t.sol b/test/unit/Greeter.t.sol index 2c855bf3..82f59c91 100644 --- a/test/unit/Greeter.t.sol +++ b/test/unit/Greeter.t.sol @@ -22,6 +22,11 @@ contract UnitGreeter is Test { vm.etch(address(_token), new bytes(0x1)); } + function test_EmptyTestExample() external { + // it does nothing + vm.skip(true); + } + function test_ConstructorWhenPassingValidGreetingString() external { vm.prank(_owner); From c15ac7abd21876994a61b3b024bb3451c316d346 Mon Sep 17 00:00:00 2001 From: GoNoGo <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 23:22:36 +0200 Subject: [PATCH 24/35] Update .github/workflows/coverage_check.yml Co-authored-by: Gas <86567384+gas1cent@users.noreply.github.com> --- .github/workflows/coverage_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index edb09c0d..f39747cd 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -18,7 +18,7 @@ jobs: version: nightly - name: Use Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18.x cache: 'yarn' From e7643545332375d27c216cfe1e59e059bf25d6de Mon Sep 17 00:00:00 2001 From: GoNoGo <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 23:22:43 +0200 Subject: [PATCH 25/35] Update .github/workflows/coverage_check.yml Co-authored-by: Gas <86567384+gas1cent@users.noreply.github.com> --- .github/workflows/coverage_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index f39747cd..b46fdb99 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 From 494dec86dd33fa929b821562a9062c7b4a2c2a4b Mon Sep 17 00:00:00 2001 From: GoNoGo <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 23:22:51 +0200 Subject: [PATCH 26/35] Update .github/workflows/coverage_check.yml Co-authored-by: Gas <86567384+gas1cent@users.noreply.github.com> --- .github/workflows/coverage_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index b46fdb99..97578c6b 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -38,7 +38,7 @@ jobs: - name: Capture coverage output id: new-coverage - uses: zgosalvez/github-actions-report-lcov@v3 + uses: zgosalvez/github-actions-report-lcov@v4 with: coverage-files: lcovNew.info From 8f46e6b33bc69f206d67b0df64e6dee7515ee676 Mon Sep 17 00:00:00 2001 From: GoNoGo <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 20 May 2024 23:34:09 +0200 Subject: [PATCH 27/35] Update .github/workflows/tests.yml Co-authored-by: Gas <86567384+gas1cent@users.noreply.github.com> --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8e11c693..52de2d36 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -120,7 +120,7 @@ jobs: - name: Install dependencies run: yarn --frozen-lockfile --network-concurrency 1 - - name: Precompile using 0.8.14 and via-ir=false + - name: Precompile with via-ir=false run: yarn build - name: Run tests From 380d7ab5c25e3dc6e66d0003e8b50876ee28f7f9 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Mon, 27 May 2024 17:13:52 +0200 Subject: [PATCH 28/35] chore: commit lint --- test/invariants/fuzz/Greeter.t.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol index 2aa39942..40608cfa 100644 --- a/test/invariants/fuzz/Greeter.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -8,6 +8,7 @@ interface IHevm { } contract InvariantGreeter { + // See https://github.com/a16z/halmos-cheatcodes?tab=readme-ov-file address constant HEVM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; IHevm hevm = IHevm(HEVM_ADDRESS); Greeter public targetContract; From b408a95aca2a8cf4d1e05900a81a14d50a6f6cd2 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Tue, 28 May 2024 11:35:06 +0200 Subject: [PATCH 29/35] fix: solhint wrong rule naming --- .solhint.tests.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.solhint.tests.json b/.solhint.tests.json index ecbf37ec..fb26b4ea 100644 --- a/.solhint.tests.json +++ b/.solhint.tests.json @@ -6,7 +6,7 @@ "quotes": ["error", "single"], "func-visibility": ["warn", { "ignoreConstructors": true }], "not-rely-on-time": "off", - "func-name-mixedcase": "off", + "style-guide-casing": "off", "var-name-mixedcase": "off", "const-name-snakecase": "off", "no-inline-assembly": "off", @@ -16,7 +16,7 @@ "no-global-import": "off", "max-states-count": "off", "private-vars-leading-underscore": ["warn", { "strict": false }], - "ordering": "warn", + "ordering": "off", "immutable-name-snakecase": "warn", "avoid-low-level-calls": "off", "one-contract-per-file": "off", From 37581e67c04107d5d3aca4e47199234f6cae43e0 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Tue, 28 May 2024 11:42:29 +0200 Subject: [PATCH 30/35] chore: style --- test/invariants/fuzz/Greeter.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol index 40608cfa..302a984f 100644 --- a/test/invariants/fuzz/Greeter.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -9,8 +9,8 @@ interface IHevm { contract InvariantGreeter { // See https://github.com/a16z/halmos-cheatcodes?tab=readme-ov-file - address constant HEVM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; - IHevm hevm = IHevm(HEVM_ADDRESS); + IHevm public hevm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + Greeter public targetContract; constructor() { From 7ada60b14f59374294f0f85238f6f27ec5f27271 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Tue, 28 May 2024 11:54:21 +0200 Subject: [PATCH 31/35] chore: styling --- test/invariants/fuzz/Greeter.t.sol | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol index 302a984f..25bc86d3 100644 --- a/test/invariants/fuzz/Greeter.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -9,30 +9,30 @@ interface IHevm { contract InvariantGreeter { // See https://github.com/a16z/halmos-cheatcodes?tab=readme-ov-file - IHevm public hevm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + IHevm internal _hevm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); - Greeter public targetContract; + Greeter internal _targetContract; constructor() { - targetContract = new Greeter('a', IERC20(address(1))); + _targetContract = new Greeter('a', IERC20(address(1))); } function checkGreeterNeverEmpty(string memory newGreeting) public { // Execution - (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, newGreeting)); + (bool success,) = address(_targetContract).call(abi.encodeCall(Greeter.setGreeting, newGreeting)); // Check output condition - assert((success && keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))) || !success); + assert((success && keccak256(bytes(_targetContract.greeting())) != keccak256(bytes(''))) || !success); } function checkOnlyOwnerSetsGreeting(address caller) public { // Input conditions - hevm.prank(caller); + _hevm.prank(caller); // Execution (bool success,) = address(this).call(abi.encodeCall(Greeter.setGreeting, 'hello')); // Check output condition - assert((success && msg.sender == targetContract.OWNER()) || (!success && msg.sender != targetContract.OWNER())); + assert((success && msg.sender == _targetContract.OWNER()) || (!success && msg.sender != _targetContract.OWNER())); } } From 35ef99811f4597dd041faca3ecd11556aa2b045f Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Tue, 28 May 2024 18:08:05 +0200 Subject: [PATCH 32/35] chore: comment fix --- test/invariants/fuzz/Greeter.t.sol | 1 - test/invariants/symbolic/Greeter.t.sol | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol index 25bc86d3..09887ded 100644 --- a/test/invariants/fuzz/Greeter.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -8,7 +8,6 @@ interface IHevm { } contract InvariantGreeter { - // See https://github.com/a16z/halmos-cheatcodes?tab=readme-ov-file IHevm internal _hevm = IHevm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); Greeter internal _targetContract; diff --git a/test/invariants/symbolic/Greeter.t.sol b/test/invariants/symbolic/Greeter.t.sol index 763a99a7..56c20508 100644 --- a/test/invariants/symbolic/Greeter.t.sol +++ b/test/invariants/symbolic/Greeter.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.23; import {Greeter, IERC20} from 'contracts/Greeter.sol'; import {Test} from 'forge-std/Test.sol'; -import {SymTest} from 'halmos-cheatcodes/src/SymTest.sol'; +import {SymTest} from 'halmos-cheatcodes/src/SymTest.sol'; // See https://github.com/a16z/halmos-cheatcodes?tab=readme-ov-file contract SymbolicGreeter is SymTest, Test { Greeter public targetContract; From 9cccb647be93fe2d35bc931cd6671682bcdf4a30 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Wed, 29 May 2024 13:45:25 +0200 Subject: [PATCH 33/35] fix: ci cov check path --- .github/workflows/coverage_check.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index 97578c6b..2319a744 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -45,8 +45,7 @@ jobs: - name: Retrieve previous coverage uses: actions/download-artifact@v2 with: - name: coverage - path: coverage.info + name: coverage.info continue-on-error: true - name: Check if a previous coverage exists @@ -69,5 +68,5 @@ jobs: - name: Upload the new coverage uses: actions/upload-artifact@v2 with: - name: coverage - path: coverage.info \ No newline at end of file + name: coverage.info + path: . \ No newline at end of file From a979f99cc71542db945a6163f3cc3fd0364032e1 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Wed, 29 May 2024 13:50:20 +0200 Subject: [PATCH 34/35] fix: ci cov second attempt --- .github/workflows/coverage_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_check.yml b/.github/workflows/coverage_check.yml index 2319a744..b17316ca 100644 --- a/.github/workflows/coverage_check.yml +++ b/.github/workflows/coverage_check.yml @@ -69,4 +69,4 @@ jobs: uses: actions/upload-artifact@v2 with: name: coverage.info - path: . \ No newline at end of file + path: ./coverage.info \ No newline at end of file From 254ca835fc7799a94496ab9c5937e25bc61d38e8 Mon Sep 17 00:00:00 2001 From: drgorillamd <83670532+drgorillamd@users.noreply.github.com> Date: Fri, 31 May 2024 16:14:32 +0200 Subject: [PATCH 35/35] chore: underscores --- test/invariants/fuzz/Greeter.t.sol | 14 +++++----- test/invariants/symbolic/Greeter.t.sol | 36 +++++++++++++------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol index 09887ded..96e2b1eb 100644 --- a/test/invariants/fuzz/Greeter.t.sol +++ b/test/invariants/fuzz/Greeter.t.sol @@ -16,22 +16,22 @@ contract InvariantGreeter { _targetContract = new Greeter('a', IERC20(address(1))); } - function checkGreeterNeverEmpty(string memory newGreeting) public { + function checkGreeterNeverEmpty(string memory _newGreeting) public { // Execution - (bool success,) = address(_targetContract).call(abi.encodeCall(Greeter.setGreeting, newGreeting)); + (bool _success,) = address(_targetContract).call(abi.encodeCall(Greeter.setGreeting, _newGreeting)); // Check output condition - assert((success && keccak256(bytes(_targetContract.greeting())) != keccak256(bytes(''))) || !success); + assert((_success && keccak256(bytes(_targetContract.greeting())) != keccak256(bytes(''))) || !_success); } - function checkOnlyOwnerSetsGreeting(address caller) public { + function checkOnlyOwnerSetsGreeting(address _caller) public { // Input conditions - _hevm.prank(caller); + _hevm.prank(_caller); // Execution - (bool success,) = address(this).call(abi.encodeCall(Greeter.setGreeting, 'hello')); + (bool _success,) = address(this).call(abi.encodeCall(Greeter.setGreeting, 'hello')); // Check output condition - assert((success && msg.sender == _targetContract.OWNER()) || (!success && msg.sender != _targetContract.OWNER())); + assert((_success && msg.sender == _targetContract.OWNER()) || (!_success && msg.sender != _targetContract.OWNER())); } } diff --git a/test/invariants/symbolic/Greeter.t.sol b/test/invariants/symbolic/Greeter.t.sol index 56c20508..16a7edd0 100644 --- a/test/invariants/symbolic/Greeter.t.sol +++ b/test/invariants/symbolic/Greeter.t.sol @@ -10,49 +10,49 @@ contract SymbolicGreeter is SymTest, Test { Greeter public targetContract; function setUp() public { - string memory initialGreeting = svm.createString(64, 'initial greeting'); - address token = svm.createAddress('token'); + string memory _initialGreeting = svm.createString(64, 'initial greeting'); + address _token = svm.createAddress('token'); - targetContract = new Greeter(initialGreeting, IERC20(token)); + targetContract = new Greeter(_initialGreeting, IERC20(_token)); } - function check_validState_greeterNeverEmpty(address caller) public { + function check_validState_greeterNeverEmpty(address _caller) public { // Input conditions: any caller - vm.prank(caller); + vm.prank(_caller); // Execution: Halmos cannot use a dynamic-sized array, iterate over multiple string lengths - bool success; + bool _success; for (uint256 i = 1; i < 3; i++) { string memory greeting = svm.createString(i, 'greeting'); - (success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (greeting))); + (_success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (greeting))); // Output condition check - vm.assume(success); // discard failing calls + vm.assume(_success); // discard failing calls assert(keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))); } // Add the empty string (bypass the non-empty check of svm.createString) - (success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (''))); + (_success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (''))); // Output condition check - vm.assume(success); // discard failing calls + vm.assume(_success); // discard failing calls assert(keccak256(bytes(targetContract.greeting())) != keccak256(bytes(''))); } - function check_setGreeting_onlyOwnerSetsGreeting(address caller) public { + function check_setGreeting_onlyOwnerSetsGreeting(address _caller) public { // Input conditions - string memory newGreeting = svm.createString(64, 'new greeting'); + string memory _newGreeting = svm.createString(64, 'new greeting'); // Execution - vm.prank(caller); - (bool success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (newGreeting))); + vm.prank(_caller); + (bool _success,) = address(targetContract).call(abi.encodeCall(Greeter.setGreeting, (_newGreeting))); // Output condition check - if (success) { - assert(caller == targetContract.OWNER()); - assert(keccak256(bytes(targetContract.greeting())) == keccak256(bytes(newGreeting))); + if (_success) { + assert(_caller == targetContract.OWNER()); + assert(keccak256(bytes(targetContract.greeting())) == keccak256(bytes(_newGreeting))); } else { - assert(caller != targetContract.OWNER() || keccak256(bytes(newGreeting)) == keccak256(bytes(''))); + assert(_caller != targetContract.OWNER() || keccak256(bytes(_newGreeting)) == keccak256(bytes(''))); } } }