diff --git a/chain/test_chain.go b/chain/test_chain.go index a4466cc7..9e9ff4e2 100644 --- a/chain/test_chain.go +++ b/chain/test_chain.go @@ -856,8 +856,9 @@ func (t *TestChain) emitContractChangeEvents(reverting bool, messageResults ...* // this execution result is being committed to chain. if deploymentChange.Creation { err = t.Events.ContractDeploymentAddedEventEmitter.Publish(ContractDeploymentsAddedEvent{ - Chain: t, - Contract: deploymentChange.Contract, + Chain: t, + Contract: deploymentChange.Contract, + DynamicDeployment: deploymentChange.DynamicCreation, }) } else if deploymentChange.Destroyed { err = t.Events.ContractDeploymentRemovedEventEmitter.Publish(ContractDeploymentsRemovedEvent{ @@ -887,8 +888,9 @@ func (t *TestChain) emitContractChangeEvents(reverting bool, messageResults ...* }) } else if deploymentChange.Destroyed { err = t.Events.ContractDeploymentAddedEventEmitter.Publish(ContractDeploymentsAddedEvent{ - Chain: t, - Contract: deploymentChange.Contract, + Chain: t, + Contract: deploymentChange.Contract, + DynamicDeployment: deploymentChange.DynamicCreation, }) } if err != nil { diff --git a/chain/test_chain_deployments_tracer.go b/chain/test_chain_deployments_tracer.go index c2672aaa..d8bec11f 100644 --- a/chain/test_chain_deployments_tracer.go +++ b/chain/test_chain_deployments_tracer.go @@ -74,9 +74,10 @@ func (t *testChainDeploymentsTracer) CaptureStart(env *vm.EVM, from common.Addre InitBytecode: input, RuntimeBytecode: nil, }, - Creation: true, - SelfDestructed: false, - Destroyed: false, + Creation: true, + DynamicCreation: false, + SelfDestructed: false, + Destroyed: false, }) } } @@ -118,9 +119,10 @@ func (t *testChainDeploymentsTracer) CaptureEnter(typ vm.OpCode, from common.Add InitBytecode: input, RuntimeBytecode: nil, }, - Creation: true, - SelfDestructed: false, - Destroyed: false, + Creation: true, + DynamicCreation: true, + SelfDestructed: false, + Destroyed: false, }) } } @@ -158,9 +160,10 @@ func (t *testChainDeploymentsTracer) CaptureState(pc uint64, op vm.OpCode, gas, InitBytecode: nil, RuntimeBytecode: t.evm.StateDB.GetCode(scope.Contract.Address()), }, - Creation: false, - SelfDestructed: true, - Destroyed: t.selfDestructDestroysCode, + Creation: false, + DynamicCreation: false, + SelfDestructed: true, + Destroyed: t.selfDestructDestroysCode, }) } } diff --git a/chain/test_chain_events.go b/chain/test_chain_events.go index adc92fd4..49c4cf48 100644 --- a/chain/test_chain_events.go +++ b/chain/test_chain_events.go @@ -93,6 +93,10 @@ type ContractDeploymentsAddedEvent struct { // Contract defines information for the contract which was deployed to the Chain. Contract *types.DeployedContractBytecode + + // DynamicDeployment describes whether this contract deployment was dynamic (e.g. `c = new MyContract()`) or was + // because of a traditional transaction + DynamicDeployment bool } // ContractDeploymentsRemovedEvent describes an event where a contract has become unavailable on the TestChain, either diff --git a/chain/types/deployed_contract_bytecode.go b/chain/types/deployed_contract_bytecode.go index e32c76d1..9f49bef8 100644 --- a/chain/types/deployed_contract_bytecode.go +++ b/chain/types/deployed_contract_bytecode.go @@ -16,6 +16,10 @@ type DeployedContractBytecodeChange struct { // Destroyed are true. Creation bool + // DynamicCreation indicates whether the change made was a _dynamic_ contract creation. This cannot be true if + // Creation is false. + DynamicCreation bool + // SelfDestructed indicates whether the change made was due to a self-destruct instruction being executed. This // cannot be true if Creation is true. // Note: This may not be indicative of contract removal (as is the case with Destroyed), as proposed changes to diff --git a/fuzzing/config/config_defaults.go b/fuzzing/config/config_defaults.go index e82f1a1a..74cd76f4 100644 --- a/fuzzing/config/config_defaults.go +++ b/fuzzing/config/config_defaults.go @@ -53,7 +53,7 @@ func GetDefaultProjectConfig(platform string) (*ProjectConfig, error) { TransactionGasLimit: 12_500_000, Testing: TestingConfig{ StopOnFailedTest: true, - StopOnFailedContractMatching: true, + StopOnFailedContractMatching: false, StopOnNoTests: true, TestAllContracts: false, TraceAll: false, diff --git a/fuzzing/fuzzer_test.go b/fuzzing/fuzzer_test.go index 55c845fd..7fdc4f47 100644 --- a/fuzzing/fuzzer_test.go +++ b/fuzzing/fuzzer_test.go @@ -398,6 +398,7 @@ func TestDeploymentsSelfDestruct(t *testing.T) { config.Fuzzing.DeploymentOrder = []string{"InnerDeploymentFactory"} config.Fuzzing.TestLimit = 500 // this test should expose a failure quickly. config.Fuzzing.Testing.StopOnNoTests = false + config.Fuzzing.Testing.TestAllContracts = true }, method: func(f *fuzzerTestContext) { // Subscribe to any mined block events globally. When receiving them, check contract changes for a diff --git a/fuzzing/fuzzer_worker.go b/fuzzing/fuzzer_worker.go index d8f01bed..27848a23 100644 --- a/fuzzing/fuzzer_worker.go +++ b/fuzzing/fuzzer_worker.go @@ -152,6 +152,11 @@ func (fw *FuzzerWorker) getNewCorpusCallSequenceWeight() *big.Int { // onChainContractDeploymentAddedEvent is the event callback used when the chain detects a new contract deployment. // It attempts bytecode matching and updates the list of deployed contracts the worker should use for fuzz testing. func (fw *FuzzerWorker) onChainContractDeploymentAddedEvent(event chain.ContractDeploymentsAddedEvent) error { + // Do not track the deployed contract if the contract deployment was a dynamic one and testAllContracts is false + if !fw.fuzzer.config.Fuzzing.Testing.TestAllContracts && event.DynamicDeployment { + return nil + } + // Add the contract address to our value set so our generator can use it in calls. fw.valueSet.AddAddress(event.Contract.Address) diff --git a/logging/logger_test.go b/logging/logger_test.go index 540e78e3..53e0d6a4 100644 --- a/logging/logger_test.go +++ b/logging/logger_test.go @@ -70,6 +70,6 @@ func TestDisabledColors(t *testing.T) { // Ensure that msg doesn't include colors afterwards prefix := fmt.Sprintf("%s %s", colors.LEFT_ARROW, "foo") - _, ok := strings.CutPrefix(buf.String(), prefix) + _, _, ok := strings.Cut(buf.String(), prefix) assert.True(t, ok) }