@@ -121,7 +121,6 @@ impl Input {
121121 return Ok ( Bytes :: default ( ) ) ; // fallback or deployer — no input
122122 } ;
123123
124- // ABI
125124 let abi = deployed_abis
126125 . get ( & self . instance )
127126 . ok_or_else ( || anyhow:: anyhow!( "ABI for instance '{}' not found" , & self . instance) ) ?;
@@ -142,7 +141,6 @@ impl Input {
142141
143142 log:: trace!( "Functions found for instance: {}" , & self . instance) ;
144143
145- // Parse calldata
146144 let calldata_args = match & self . calldata {
147145 Some ( Calldata :: Compound ( args) ) => args,
148146 _ => anyhow:: bail!( "Expected compound calldata for function call" ) ,
@@ -156,7 +154,10 @@ impl Input {
156154 ) ;
157155 }
158156
159- log:: trace!( "Starting encoding ABI's paramters for instance: {}" , & self . instance) ;
157+ log:: trace!(
158+ "Starting encoding ABI's parameters for instance: {}" ,
159+ & self . instance
160+ ) ;
160161
161162 let mut encoded = selector. to_vec ( ) ;
162163
@@ -252,3 +253,201 @@ fn default_instance() -> String {
252253fn default_caller ( ) -> Address {
253254 "90F8bf6A479f320ead074411a4B0e7944Ea8c9C1" . parse ( ) . unwrap ( )
254255}
256+
257+ #[ cfg( test) ]
258+ mod tests {
259+
260+ use super :: * ;
261+ use alloy:: json_abi:: JsonAbi ;
262+ use alloy_primitives:: { address, keccak256} ;
263+ use std:: collections:: HashMap ;
264+
265+ #[ test]
266+ fn test_encoded_input_uint256 ( ) {
267+ let raw_metadata = r#"
268+ [
269+ {
270+ "inputs": [{"name": "value", "type": "uint256"}],
271+ "name": "store",
272+ "outputs": [],
273+ "stateMutability": "nonpayable",
274+ "type": "function"
275+ }
276+ ]
277+ "# ;
278+
279+ let parsed_abi: JsonAbi = serde_json:: from_str ( raw_metadata) . unwrap ( ) ;
280+ let selector = keccak256 ( "store(uint256)" . as_bytes ( ) ) [ 0 ..4 ]
281+ . try_into ( )
282+ . unwrap ( ) ;
283+
284+ let input = Input {
285+ instance : "Contract" . to_string ( ) ,
286+ method : Method :: Function ( selector) ,
287+ calldata : Some ( Calldata :: Compound ( vec ! [ CalldataArg :: Literal (
288+ "42" . to_string( ) ,
289+ ) ] ) ) ,
290+ ..Default :: default ( )
291+ } ;
292+
293+ let mut deployed_abis = HashMap :: new ( ) ;
294+ deployed_abis. insert ( "Contract" . to_string ( ) , parsed_abi) ;
295+ let deployed_contracts = HashMap :: new ( ) ;
296+
297+ let encoded = input
298+ . encoded_input ( & deployed_abis, & deployed_contracts)
299+ . unwrap ( ) ;
300+ assert ! ( encoded. 0 . starts_with( & selector) ) ;
301+
302+ type T = ( u64 , ) ;
303+ let decoded: T = T :: abi_decode ( & encoded. 0 [ 4 ..] ) . unwrap ( ) ;
304+ assert_eq ! ( decoded. 0 , 42 ) ;
305+ }
306+
307+ #[ test]
308+ fn test_encoded_input_bool ( ) {
309+ let raw_abi = r#"[
310+ {
311+ "inputs": [{"name": "flag", "type": "bool"}],
312+ "name": "toggle",
313+ "outputs": [],
314+ "stateMutability": "nonpayable",
315+ "type": "function"
316+ }
317+ ]"# ;
318+
319+ let parsed_abi: JsonAbi = serde_json:: from_str ( raw_abi) . unwrap ( ) ;
320+ let selector = keccak256 ( "toggle(bool)" . as_bytes ( ) ) [ 0 ..4 ]
321+ . try_into ( )
322+ . unwrap ( ) ;
323+
324+ let input = Input {
325+ instance : "Contract" . to_string ( ) ,
326+ method : Method :: Function ( selector) ,
327+ calldata : Some ( Calldata :: Compound ( vec ! [ CalldataArg :: Literal (
328+ "true" . to_string( ) ,
329+ ) ] ) ) ,
330+ ..Default :: default ( )
331+ } ;
332+
333+ let mut abis = HashMap :: new ( ) ;
334+ abis. insert ( "Contract" . to_string ( ) , parsed_abi) ;
335+ let contracts = HashMap :: new ( ) ;
336+
337+ let encoded = input. encoded_input ( & abis, & contracts) . unwrap ( ) ;
338+ assert ! ( encoded. 0 . starts_with( & selector) ) ;
339+
340+ type T = ( bool , ) ;
341+ let decoded: T = T :: abi_decode ( & encoded. 0 [ 4 ..] ) . unwrap ( ) ;
342+ assert_eq ! ( decoded. 0 , true ) ;
343+ }
344+
345+ #[ test]
346+ fn test_encoded_input_string ( ) {
347+ let raw_abi = r#"[
348+ {
349+ "inputs": [{"name": "msg", "type": "string"}],
350+ "name": "echo",
351+ "outputs": [],
352+ "stateMutability": "nonpayable",
353+ "type": "function"
354+ }
355+ ]"# ;
356+
357+ let parsed_abi: JsonAbi = serde_json:: from_str ( raw_abi) . unwrap ( ) ;
358+ let selector = keccak256 ( "echo(string)" . as_bytes ( ) ) [ 0 ..4 ]
359+ . try_into ( )
360+ . unwrap ( ) ;
361+
362+ let input = Input {
363+ instance : "Contract" . to_string ( ) ,
364+ method : Method :: Function ( selector) ,
365+ calldata : Some ( Calldata :: Compound ( vec ! [ CalldataArg :: Literal (
366+ "hello" . to_string( ) ,
367+ ) ] ) ) ,
368+ ..Default :: default ( )
369+ } ;
370+
371+ let mut abis = HashMap :: new ( ) ;
372+ abis. insert ( "Contract" . to_string ( ) , parsed_abi) ;
373+ let contracts = HashMap :: new ( ) ;
374+
375+ let encoded = input. encoded_input ( & abis, & contracts) . unwrap ( ) ;
376+ assert ! ( encoded. 0 . starts_with( & selector) ) ;
377+ }
378+
379+ #[ test]
380+ fn test_encoded_input_uint256_array ( ) {
381+ let raw_abi = r#"[
382+ {
383+ "inputs": [{"name": "arr", "type": "uint256[]"}],
384+ "name": "sum",
385+ "outputs": [],
386+ "stateMutability": "nonpayable",
387+ "type": "function"
388+ }
389+ ]"# ;
390+
391+ let parsed_abi: JsonAbi = serde_json:: from_str ( raw_abi) . unwrap ( ) ;
392+ let selector = keccak256 ( "sum(uint256[])" . as_bytes ( ) ) [ 0 ..4 ]
393+ . try_into ( )
394+ . unwrap ( ) ;
395+
396+ let input = Input {
397+ instance : "Contract" . to_string ( ) ,
398+ method : Method :: Function ( selector) ,
399+ calldata : Some ( Calldata :: Compound ( vec ! [ CalldataArg :: Literal (
400+ "[1,2,3]" . to_string( ) ,
401+ ) ] ) ) ,
402+ ..Default :: default ( )
403+ } ;
404+
405+ let mut abis = HashMap :: new ( ) ;
406+ abis. insert ( "Contract" . to_string ( ) , parsed_abi) ;
407+ let contracts = HashMap :: new ( ) ;
408+
409+ let encoded = input. encoded_input ( & abis, & contracts) . unwrap ( ) ;
410+ assert ! ( encoded. 0 . starts_with( & selector) ) ;
411+ }
412+
413+ #[ test]
414+ fn test_encoded_input_address ( ) {
415+ let raw_abi = r#"[
416+ {
417+ "inputs": [{"name": "recipient", "type": "address"}],
418+ "name": "send",
419+ "outputs": [],
420+ "stateMutability": "nonpayable",
421+ "type": "function"
422+ }
423+ ]"# ;
424+
425+ let parsed_abi: JsonAbi = serde_json:: from_str ( raw_abi) . unwrap ( ) ;
426+ let selector = keccak256 ( "send(address)" . as_bytes ( ) ) [ 0 ..4 ]
427+ . try_into ( )
428+ . unwrap ( ) ;
429+
430+ let input = Input {
431+ instance : "Contract" . to_string ( ) ,
432+ method : Method :: Function ( selector) ,
433+ calldata : Some ( Calldata :: Compound ( vec ! [ CalldataArg :: Literal (
434+ "0x1000000000000000000000000000000000000001" . to_string( ) ,
435+ ) ] ) ) ,
436+ ..Default :: default ( )
437+ } ;
438+
439+ let mut abis = HashMap :: new ( ) ;
440+ abis. insert ( "Contract" . to_string ( ) , parsed_abi) ;
441+ let contracts = HashMap :: new ( ) ;
442+
443+ let encoded = input. encoded_input ( & abis, & contracts) . unwrap ( ) ;
444+ assert ! ( encoded. 0 . starts_with( & selector) ) ;
445+
446+ type T = ( alloy_primitives:: Address , ) ;
447+ let decoded: T = T :: abi_decode ( & encoded. 0 [ 4 ..] ) . unwrap ( ) ;
448+ assert_eq ! (
449+ decoded. 0 ,
450+ address!( "0x1000000000000000000000000000000000000001" )
451+ ) ;
452+ }
453+ }
0 commit comments