4
4
"encoding/hex"
5
5
"errors"
6
6
"fmt"
7
+ "github.com/crytic/medusa/utils"
8
+ "github.com/ethereum/go-ethereum/common"
7
9
"regexp"
8
10
"strings"
9
11
@@ -13,7 +15,6 @@ import (
13
15
"github.com/crytic/medusa/fuzzing/valuegeneration"
14
16
"github.com/crytic/medusa/logging"
15
17
"github.com/crytic/medusa/logging/colors"
16
- "github.com/crytic/medusa/utils"
17
18
"github.com/ethereum/go-ethereum/accounts/abi"
18
19
coreTypes "github.com/ethereum/go-ethereum/core/types"
19
20
"github.com/ethereum/go-ethereum/core/vm"
@@ -29,13 +30,17 @@ type ExecutionTrace struct {
29
30
// contractDefinitions represents the known contract definitions at the time of tracing. This is used to help
30
31
// obtain any additional information regarding execution.
31
32
contractDefinitions contracts.Contracts
33
+
34
+ // labels is a mapping that maps an address to its string representation for cleaner execution traces
35
+ labels map [common.Address ]string
32
36
}
33
37
34
38
// newExecutionTrace creates and returns a new ExecutionTrace, to be used by the ExecutionTracer.
35
- func newExecutionTrace (contracts contracts.Contracts ) * ExecutionTrace {
39
+ func newExecutionTrace (contracts contracts.Contracts , labels map [common. Address ] string ) * ExecutionTrace {
36
40
return & ExecutionTrace {
37
41
TopLevelCallFrame : nil ,
38
42
contractDefinitions : contracts ,
43
+ labels : labels ,
39
44
}
40
45
}
41
46
@@ -70,10 +75,18 @@ func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) ([
70
75
71
76
// Resolve our contract names, as well as our method and its name from the code contract.
72
77
if callFrame .ToContractAbi != nil {
78
+ // Check to see if there is a label for the proxy address
73
79
proxyContractName = callFrame .ToContractName
80
+ if label , ok := t .labels [callFrame .ToAddress ]; ok {
81
+ proxyContractName = label
82
+ }
74
83
}
75
84
if callFrame .CodeContractAbi != nil {
85
+ // Check to see if there is a label for the code address
76
86
codeContractName = callFrame .CodeContractName
87
+ if label , ok := t .labels [callFrame .CodeAddress ]; ok {
88
+ codeContractName = label
89
+ }
77
90
if callFrame .IsContractCreation () {
78
91
methodName = "constructor"
79
92
method = & callFrame .CodeContractAbi .Constructor
@@ -102,8 +115,8 @@ func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) ([
102
115
// Unpack our input values and obtain a string to represent them
103
116
inputValues , err := method .Inputs .Unpack (abiDataInputBuffer )
104
117
if err == nil {
105
- // Encode the ABI arguments into strings
106
- encodedInputString , err := valuegeneration .EncodeABIArgumentsToString (method .Inputs , inputValues )
118
+ // Encode the ABI arguments into strings and provide the label overrides
119
+ encodedInputString , err := valuegeneration .EncodeABIArgumentsToString (method .Inputs , inputValues , t . labels )
107
120
if err == nil {
108
121
inputArgumentsDisplayText = & encodedInputString
109
122
}
@@ -137,24 +150,29 @@ func (t *ExecutionTrace) generateCallFrameEnterElements(callFrame *CallFrame) ([
137
150
inputArgumentsDisplayText = & temp
138
151
}
139
152
153
+ // Handle all label overrides
154
+ toAddress := utils .AttachLabelToAddress (callFrame .ToAddress , t .labels [callFrame .ToAddress ])
155
+ senderAddress := utils .AttachLabelToAddress (callFrame .SenderAddress , t .labels [callFrame .SenderAddress ])
156
+ codeAddress := utils .AttachLabelToAddress (callFrame .CodeAddress , t .labels [callFrame .CodeAddress ])
157
+
140
158
// Generate the message we wish to output finally, using all these display string components.
141
159
// If we executed code, attach additional context such as the contract name, method, etc.
142
160
var callInfo string
143
161
if callFrame .IsProxyCall () {
144
162
if callFrame .ExecutedCode {
145
- callInfo = fmt .Sprintf ("%v -> %v.%v(%v) (addr=%v, code=%v, value=%v, sender=%v)" , proxyContractName , codeContractName , methodName , * inputArgumentsDisplayText , utils . TrimLeadingZeroesFromAddress ( callFrame . ToAddress . String ()), utils . TrimLeadingZeroesFromAddress ( callFrame . CodeAddress . String ()) , callFrame .CallValue , utils . TrimLeadingZeroesFromAddress ( callFrame . SenderAddress . String ()) )
163
+ callInfo = fmt .Sprintf ("%v -> %v.%v(%v) (addr=%v, code=%v, value=%v, sender=%v)" , proxyContractName , codeContractName , methodName , * inputArgumentsDisplayText , toAddress , codeAddress , callFrame .CallValue , senderAddress )
146
164
} else {
147
- callInfo = fmt .Sprintf ("(addr=%v, value=%v, sender=%v)" , utils . TrimLeadingZeroesFromAddress ( callFrame . ToAddress . String ()) , callFrame .CallValue , utils . TrimLeadingZeroesFromAddress ( callFrame . SenderAddress . String ()) )
165
+ callInfo = fmt .Sprintf ("(addr=%v, value=%v, sender=%v)" , toAddress , callFrame .CallValue , senderAddress )
148
166
}
149
167
} else {
150
168
if callFrame .ExecutedCode {
151
169
if callFrame .ToAddress == chain .ConsoleLogContractAddress {
152
170
callInfo = fmt .Sprintf ("%v.%v(%v)" , codeContractName , methodName , * inputArgumentsDisplayText )
153
171
} else {
154
- callInfo = fmt .Sprintf ("%v.%v(%v) (addr=%v, value=%v, sender=%v)" , codeContractName , methodName , * inputArgumentsDisplayText , utils . TrimLeadingZeroesFromAddress ( callFrame . ToAddress . String ()) , callFrame .CallValue , utils . TrimLeadingZeroesFromAddress ( callFrame . SenderAddress . String ()) )
172
+ callInfo = fmt .Sprintf ("%v.%v(%v) (addr=%v, value=%v, sender=%v)" , codeContractName , methodName , * inputArgumentsDisplayText , toAddress , callFrame .CallValue , senderAddress )
155
173
}
156
174
} else {
157
- callInfo = fmt .Sprintf ("(addr=%v, value=%v, sender=%v)" , utils . TrimLeadingZeroesFromAddress ( callFrame . ToAddress . String ()) , callFrame .CallValue , utils . TrimLeadingZeroesFromAddress ( callFrame . SenderAddress . String ()) )
175
+ callInfo = fmt .Sprintf ("(addr=%v, value=%v, sender=%v)" , toAddress , callFrame .CallValue , senderAddress )
158
176
}
159
177
}
160
178
@@ -189,7 +207,7 @@ func (t *ExecutionTrace) generateCallFrameExitElements(callFrame *CallFrame) []a
189
207
if callFrame .ReturnError == nil {
190
208
outputValues , err := method .Outputs .Unpack (callFrame .ReturnData )
191
209
if err == nil {
192
- encodedOutputString , err := valuegeneration .EncodeABIArgumentsToString (method .Outputs , outputValues )
210
+ encodedOutputString , err := valuegeneration .EncodeABIArgumentsToString (method .Outputs , outputValues , t . labels )
193
211
if err == nil {
194
212
outputArgumentsDisplayText = & encodedOutputString
195
213
}
@@ -232,7 +250,7 @@ func (t *ExecutionTrace) generateCallFrameExitElements(callFrame *CallFrame) []a
232
250
// Try to unpack a custom Solidity error from the return values.
233
251
matchedCustomError , unpackedCustomErrorArgs := abiutils .GetSolidityCustomRevertError (callFrame .CodeContractAbi , callFrame .ReturnError , callFrame .ReturnData )
234
252
if matchedCustomError != nil {
235
- customErrorArgsDisplayText , err := valuegeneration .EncodeABIArgumentsToString (matchedCustomError .Inputs , unpackedCustomErrorArgs )
253
+ customErrorArgsDisplayText , err := valuegeneration .EncodeABIArgumentsToString (matchedCustomError .Inputs , unpackedCustomErrorArgs , t . labels )
236
254
if err == nil {
237
255
elements = append (elements , colors .RedBold , fmt .Sprintf ("[revert (error: %v(%v))]" , matchedCustomError .Name , customErrorArgsDisplayText ), colors .Reset , "\n " )
238
256
return elements
@@ -276,7 +294,7 @@ func (t *ExecutionTrace) generateEventEmittedElements(callFrame *CallFrame, even
276
294
// If we resolved an event definition and unpacked data.
277
295
if event != nil {
278
296
// Format the values as a comma-separated string
279
- encodedEventValuesString , err := valuegeneration .EncodeABIArgumentsToString (event .Inputs , eventInputValues )
297
+ encodedEventValuesString , err := valuegeneration .EncodeABIArgumentsToString (event .Inputs , eventInputValues , t . labels )
280
298
if err == nil {
281
299
// Format our event display text finally, with the event name.
282
300
temp := fmt .Sprintf ("%v(%v)" , event .Name , encodedEventValuesString )
0 commit comments