Skip to content

Commit 7823e9a

Browse files
authored
Merge commit from fork
* fix(dyn-abi): don't panic when linearization is empty * slim down
1 parent baa341c commit 7823e9a

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

crates/dyn-abi/src/eip712/resolver.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,9 @@ impl Resolver {
421421
/// <https://eips.ethereum.org/EIPS/eip-712#definition-of-encodetype>
422422
pub fn encode_type(&self, name: &str) -> Result<String> {
423423
let linear = self.linearize(name)?;
424+
if linear.is_empty() {
425+
return Err(Error::missing_type(name));
426+
}
424427
let first = linear.first().unwrap().eip712_encode_type();
425428

426429
// Sort references by name (eip-712 encodeType spec)

crates/dyn-abi/src/eip712/typed_data.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,4 +770,84 @@ mod tests {
770770
let typed_data: TypedData = serde_json::from_value(json).unwrap();
771771
let _hash = typed_data.eip712_signing_hash().unwrap();
772772
}
773+
774+
#[test]
775+
fn primary_types() {
776+
let get_typed_data = |primary: &str, set_types: bool| {
777+
let types = if set_types {
778+
json!({
779+
primary: [
780+
{ "name": "whatever", "type": "string" }
781+
]
782+
})
783+
} else {
784+
json!({})
785+
};
786+
let json = json!({
787+
"types": types,
788+
"primaryType": primary,
789+
"domain": {},
790+
"message": {
791+
"whatever": "hi"
792+
}
793+
});
794+
serde_json::from_value::<TypedData>(json).unwrap()
795+
};
796+
797+
// Valid syntax.
798+
for primary in ["T", "T:U"] {
799+
let typed_data = get_typed_data(primary, false);
800+
let err = typed_data.eip712_signing_hash().unwrap_err();
801+
assert_eq!(err, Error::missing_type(primary));
802+
803+
let typed_data = get_typed_data(primary, true);
804+
let _hash = typed_data.eip712_signing_hash().unwrap();
805+
}
806+
807+
// Invalid syntax, but still parses.
808+
// - `.` in the name is re-parsed as `uint8` for the enum hack;
809+
// - the rest are basic Solidity types;
810+
// Therefore the `try_as_basic_solidity` skips over them, returning `MissingType` because
811+
// the list of linearized types is empty.
812+
for primary in ["T.", "T.U", "bool", "uint256"] {
813+
for set_types in [false, true] {
814+
let typed_data = get_typed_data(primary, set_types);
815+
let err = typed_data.eip712_signing_hash().unwrap_err();
816+
assert_eq!(err, Error::missing_type(primary));
817+
}
818+
}
819+
820+
// Invalid syntax.
821+
for primary in ["T[]", "string[]", "uint256[]", "(bool,string)", "(bool,string)[]"] {
822+
for set_types in [false, true] {
823+
let typed_data = get_typed_data(primary, set_types);
824+
let err = typed_data.eip712_signing_hash().unwrap_err();
825+
assert!(err.to_string().contains("parser error"), "{err}");
826+
}
827+
}
828+
}
829+
830+
#[test]
831+
fn missing_types() {
832+
let json = json!({
833+
"types": {
834+
"User": [
835+
{
836+
"name": "name",
837+
"type": "Unknown"
838+
},
839+
]
840+
},
841+
"primaryType": "User",
842+
"domain": {}
843+
});
844+
let typed_data = serde_json::from_value::<TypedData>(json).unwrap();
845+
let expected_error = Error::missing_type("Unknown");
846+
847+
let ty = typed_data.encode_type().unwrap_err();
848+
assert_eq!(ty, expected_error);
849+
850+
let err = typed_data.eip712_signing_hash().unwrap_err();
851+
assert_eq!(err, expected_error);
852+
}
773853
}

0 commit comments

Comments
 (0)