@@ -19,7 +19,6 @@ import (
1919 "github.com/crytic/medusa/fuzzing/contracts"
2020 "github.com/crytic/medusa/fuzzing/coverage"
2121 "github.com/crytic/medusa/logging"
22- "github.com/crytic/medusa/logging/colors"
2322 "github.com/crytic/medusa/utils"
2423 "github.com/crytic/medusa/utils/randomutils"
2524 "github.com/google/uuid"
@@ -285,100 +284,6 @@ func (c *Corpus) Initialize(baseTestChain *chain.TestChain, contractDefinitions
285284 return nil
286285}
287286
288- // initializeSequences is a helper method for Initialize. It validates a list of call sequence files on a given
289- // chain, using the map of deployed contracts (e.g. to check for non-existent method called, due to code changes).
290- // Valid call sequences are added to the list of un-executed sequences the fuzzer should execute first.
291- // If this sequence list being initialized is for use with mutations, it is added to the mutationTargetSequenceChooser.
292- // Returns an error if one occurs.
293- func (c * Corpus ) initializeSequences (sequenceFiles * corpusDirectory [calls.CallSequence ], testChain * chain.TestChain , deployedContracts map [common.Address ]* contracts.Contract , useInMutations bool ) error {
294- // Cache the base block index so that you can reset back to it after every sequence
295- baseBlockIndex := uint64 (len (testChain .CommittedBlocks ()))
296-
297- // Loop for each sequence
298- var err error
299- for _ , sequenceFileData := range sequenceFiles .files {
300- // Unwrap the underlying sequence.
301- sequence := sequenceFileData .data
302-
303- // Define a variable to track whether we should disable this sequence (if it is no longer applicable in some
304- // way).
305- sequenceInvalidError := error (nil )
306- fetchElementFunc := func (currentIndex int ) (* calls.CallSequenceElement , error ) {
307- // If we are at the end of our sequence, return nil indicating we should stop executing.
308- if currentIndex >= len (sequence ) {
309- return nil , nil
310- }
311-
312- // If we are deploying a contract and not targeting one with this call, there should be no work to do.
313- currentSequenceElement := sequence [currentIndex ]
314- if currentSequenceElement .Call .To == nil {
315- return currentSequenceElement , nil
316- }
317-
318- // We are calling a contract with this call, ensure we can resolve the contract call is targeting.
319- resolvedContract , resolvedContractExists := deployedContracts [* currentSequenceElement .Call .To ]
320- if ! resolvedContractExists {
321- sequenceInvalidError = fmt .Errorf ("contract at address '%v' could not be resolved" , currentSequenceElement .Call .To .String ())
322- return nil , nil
323- }
324- currentSequenceElement .Contract = resolvedContract
325-
326- // Next, if our sequence element uses ABI values to produce call data, our deserialized data is not yet
327- // sufficient for runtime use, until we use it to resolve runtime references.
328- callAbiValues := currentSequenceElement .Call .DataAbiValues
329- if callAbiValues != nil {
330- sequenceInvalidError = callAbiValues .Resolve (currentSequenceElement .Contract .CompiledContract ().Abi )
331- if sequenceInvalidError != nil {
332- sequenceInvalidError = fmt .Errorf ("error resolving method in contract '%v': %v" , currentSequenceElement .Contract .Name (), sequenceInvalidError )
333- return nil , nil
334- }
335- }
336- return currentSequenceElement , nil
337- }
338-
339- // Define actions to perform after executing each call in the sequence.
340- executionCheckFunc := func (currentlyExecutedSequence calls.CallSequence ) (bool , error ) {
341- // Grab the coverage maps for the last executed sequence element
342- lastExecutedSequenceElement := currentlyExecutedSequence [len (currentlyExecutedSequence )- 1 ]
343- covMaps := coverage .GetCoverageTracerResults (lastExecutedSequenceElement .ChainReference .MessageResults ())
344-
345- // Memory optimization: Remove the coverage maps from the message results
346- coverage .RemoveCoverageTracerResults (lastExecutedSequenceElement .ChainReference .MessageResults ())
347-
348- // Update the global coverage maps
349- _ , covErr := c .coverageMaps .Update (covMaps )
350- if covErr != nil {
351- return true , covErr
352- }
353- return false , nil
354- }
355-
356- // Execute each call sequence, populating runtime data and collecting coverage data along the way.
357- _ , err = calls .ExecuteCallSequenceIteratively (testChain , fetchElementFunc , executionCheckFunc )
358-
359- // If we failed to replay a sequence and measure coverage due to an unexpected error, report it.
360- if err != nil {
361- return fmt .Errorf ("failed to initialize coverage maps from corpus, encountered an error while executing call sequence: %v" , err )
362- }
363-
364- // If the sequence was replayed successfully, we add it. If it was not, we exclude it with a warning.
365- if sequenceInvalidError == nil {
366- if useInMutations && c .mutationTargetSequenceChooser != nil {
367- c .mutationTargetSequenceChooser .AddChoices (randomutils .NewWeightedRandomChoice [calls.CallSequence ](sequence , big .NewInt (1 )))
368- }
369- c .unexecutedCallSequences = append (c .unexecutedCallSequences , sequence )
370- } else {
371- c .logger .Debug ("Corpus item " , colors .Bold , sequenceFileData .fileName , colors .Reset , " disabled due to error when replaying it" , sequenceInvalidError )
372- }
373-
374- // Revert chain state to our starting point to test the next sequence.
375- if err := testChain .RevertToBlockIndex (baseBlockIndex ); err != nil {
376- return fmt .Errorf ("failed to reset the chain while seeding coverage: %v" , err )
377- }
378- }
379- return nil
380- }
381-
382287// CoverageMaps exposes coverage details for all call sequences known to the corpus.
383288func (c * Corpus ) CoverageMaps () * coverage.CoverageMaps {
384289 return c .coverageMaps
0 commit comments