From fbff39e631b8d2839f34e979106d057b189ff21b Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 19 Sep 2024 11:27:35 -0500 Subject: [PATCH 1/2] fix: dedup pc by codehash for unique pc metric --- fuzzing/coverage/coverage_maps.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fuzzing/coverage/coverage_maps.go b/fuzzing/coverage/coverage_maps.go index 59237669..cba3fa0b 100644 --- a/fuzzing/coverage/coverage_maps.go +++ b/fuzzing/coverage/coverage_maps.go @@ -3,11 +3,12 @@ package coverage import ( "golang.org/x/exp/slices" + "sync" + compilationTypes "github.com/crytic/medusa/compilation/types" "github.com/crytic/medusa/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "sync" ) // CoverageMaps represents a data structure used to identify instruction execution coverage of various smart contracts @@ -270,6 +271,8 @@ func (cm *CoverageMaps) UniquePCs() uint64 { uniquePCs++ } } + // We have seen one coveragemap for the codehash and do not want to double count + break } } return uniquePCs From e541c8fc74c94cd988fada737a715f0b324ac037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Fri, 27 Sep 2024 18:20:16 +0200 Subject: [PATCH 2/2] fix: unify coverage across multiple instances of a codehash when counting unique PCs --- fuzzing/coverage/coverage_maps.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/fuzzing/coverage/coverage_maps.go b/fuzzing/coverage/coverage_maps.go index cba3fa0b..2d8c0b0f 100644 --- a/fuzzing/coverage/coverage_maps.go +++ b/fuzzing/coverage/coverage_maps.go @@ -250,6 +250,10 @@ func (cm *CoverageMaps) UniquePCs() uint64 { uniquePCs := uint64(0) // Iterate across each contract deployment for _, mapsByAddress := range cm.maps { + // Consider the coverage of all of the different deployments of this codehash as a set + // And mark a PC as hit if any of the instances has a hit for it + uniquePCsForHash := make(map[int]struct{}) + for _, contractCoverageMap := range mapsByAddress { // TODO: Note we are not checking for nil dereference here because we are guaranteed that the successful // coverage and reverted coverage arrays have been instantiated if we are iterating over it @@ -260,7 +264,7 @@ func (cm *CoverageMaps) UniquePCs() uint64 { for i, hits := range contractCoverageMap.successfulCoverage.executedFlags { // If we hit the PC at least once, we have a unique PC hit if hits != 0 { - uniquePCs++ + uniquePCsForHash[i] = struct{}{} // Do not count both success and revert continue @@ -268,12 +272,12 @@ func (cm *CoverageMaps) UniquePCs() uint64 { // This is only executed if the PC was not executed successfully if contractCoverageMap.revertedCoverage.executedFlags != nil && contractCoverageMap.revertedCoverage.executedFlags[i] != 0 { - uniquePCs++ + uniquePCsForHash[i] = struct{}{} } } - // We have seen one coveragemap for the codehash and do not want to double count - break } + + uniquePCs += uint64(len(uniquePCsForHash)) } return uniquePCs }