@@ -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