@@ -41,21 +41,28 @@ pub enum CounterExample {
41
41
42
42
#[ derive( Clone , Debug , Serialize , Deserialize ) ]
43
43
pub struct BaseCounterExample {
44
- /// Address which makes the call
44
+ /// Address which makes the call.
45
45
pub sender : Option < Address > ,
46
- /// Address to which to call to
46
+ /// Address to which to call to.
47
47
pub addr : Option < Address > ,
48
- /// The data to provide
48
+ /// The data to provide.
49
49
pub calldata : Bytes ,
50
- /// Contract name if it exists
50
+ /// Contract name if it exists.
51
51
pub contract_name : Option < String > ,
52
- /// Function signature if it exists
52
+ /// Function name if it exists.
53
+ pub func_name : Option < String > ,
54
+ /// Function signature if it exists.
53
55
pub signature : Option < String > ,
54
- /// Args used to call the function
56
+ /// Pretty formatted args used to call the function.
55
57
pub args : Option < String > ,
56
- /// Traces
58
+ /// Unformatted args used to call the function.
59
+ pub raw_args : Option < String > ,
60
+ /// Counter example traces.
57
61
#[ serde( skip) ]
58
62
pub traces : Option < SparsedTraceArena > ,
63
+ /// Whether to display sequence as solidity.
64
+ #[ serde( skip) ]
65
+ pub show_solidity : bool ,
59
66
}
60
67
61
68
impl BaseCounterExample {
@@ -66,6 +73,7 @@ impl BaseCounterExample {
66
73
bytes : & Bytes ,
67
74
contracts : & ContractsByAddress ,
68
75
traces : Option < SparsedTraceArena > ,
76
+ show_solidity : bool ,
69
77
) -> Self {
70
78
if let Some ( ( name, abi) ) = & contracts. get ( & addr) {
71
79
if let Some ( func) = abi. functions ( ) . find ( |f| f. selector ( ) == bytes[ ..4 ] ) {
@@ -76,11 +84,16 @@ impl BaseCounterExample {
76
84
addr : Some ( addr) ,
77
85
calldata : bytes. clone ( ) ,
78
86
contract_name : Some ( name. clone ( ) ) ,
87
+ func_name : Some ( func. name . clone ( ) ) ,
79
88
signature : Some ( func. signature ( ) ) ,
80
89
args : Some (
81
90
foundry_common:: fmt:: format_tokens ( & args) . format ( ", " ) . to_string ( ) ,
82
91
) ,
92
+ raw_args : Some (
93
+ foundry_common:: fmt:: format_tokens_raw ( & args) . format ( ", " ) . to_string ( ) ,
94
+ ) ,
83
95
traces,
96
+ show_solidity,
84
97
} ;
85
98
}
86
99
}
@@ -91,9 +104,12 @@ impl BaseCounterExample {
91
104
addr : Some ( addr) ,
92
105
calldata : bytes. clone ( ) ,
93
106
contract_name : None ,
107
+ func_name : None ,
94
108
signature : None ,
95
109
args : None ,
110
+ raw_args : None ,
96
111
traces,
112
+ show_solidity : false ,
97
113
}
98
114
}
99
115
@@ -108,17 +124,40 @@ impl BaseCounterExample {
108
124
addr : None ,
109
125
calldata : bytes,
110
126
contract_name : None ,
127
+ func_name : None ,
111
128
signature : None ,
112
129
args : Some ( foundry_common:: fmt:: format_tokens ( & args) . format ( ", " ) . to_string ( ) ) ,
130
+ raw_args : Some ( foundry_common:: fmt:: format_tokens_raw ( & args) . format ( ", " ) . to_string ( ) ) ,
113
131
traces,
132
+ show_solidity : false ,
114
133
}
115
134
}
116
135
}
117
136
118
137
impl fmt:: Display for BaseCounterExample {
119
138
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
139
+ // Display counterexample as solidity.
140
+ if self . show_solidity {
141
+ if let ( Some ( sender) , Some ( contract) , Some ( address) , Some ( func_name) , Some ( args) ) =
142
+ ( & self . sender , & self . contract_name , & self . addr , & self . func_name , & self . raw_args )
143
+ {
144
+ writeln ! ( f, "\t \t vm.prank({sender});" ) ?;
145
+ write ! (
146
+ f,
147
+ "\t \t {}({}).{}({});" ,
148
+ contract. split_once( ':' ) . map_or( contract. as_str( ) , |( _, contract) | contract) ,
149
+ address,
150
+ func_name,
151
+ args
152
+ ) ?;
153
+
154
+ return Ok ( ( ) )
155
+ }
156
+ }
157
+
158
+ // Regular counterexample display.
120
159
if let Some ( sender) = self . sender {
121
- write ! ( f, "sender ={sender} addr=" ) ?
160
+ write ! ( f, "\t \t sender ={sender} addr=" ) ?
122
161
}
123
162
124
163
if let Some ( name) = & self . contract_name {
0 commit comments