From f00f08593b8c8a7157da6b071e9240a06b538468 Mon Sep 17 00:00:00 2001 From: simon0820s Date: Fri, 1 Aug 2025 17:32:53 -0500 Subject: [PATCH 1/5] fix(encode-args-length mismatch): validate inputs length match args length before encode args --- crates/cast/src/lib.rs | 5 +---- crates/common/src/abi.rs | 10 ++++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 412e9bd83ee9b..8b58b0ae319e8 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1762,10 +1762,7 @@ impl SimpleCast { let func = get_func(sig)?; match encode_function_args(&func, args) { Ok(res) => Ok(hex::encode_prefixed(&res[4..])), - Err(e) => eyre::bail!( - "Could not ABI encode the function and arguments. Did you pass in the right types?\nError\n{}", - e - ), + Err(e) => eyre::bail!("{}", e), } } diff --git a/crates/common/src/abi.rs b/crates/common/src/abi.rs index aee64473f135b..7f9c31d685532 100644 --- a/crates/common/src/abi.rs +++ b/crates/common/src/abi.rs @@ -15,6 +15,16 @@ where I: IntoIterator, S: AsRef, { + let args: Vec = args.into_iter().collect(); + + if inputs.len() != args.len() { + eyre::bail!( + "encode length mismatch: expected {} types, got {}", + inputs.len(), + args.len() + ) + } + std::iter::zip(inputs, args) .map(|(input, arg)| coerce_value(&input.selector_type(), arg.as_ref())) .collect() From b952b165e1c55fbd06be06bfc2656bf70d9edd9f Mon Sep 17 00:00:00 2001 From: simon0820s Date: Fri, 1 Aug 2025 17:49:06 -0500 Subject: [PATCH 2/5] feat(encode-args): add test to length validation --- crates/common/src/abi.rs | 45 +++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/crates/common/src/abi.rs b/crates/common/src/abi.rs index 7f9c31d685532..4a685b329cd76 100644 --- a/crates/common/src/abi.rs +++ b/crates/common/src/abi.rs @@ -18,11 +18,7 @@ where let args: Vec = args.into_iter().collect(); if inputs.len() != args.len() { - eyre::bail!( - "encode length mismatch: expected {} types, got {}", - inputs.len(), - args.len() - ) + eyre::bail!("encode length mismatch: expected {} types, got {}", inputs.len(), args.len()) } std::iter::zip(inputs, args) @@ -267,4 +263,43 @@ mod tests { assert_eq!(parsed.indexed[1], DynSolValue::Uint(U256::from_be_bytes([3; 32]), 256)); assert_eq!(parsed.indexed[2], DynSolValue::Address(Address::from_word(param2))); } + + #[test] + fn test_encode_args_length_validation() { + use alloy_json_abi::Param; + + let params = vec![ + Param { + name: "a".to_string(), + ty: "uint256".to_string(), + internal_type: None, + components: vec![], + }, + Param { + name: "b".to_string(), + ty: "address".to_string(), + internal_type: None, + components: vec![], + }, + ]; + + // Less arguments than parameters + let args = vec!["1"]; + let res = encode_args(¶ms, &args); + assert!(res.is_err()); + assert!(format!("{}", res.unwrap_err()).contains("encode length mismatch")); + + // Exact number of arguments and parameters + let args = vec!["1", "0x0000000000000000000000000000000000000001"]; + let res = encode_args(¶ms, &args); + assert!(res.is_ok()); + let values = res.unwrap(); + assert_eq!(values.len(), 2); + + // More arguments than parameters + let args = vec!["1", "0x0000000000000000000000000000000000000001", "extra"]; + let res = encode_args(¶ms, &args); + assert!(res.is_err()); + assert!(format!("{}", res.unwrap_err()).contains("encode length mismatch")); + } } From b3e79384b284641be0e520ccb230e8de99be4d4e Mon Sep 17 00:00:00 2001 From: simon0820s Date: Sun, 10 Aug 2025 19:35:51 -0500 Subject: [PATCH 3/5] feat(abi-encode): fit args validation error message and add validation for packaged abi encode --- crates/cast/src/lib.rs | 4 ++-- crates/common/src/abi.rs | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 45b592731f820..91c45f1da4630 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1809,7 +1809,7 @@ impl SimpleCast { let func = get_func(sig)?; match encode_function_args(&func, args) { Ok(res) => Ok(hex::encode_prefixed(&res[4..])), - Err(e) => eyre::bail!("{}", e), + Err(e) => eyre::bail!("Could not ABI encode the function and arguments: {}", e), } } @@ -1840,7 +1840,7 @@ impl SimpleCast { let encoded = match encode_function_args_packed(&func, args) { Ok(res) => hex::encode(res), Err(e) => eyre::bail!( - "Could not ABI encode the function and arguments. Did you pass in the right types?\nError\n{}", + "Could not ABI encode the function and arguments: {}", e ), }; diff --git a/crates/common/src/abi.rs b/crates/common/src/abi.rs index 4a685b329cd76..7f6710f5c7102 100644 --- a/crates/common/src/abi.rs +++ b/crates/common/src/abi.rs @@ -53,6 +53,13 @@ where I: IntoIterator, S: AsRef, { + + let args: Vec = args.into_iter().collect(); + + if func.inputs.len() != args.len() { + eyre::bail!("encode length mismatch: expected {} types, got {}", func.inputs.len(), args.len()) + } + let params: Vec> = std::iter::zip(&func.inputs, args) .map(|(input, arg)| coerce_value(&input.selector_type(), arg.as_ref())) .collect::>>()? From 86ec88d31657a2ebd8d2124a178ccb29066093de Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:14:06 +0200 Subject: [PATCH 4/5] chore: clippy --- crates/cast/src/lib.rs | 5 +---- crates/common/src/abi.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 91c45f1da4630..4f3eed69d7612 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1839,10 +1839,7 @@ impl SimpleCast { let func = get_func(sig.as_str())?; let encoded = match encode_function_args_packed(&func, args) { Ok(res) => hex::encode(res), - Err(e) => eyre::bail!( - "Could not ABI encode the function and arguments: {}", - e - ), + Err(e) => eyre::bail!("Could not ABI encode the function and arguments: {e}"), }; Ok(format!("0x{encoded}")) } diff --git a/crates/common/src/abi.rs b/crates/common/src/abi.rs index 7f6710f5c7102..176453a1974ca 100644 --- a/crates/common/src/abi.rs +++ b/crates/common/src/abi.rs @@ -53,11 +53,14 @@ where I: IntoIterator, S: AsRef, { - let args: Vec = args.into_iter().collect(); if func.inputs.len() != args.len() { - eyre::bail!("encode length mismatch: expected {} types, got {}", func.inputs.len(), args.len()) + eyre::bail!( + "encode length mismatch: expected {} types, got {}", + func.inputs.len(), + args.len(), + ); } let params: Vec> = std::iter::zip(&func.inputs, args) @@ -290,7 +293,7 @@ mod tests { }, ]; - // Less arguments than parameters + // Less arguments than parameters let args = vec!["1"]; let res = encode_args(¶ms, &args); assert!(res.is_err()); From bd3e8d9c956418f707c0ea006ef763e37f75ba1b Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 21 Aug 2025 13:14:47 +0200 Subject: [PATCH 5/5] fmt --- crates/cast/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cast/src/lib.rs b/crates/cast/src/lib.rs index 4f3eed69d7612..3284cc13b1781 100644 --- a/crates/cast/src/lib.rs +++ b/crates/cast/src/lib.rs @@ -1809,7 +1809,7 @@ impl SimpleCast { let func = get_func(sig)?; match encode_function_args(&func, args) { Ok(res) => Ok(hex::encode_prefixed(&res[4..])), - Err(e) => eyre::bail!("Could not ABI encode the function and arguments: {}", e), + Err(e) => eyre::bail!("Could not ABI encode the function and arguments: {e}"), } }