fix(eip712): improve argument parsing (#1485)

* fix(eip712): improve argument parsing

* use reexported serde_json

* chore: rustfmt

* fix: add missing salt
This commit is contained in:
Matthias Seitz 2022-07-20 09:09:11 +02:00 committed by GitHub
parent 1d4f3efe8a
commit a958b4fd28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 35 deletions

View File

@ -42,7 +42,7 @@ pub(crate) fn struct_declaration(cx: &Context) -> TokenStream {
let abi_parse = if !cx.human_readable {
quote! {
pub static #abi_name: #ethers_contract::Lazy<#ethers_core::abi::Abi> = #ethers_contract::Lazy::new(|| serde_json::from_str(#abi)
pub static #abi_name: #ethers_contract::Lazy<#ethers_core::abi::Abi> = #ethers_contract::Lazy::new(|| #ethers_core::utils::__serde_json::from_str(#abi)
.expect("invalid abi"));
}
} else {

View File

@ -61,7 +61,6 @@
//! determine if there is a nested eip712 struct. However, this work is not yet complete.
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(unused_crate_dependencies)]
use std::convert::TryFrom;
@ -121,7 +120,7 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
fn type_hash() -> Result<[u8; 32], Self::Error> {
use std::convert::TryFrom;
let decoded = hex::decode(#type_hash)?;
let decoded = #ethers_core::utils::hex::decode(#type_hash)?;
let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?;
Ok(byte_array)
}
@ -129,13 +128,13 @@ fn impl_eip_712_macro(ast: &syn::DeriveInput) -> TokenStream {
// Return the pre-computed domain separator from compile time;
fn domain_separator(&self) -> Result<[u8; 32], Self::Error> {
use std::convert::TryFrom;
let decoded = hex::decode(#domain_separator)?;
let decoded = #ethers_core::utils::hex::decode(#domain_separator)?;
let byte_array: [u8; 32] = <[u8; 32]>::try_from(&decoded[..])?;
Ok(byte_array)
}
fn domain(&self) -> Result<#ethers_core::types::transaction::eip712::EIP712Domain, Self::Error> {
let domain: #ethers_core::types::transaction::eip712::EIP712Domain = serde_json::from_str(#domain_str)?;
let domain: #ethers_core::types::transaction::eip712::EIP712Domain = # ethers_core::utils::__serde_json::from_str(#domain_str)?;
Ok(domain)
}

View File

@ -9,7 +9,7 @@ use syn::{
use crate::{
abi,
abi::{ParamType, Token},
types::{Address, H160, U256},
types::{Address, U256},
utils::keccak256,
};
@ -196,9 +196,14 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
type Error = TokenStream;
fn try_from(input: &syn::DeriveInput) -> Result<EIP712Domain, Self::Error> {
let mut domain = EIP712Domain::default();
let mut domain_name = None;
let mut domain_version = None;
let mut chain_id = None;
let mut verifying_contract = None;
let mut found_eip712_attribute = false;
for attribute in input.attrs.iter() {
'attribute_search: for attribute in input.attrs.iter() {
if let AttrStyle::Outer = attribute.style {
if let Ok(syn::Meta::List(meta)) = attribute.parse_meta() {
if meta.path.is_ident("eip712") {
@ -219,7 +224,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
match ident.to_string().as_ref() {
"name" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.name != String::default() {
if domain_name.is_some() {
return Err(Error::new(
meta.path.span(),
"domain name already specified",
@ -227,7 +232,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
.to_compile_error())
}
domain.name = lit_str.value();
domain_name = Some(lit_str.value());
}
_ => {
return Err(Error::new(
@ -239,7 +244,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
},
"version" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.version != String::default() {
if domain_version.is_some() {
return Err(Error::new(
meta.path.span(),
"domain version already specified",
@ -247,7 +252,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
.to_compile_error())
}
domain.version = lit_str.value();
domain_version = Some(lit_str.value());
}
_ => {
return Err(Error::new(
@ -259,7 +264,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
},
"chain_id" => match meta.lit {
syn::Lit::Int(ref lit_int) => {
if domain.chain_id != U256::default() {
if chain_id.is_some() {
return Err(Error::new(
meta.path.span(),
"domain chain_id already specified",
@ -267,7 +272,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
.to_compile_error())
}
domain.chain_id = U256::from(
chain_id = Some(U256::from(
lit_int.base10_parse::<u64>().map_err(
|_| {
Error::new(
@ -277,7 +282,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
.to_compile_error()
},
)?,
);
));
}
_ => {
return Err(Error::new(
@ -289,8 +294,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
},
"verifying_contract" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.verifying_contract != H160::default()
{
if verifying_contract.is_some() {
return Err(Error::new(
meta.path.span(),
"domain verifying_contract already specified",
@ -298,13 +302,13 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
.to_compile_error());
}
domain.verifying_contract = lit_str.value().parse().map_err(|_| {
verifying_contract = Some(lit_str.value().parse().map_err(|_| {
Error::new(
meta.path.span(),
"failed to parse verifying contract into Address",
)
.to_compile_error()
})?;
})?);
}
_ => {
return Err(Error::new(
@ -316,7 +320,7 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
},
"salt" => match meta.lit {
syn::Lit::Str(ref lit_str) => {
if domain.salt != Option::None {
if domain.salt.is_some() {
return Err(Error::new(
meta.path.span(),
"domain salt already specified",
@ -365,36 +369,41 @@ impl TryFrom<&syn::DeriveInput> for EIP712Domain {
}
}
if domain.name == String::default() {
return Err(Error::new(
domain.name = domain_name.ok_or_else(|| {
Error::new(
meta.path.span(),
"missing required domain attribute: 'name'".to_string(),
)
.to_compile_error())
}
if domain.version == String::default() {
return Err(Error::new(
.to_compile_error()
})?;
domain.version = domain_version.ok_or_else(|| {
Error::new(
meta.path.span(),
"missing required domain attribute: 'version'".to_string(),
)
.to_compile_error())
}
if domain.chain_id == U256::default() {
return Err(Error::new(
.to_compile_error()
})?;
domain.chain_id = chain_id.ok_or_else(|| {
Error::new(
meta.path.span(),
"missing required domain attribute: 'chain_id'".to_string(),
)
.to_compile_error())
}
if domain.verifying_contract == H160::default() {
return Err(Error::new(
.to_compile_error()
})?;
domain.verifying_contract = verifying_contract.ok_or_else(|| {
Error::new(
meta.path.span(),
"missing required domain attribute: 'verifying_contract'"
.to_string(),
)
.to_compile_error())
}
.to_compile_error()
})?;
}
break 'attribute_search
}
}
}

View File

@ -38,6 +38,12 @@ use k256::{ecdsa::SigningKey, PublicKey as K256PublicKey};
use std::convert::{TryFrom, TryInto};
use thiserror::Error;
/// Re-export of serde-json
#[doc(hidden)]
pub mod __serde_json {
pub use serde_json::*;
}
#[derive(Error, Debug)]
pub enum ConversionError {
#[error("Unknown units: {0}")]