Skip to content

Commit

Permalink
fix: ingest domain when instantiating TypedData (#453)
Browse files Browse the repository at this point in the history
* fix: ingest domain when intantiating typeddata

* fix: allow empty types in type parser
  • Loading branch information
prestwich authored Dec 16, 2023
1 parent 5233e0f commit c59d1ff
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
21 changes: 18 additions & 3 deletions crates/dyn-abi/src/eip712/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use parser::{Error as TypeParserError, TypeSpecifier};

/// A property is a type and a name. Of the form `type name`. E.g.
/// `uint256 foo` or `(MyStruct[23],bool) bar`.
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PropDef<'a> {
/// The prop type specifier.
pub ty: TypeSpecifier<'a>,
Expand Down Expand Up @@ -47,7 +47,7 @@ impl<'a> PropDef<'a> {
/// Represents a single component type in an EIP-712 `encodeType` type string.
///
/// <https://eips.ethereum.org/EIPS/eip-712#definition-of-encodetype>
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ComponentType<'a> {
/// The span.
pub span: &'a str,
Expand Down Expand Up @@ -83,7 +83,10 @@ impl<'a> ComponentType<'a> {
')' => {
depth -= 1;
if depth == 0 {
props.push(props_str[last..i].try_into()?);
let candidate = &props_str[last..i];
if !candidate.is_empty() {
props.push(candidate.try_into()?);
}
last = i + 1;
break;
}
Expand Down Expand Up @@ -144,6 +147,18 @@ mod tests {

const EXAMPLE: &str = "Transaction(Person from,Person to,Asset tx)Asset(address token,uint256 amount)Person(address wallet,string name)";

#[test]
fn empty_type() {
let empty_domain_type =
ComponentType { span: "EIP712Domain()", type_name: "EIP712Domain", props: vec![] };
assert_eq!(ComponentType::parse("EIP712Domain()"), Ok(empty_domain_type.clone()));

assert_eq!(
EncodeType::try_from("EIP712Domain()"),
Ok(EncodeType { types: vec![empty_domain_type] })
);
}

#[test]
fn test_component_type() {
assert_eq!(
Expand Down
9 changes: 9 additions & 0 deletions crates/dyn-abi/src/eip712/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,15 @@ impl Resolver {
};
Ok(keccak256(to_hash))
}

/// Check if the resolver graph contains a type by its name.
///
/// ## Warning
///
/// This checks by NAME only. It does NOT check for type
pub fn contains_type_name(&self, name: &str) -> bool {
self.nodes.contains_key(name)
}
}

#[cfg(test)]
Expand Down
9 changes: 7 additions & 2 deletions crates/dyn-abi/src/eip712/typed_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,12 @@ impl TypedData {
/// Instantiate [`TypedData`] from a [`SolStruct`] that implements
/// [`serde::Serialize`].
pub fn from_struct<S: SolStruct + Serialize>(s: &S, domain: Option<Eip712Domain>) -> Self {
let mut resolver = Resolver::from_struct::<S>();
let domain = domain.unwrap_or_default();
resolver.ingest_string(domain.encode_type()).expect("domain string always valid");
Self {
domain: domain.unwrap_or_default(),
resolver: Resolver::from_struct::<S>(),
domain,
resolver,
primary_type: S::NAME.into(),
message: serde_json::to_value(s).unwrap(),
}
Expand Down Expand Up @@ -674,6 +677,8 @@ mod tests {

let typed_data = TypedData::from_struct(&s, None);
assert_eq!(typed_data.encode_type().unwrap(), "MyStruct(string name,string otherThing)",);

assert!(typed_data.resolver.contains_type_name("EIP712Domain"));
}

#[test]
Expand Down

0 comments on commit c59d1ff

Please sign in to comment.