Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail on revert/require feature #242

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fuzzing/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`

Expand Down
8 changes: 8 additions & 0 deletions fuzzing/test_case_assertion_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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 {
Expand Down
22 changes: 22 additions & 0 deletions fuzzing/testdata/contracts/assertions/assert_fail_on_revert.sol
Original file line number Diff line number Diff line change
@@ -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");
}
}