From 74c4a4246466fae65b954ea2f70f245a4d143380 Mon Sep 17 00:00:00 2001 From: Damilola Edwards Date: Thu, 12 Oct 2023 14:03:40 +0100 Subject: [PATCH] added fail on revert feature option --- fuzzing/config/config.go | 2 ++ fuzzing/test_case_assertion_provider.go | 8 +++++++ .../assertions/assert_fail_on_revert.sol | 22 +++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 fuzzing/testdata/contracts/assertions/assert_fail_on_revert.sol diff --git a/fuzzing/config/config.go b/fuzzing/config/config.go index eac6c371..8f2298d2 100644 --- a/fuzzing/config/config.go +++ b/fuzzing/config/config.go @@ -132,6 +132,8 @@ type AssertionTestingConfig struct { // AssertionModesConfig describes the configuration options for the various modes that can be enabled for assertion // testing type AssertionModesConfig struct { + // FailOnRevert describes whether a revert should be treated as a failing case + FailOnRevert bool `json:"failOnRevert"` // FailOnCompilerInsertedPanic describes whether a generic compiler inserted panic should be treated as a failing case FailOnCompilerInsertedPanic bool `json:"failOnCompilerInsertedPanic"` diff --git a/fuzzing/test_case_assertion_provider.go b/fuzzing/test_case_assertion_provider.go index 300d97dc..40721dc7 100644 --- a/fuzzing/test_case_assertion_provider.go +++ b/fuzzing/test_case_assertion_provider.go @@ -6,6 +6,7 @@ import ( "github.com/crytic/medusa/fuzzing/config" "github.com/crytic/medusa/fuzzing/contracts" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/core/vm" "golang.org/x/exp/slices" "sync" ) @@ -70,6 +71,13 @@ func (t *AssertionTestCaseProvider) checkAssertionFailures(callSequence calls.Ca // want to be backwards compatible with older Solidity which simply hit an invalid opcode and did not actually // have a panic code. lastExecutionResult := lastCall.ChainReference.MessageResults().ExecutionResult + + // Check for revert or require failures if FailOnRevert is set to true + if t.fuzzer.config.Fuzzing.Testing.AssertionTesting.AssertionModes.FailOnRevert { + if lastExecutionResult.Err == vm.ErrExecutionReverted { + return &methodId, true, nil + } + } panicCode := abiutils.GetSolidityPanicCode(lastExecutionResult.Err, lastExecutionResult.ReturnData, true) failure := false if panicCode != nil { diff --git a/fuzzing/testdata/contracts/assertions/assert_fail_on_revert.sol b/fuzzing/testdata/contracts/assertions/assert_fail_on_revert.sol new file mode 100644 index 00000000..d06f0725 --- /dev/null +++ b/fuzzing/testdata/contracts/assertions/assert_fail_on_revert.sol @@ -0,0 +1,22 @@ +// This contract ensures the fuzzer will report an error when it encounters a revert. +contract TestContract { + function failRequire(uint value) public { + // This should trigger a test failure due to a failing require statement (without an error message) + require(false); + } + + function failRequireWithErrorString(uint value) public { + // This should trigger a test failure due to a failing require statement (with an error message) + require(false, "Require error"); + } + + function failRevert(uint value) public { + // This should trigger a test failure on encountering a revert instruction (without an error message) + revert(); + } + + function failRevertWithErrorString(uint value) public { + // This should trigger a test failure on encountering a revert instruction (with an error message) + revert("Function reverted"); + } +} \ No newline at end of file