11#[ macro_use]
22extern crate tracing;
33
4- use alloy_dyn_abi:: DynSolValue ;
4+ use alloy_dyn_abi:: { DynSolValue , ErrorExt , EventExt } ;
55use alloy_primitives:: { eip191_hash_message, hex, keccak256, Address , B256 } ;
66use alloy_provider:: Provider ;
77use alloy_rpc_types:: { BlockId , BlockNumberOrTag :: Latest } ;
@@ -11,7 +11,7 @@ use clap_complete::generate;
1111use eyre:: Result ;
1212use foundry_cli:: { handler, utils} ;
1313use foundry_common:: {
14- abi:: get_event,
14+ abi:: { get_error , get_event} ,
1515 ens:: { namehash, ProviderEnsExt } ,
1616 fmt:: { format_tokens, format_tokens_raw, format_uint_exp} ,
1717 fs,
@@ -30,6 +30,7 @@ pub mod cmd;
3030pub mod tx;
3131
3232use args:: { Cast as CastArgs , CastSubcommand , ToBaseArgs } ;
33+ use cast:: traces:: identifier:: SignaturesIdentifier ;
3334
3435#[ macro_use]
3536extern crate foundry_common;
@@ -189,7 +190,7 @@ async fn main_args(args: CastArgs) -> Result<()> {
189190 }
190191
191192 // ABI encoding & decoding
192- CastSubcommand :: AbiDecode { sig, calldata, input } => {
193+ CastSubcommand :: DecodeAbi { sig, calldata, input } => {
193194 let tokens = SimpleCast :: abi_decode ( & sig, & calldata, input) ?;
194195 print_tokens ( & tokens) ;
195196 }
@@ -200,17 +201,65 @@ async fn main_args(args: CastArgs) -> Result<()> {
200201 sh_println ! ( "{}" , SimpleCast :: abi_encode_packed( & sig, & args) ?) ?
201202 }
202203 }
203- CastSubcommand :: CalldataDecode { sig, calldata } => {
204+ CastSubcommand :: DecodeCalldata { sig, calldata } => {
204205 let tokens = SimpleCast :: calldata_decode ( & sig, & calldata, true ) ?;
205206 print_tokens ( & tokens) ;
206207 }
207208 CastSubcommand :: CalldataEncode { sig, args } => {
208209 sh_println ! ( "{}" , SimpleCast :: calldata_encode( sig, & args) ?) ?;
209210 }
210- CastSubcommand :: StringDecode { data } => {
211+ CastSubcommand :: DecodeString { data } => {
211212 let tokens = SimpleCast :: calldata_decode ( "Any(string)" , & data, true ) ?;
212213 print_tokens ( & tokens) ;
213214 }
215+ CastSubcommand :: DecodeEvent { sig, data } => {
216+ let decoded_event = if let Some ( event_sig) = sig {
217+ get_event ( event_sig. as_str ( ) ) ?. decode_log_parts ( None , & hex:: decode ( data) ?, false ) ?
218+ } else {
219+ let data = data. strip_prefix ( "0x" ) . unwrap_or ( data. as_str ( ) ) ;
220+ let selector = data. get ( ..64 ) . unwrap_or_default ( ) ;
221+ let identified_event =
222+ SignaturesIdentifier :: new ( Config :: foundry_cache_dir ( ) , false ) ?
223+ . write ( )
224+ . await
225+ . identify_event ( & hex:: decode ( selector) ?)
226+ . await ;
227+ if let Some ( event) = identified_event {
228+ let _ = sh_println ! ( "{}" , event. signature( ) ) ;
229+ let data = data. get ( 64 ..) . unwrap_or_default ( ) ;
230+ get_event ( event. signature ( ) . as_str ( ) ) ?. decode_log_parts (
231+ None ,
232+ & hex:: decode ( data) ?,
233+ false ,
234+ ) ?
235+ } else {
236+ eyre:: bail!( "No matching event signature found for selector `{selector}`" )
237+ }
238+ } ;
239+ print_tokens ( & decoded_event. body ) ;
240+ }
241+ CastSubcommand :: DecodeError { sig, data } => {
242+ let error = if let Some ( err_sig) = sig {
243+ get_error ( err_sig. as_str ( ) ) ?
244+ } else {
245+ let data = data. strip_prefix ( "0x" ) . unwrap_or ( data. as_str ( ) ) ;
246+ let selector = data. get ( ..8 ) . unwrap_or_default ( ) ;
247+ let identified_error =
248+ SignaturesIdentifier :: new ( Config :: foundry_cache_dir ( ) , false ) ?
249+ . write ( )
250+ . await
251+ . identify_error ( & hex:: decode ( selector) ?)
252+ . await ;
253+ if let Some ( error) = identified_error {
254+ let _ = sh_println ! ( "{}" , error. signature( ) ) ;
255+ error
256+ } else {
257+ eyre:: bail!( "No matching error signature found for selector `{selector}`" )
258+ }
259+ } ;
260+ let decoded_error = error. decode_error ( & hex:: decode ( data) ?) ?;
261+ print_tokens ( & decoded_error. body ) ;
262+ }
214263 CastSubcommand :: Interface ( cmd) => cmd. run ( ) . await ?,
215264 CastSubcommand :: CreationCode ( cmd) => cmd. run ( ) . await ?,
216265 CastSubcommand :: ConstructorArgs ( cmd) => cmd. run ( ) . await ?,
0 commit comments