Skip to content

Commit cd09dc3

Browse files
fix(eip712): Fix cyclic message types handling (trustwallet#4650)
* fix(eip712): Fix cyclic message types handling * fix(eip712): Add an extra test
1 parent 60aa5f8 commit cd09dc3

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

rust/tw_evm/src/message/eip712/eip712_message.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ mod encode_custom_type {
321321
&field.property_type
322322
};
323323
// Seen this type before? or not a custom type - skip
324-
if !deps.contains(field_type) || custom_types.contains_key(field_type) {
324+
if !deps.contains(field_type) && custom_types.contains_key(field_type) {
325325
types_stack.push(field_type);
326326
}
327327
}
@@ -340,6 +340,8 @@ mod tests {
340340

341341
#[test]
342342
fn test_build_dependencies() {
343+
// This custom types definition has an intentional cycle dependency between `Person` and `Mail`
344+
// to test if the `build_dependencies` function can handle it without getting into an infinite loop.
343345
let custom_types = r#"{
344346
"EIP712Domain": [
345347
{ "name": "name", "type": "string" },
@@ -349,7 +351,8 @@ mod tests {
349351
],
350352
"Person": [
351353
{ "name": "name", "type": "string" },
352-
{ "name": "wallet", "type": "address" }
354+
{ "name": "wallet", "type": "address" },
355+
{ "name": "mail", "type": "Mail" }
353356
],
354357
"Mail": [
355358
{ "name": "from", "type": "Person" },
@@ -402,6 +405,34 @@ mod tests {
402405
)
403406
}
404407

408+
#[test]
409+
fn test_encode_type_cyclic_dependency() {
410+
let custom_types = r#"{
411+
"EIP712Domain": [
412+
{ "name": "name", "type": "string" },
413+
{ "name": "version", "type": "string" },
414+
{ "name": "chainId", "type": "uint256" },
415+
{ "name": "verifyingContract", "type": "address" }
416+
],
417+
"Person": [
418+
{ "name": "name", "type": "string" },
419+
{ "name": "wallet", "type": "address" },
420+
{ "name": "mail", "type": "Mail" }
421+
],
422+
"Mail": [
423+
{ "name": "from", "type": "Person" },
424+
{ "name": "to", "type": "Person" },
425+
{ "name": "contents", "type": "string" }
426+
]
427+
}"#;
428+
429+
let custom_types: CustomTypes = serde_json::from_str(custom_types).expect("alas error!");
430+
assert_eq!(
431+
"Mail(Person from,Person to,string contents)Person(string name,address wallet,Mail mail)",
432+
encode_custom_type::encode_type(&custom_types, "Mail").expect("alas error!")
433+
)
434+
}
435+
405436
#[test]
406437
fn test_encode_type_hash() {
407438
let custom_types = r#"{

0 commit comments

Comments
 (0)