From dd7ea8dec04735ee521496cf16e9f3014512513f Mon Sep 17 00:00:00 2001 From: teddy Date: Fri, 18 Oct 2024 17:42:40 -0300 Subject: [PATCH] fix: feedback from gas --- medusa.json | 4 +- test/invariants/PROPERTIES.md | 2 +- test/invariants/fuzz/FuzzTest.t.sol | 8 ++++ test/invariants/fuzz/Greeter.t.sol | 40 ------------------- .../fuzz/handlers/guided/Greeter.t.sol | 15 +++++++ .../fuzz/handlers/unguided/Greeter.t.sol | 18 +++++++++ test/invariants/fuzz/properties/Greeter.t.sol | 12 ++++++ test/invariants/fuzz/setup/Greeter.t.sol | 13 ++++++ 8 files changed, 69 insertions(+), 43 deletions(-) create mode 100644 test/invariants/fuzz/FuzzTest.t.sol delete mode 100644 test/invariants/fuzz/Greeter.t.sol create mode 100644 test/invariants/fuzz/handlers/guided/Greeter.t.sol create mode 100644 test/invariants/fuzz/handlers/unguided/Greeter.t.sol create mode 100644 test/invariants/fuzz/properties/Greeter.t.sol create mode 100644 test/invariants/fuzz/setup/Greeter.t.sol diff --git a/medusa.json b/medusa.json index dc61b33d..31227c5b 100644 --- a/medusa.json +++ b/medusa.json @@ -12,7 +12,7 @@ "html", "lcov" ], - "targetContracts": ["InvariantGreeter"], + "targetContracts": ["FuzzTest"], "predeployedContracts": {}, "targetContractsBalances": [], "constructorArgs": {}, @@ -75,7 +75,7 @@ "compilation": { "platform": "crytic-compile", "platformConfig": { - "target": "test/invariants/fuzz/Greeter.t.sol", + "target": "test/invariants/fuzz/FuzzTest.t.sol", "solcVersion": "", "exportDirectory": "", "args": [] diff --git a/test/invariants/PROPERTIES.md b/test/invariants/PROPERTIES.md index bb8837e9..bbf31df4 100644 --- a/test/invariants/PROPERTIES.md +++ b/test/invariants/PROPERTIES.md @@ -1,4 +1,4 @@ -| id | Properties | Type | +| Id | Properties | Type | | --- | --------------------------------------------------- | ------------ | | 1 | Greeting should never be empty | Valid state | | 2 | Only the owner can set the greeting | State transition | diff --git a/test/invariants/fuzz/FuzzTest.t.sol b/test/invariants/fuzz/FuzzTest.t.sol new file mode 100644 index 00000000..02a127bf --- /dev/null +++ b/test/invariants/fuzz/FuzzTest.t.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {GreeterGuidedHandlers} from './handlers/guided/Greeter.t.sol'; +import {GreeterUnguidedHandlers} from './handlers/unguided/Greeter.t.sol'; +import {GreeterProperties} from './properties/Greeter.t.sol'; + +contract FuzzTest is GreeterGuidedHandlers, GreeterUnguidedHandlers, GreeterProperties {} diff --git a/test/invariants/fuzz/Greeter.t.sol b/test/invariants/fuzz/Greeter.t.sol deleted file mode 100644 index a8f6cf95..00000000 --- a/test/invariants/fuzz/Greeter.t.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.23; - -import {Greeter, IERC20} from 'contracts/Greeter.sol'; -import {CommonBase} from 'forge-std/Base.sol'; - -contract InvariantGreeter is CommonBase { - Greeter internal _targetContract; - - constructor() { - _targetContract = new Greeter('a', IERC20(address(1))); - } - - /// @custom:property-id 2 - /// @custom:property Only the owner can set the greeting - function handler_unguided_setGreeting(address _caller, string memory _newGreeting) external { - vm.prank(_caller); - try _targetContract.setGreeting(_newGreeting) { - assert(keccak256(bytes(_targetContract.greeting())) == keccak256(bytes(_newGreeting))); - assert(_caller == _targetContract.OWNER()); - } catch { - assert(_caller != _targetContract.OWNER() || keccak256(bytes(_newGreeting)) == keccak256('')); - } - } - - function handler_guided_setGreeting(string memory _newGreeting) external { - // no need to prank since this contract deployed the greeter and is therefore its owner - try _targetContract.setGreeting(_newGreeting) { - assert(keccak256(bytes(_targetContract.greeting())) == keccak256(bytes(_newGreeting))); - } catch { - assert(keccak256(bytes(_newGreeting)) == keccak256('')); - } - } - - /// @custom:property-id 1 - /// @custom:property Greeting should never be empty - function property_greetingIsNeverEmpty() external view { - assert(keccak256(bytes(_targetContract.greeting())) != keccak256('')); - } -} diff --git a/test/invariants/fuzz/handlers/guided/Greeter.t.sol b/test/invariants/fuzz/handlers/guided/Greeter.t.sol new file mode 100644 index 00000000..732e105e --- /dev/null +++ b/test/invariants/fuzz/handlers/guided/Greeter.t.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {GreeterSetup} from '../../setup/Greeter.t.sol'; + +contract GreeterGuidedHandlers is GreeterSetup { + function handler_setGreeting(string memory _newGreeting) external { + // no need to prank since this contract deployed the greeter and is therefore its owner + try _targetContract.setGreeting(_newGreeting) { + assert(keccak256(bytes(_targetContract.greeting())) == keccak256(bytes(_newGreeting))); + } catch { + assert(keccak256(bytes(_newGreeting)) == keccak256('')); + } + } +} diff --git a/test/invariants/fuzz/handlers/unguided/Greeter.t.sol b/test/invariants/fuzz/handlers/unguided/Greeter.t.sol new file mode 100644 index 00000000..213d73bc --- /dev/null +++ b/test/invariants/fuzz/handlers/unguided/Greeter.t.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {GreeterSetup} from '../../setup/Greeter.t.sol'; + +contract GreeterUnguidedHandlers is GreeterSetup { + /// @custom:property-id 2 + /// @custom:property Only the owner can set the greeting + function handler_setGreeting(address _caller, string memory _newGreeting) external { + vm.prank(_caller); + try _targetContract.setGreeting(_newGreeting) { + assert(keccak256(bytes(_targetContract.greeting())) == keccak256(bytes(_newGreeting))); + assert(_caller == _targetContract.OWNER()); + } catch { + assert(_caller != _targetContract.OWNER() || keccak256(bytes(_newGreeting)) == keccak256('')); + } + } +} diff --git a/test/invariants/fuzz/properties/Greeter.t.sol b/test/invariants/fuzz/properties/Greeter.t.sol new file mode 100644 index 00000000..979d278f --- /dev/null +++ b/test/invariants/fuzz/properties/Greeter.t.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {GreeterSetup} from '../setup/Greeter.t.sol'; + +contract GreeterProperties is GreeterSetup { + /// @custom:property-id 1 + /// @custom:property Greeting should never be empty + function property_greetingIsNeverEmpty() external view { + assert(keccak256(bytes(_targetContract.greeting())) != keccak256('')); + } +} diff --git a/test/invariants/fuzz/setup/Greeter.t.sol b/test/invariants/fuzz/setup/Greeter.t.sol new file mode 100644 index 00000000..ee6676f1 --- /dev/null +++ b/test/invariants/fuzz/setup/Greeter.t.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.23; + +import {Greeter, IERC20} from 'contracts/Greeter.sol'; +import {CommonBase} from 'forge-std/Base.sol'; + +contract GreeterSetup is CommonBase { + Greeter internal _targetContract; + + constructor() { + _targetContract = new Greeter('a', IERC20(address(1))); + } +}