1use std::{fmt::Display, str::FromStr};
6
7use regex::Regex;
8use serde::{Deserialize, Serialize};
9
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13pub enum AbiError {
14 #[error("Invalid fixed type declare {0}, {1}")]
15 FixedMN(String, String),
16
17 #[error("Invalid integer type declare {0}, {1}")]
18 IntegerM(String, String),
19
20 #[error("Invalid fixed length binary type declare {0}, {1}")]
21 BytesM(String, String),
22
23 #[error("Invalid tuple type declare {0}, {1}")]
24 Tuple(String, String),
25
26 #[error("Invalid fixed-length Array type declare {0}, {1}")]
27 ArrayM(String, String),
28
29 #[error("Invalid Array type declare {0}, {1}")]
30 Array(String, String),
31
32 #[error("Invalid Type declare {0}")]
33 UnknownType(String),
34}
35
36#[derive(Debug, Serialize, Deserialize)]
38#[serde(rename_all = "camelCase")]
39pub struct HardhatArtifact {
40 pub contract_name: String,
41 pub source_name: String,
42 pub abi: Vec<AbiField>,
43 pub bytecode: String,
44 pub deployed_bytecode: String,
45}
46
47#[derive(Debug, Serialize, Deserialize)]
49#[serde(rename_all = "camelCase", tag = "type")]
50pub enum AbiField {
51 Function(Function),
52 Constructor(Constructor),
53 Receive(Receive),
54 Fallback(Fallback),
55 Event(Event),
56 Error(Error),
57}
58
59#[derive(Debug, Serialize, Deserialize)]
61#[serde(rename_all = "camelCase")]
62pub struct Function {
63 pub name: String,
65 #[serde(default = "default_parameters")]
67 pub inputs: Vec<Parameter>,
68 #[serde(default = "default_parameters")]
70 pub outputs: Vec<Parameter>,
71 pub state_mutability: StateMutability,
75}
76
77impl Function {
78 pub fn signature(&self) -> String {
80 let tuple = Self::to_signature(&self.inputs);
81
82 format!("{}{}", self.name, tuple)
83 }
84
85 fn to_signature(params: &[Parameter]) -> String {
86 let mut pairs = vec![];
87
88 for param in params.iter() {
89 if let Some(components) = ¶m.components {
90 let element = Self::to_signature(components);
91 match ¶m.r#type {
92 Type::Array(_) => {
93 pairs.push(format!("{}[]", element));
94 }
95 Type::ArrayM(array_m) => {
96 pairs.push(format!("{}[{}]", element, array_m.m));
97 }
98 _ => {
99 pairs.push(format!("{}", element));
100 }
101 }
102 } else {
103 pairs.push(format!("{}", param.r#type));
104 }
105 }
106
107 format!("({})", pairs.join(","))
108 }
109}
110
111fn default_parameters() -> Vec<Parameter> {
112 vec![]
113}
114
115#[derive(Debug, Serialize, Deserialize)]
117#[serde(rename_all = "camelCase")]
118pub struct Constructor {
119 pub inputs: Vec<Parameter>,
121 pub state_mutability: StateMutability,
125}
126
127impl Constructor {
128 pub fn signature(&self) -> String {
130 let tuple = Self::to_signature(&self.inputs);
131
132 format!("Constructor{}", tuple)
133 }
134
135 fn to_signature(params: &[Parameter]) -> String {
136 let mut pairs = vec![];
137
138 for param in params.iter() {
139 if let Some(components) = ¶m.components {
140 let element = Self::to_signature(components);
141 match ¶m.r#type {
142 Type::Array(_) => {
143 pairs.push(format!("{}[]", element));
144 }
145 Type::ArrayM(array_m) => {
146 pairs.push(format!("{}[{}]", element, array_m.m));
147 }
148 _ => {
149 pairs.push(format!("{}", element));
150 }
151 }
152 } else {
153 pairs.push(format!("{}", param.r#type));
154 }
155 }
156
157 format!("({})", pairs.join(","))
158 }
159}
160
161#[derive(Debug, Serialize, Deserialize)]
163#[serde(rename_all = "camelCase")]
164pub struct Receive {
165 pub state_mutability: StateMutability,
169}
170
171#[derive(Debug, Serialize, Deserialize)]
173#[serde(rename_all = "camelCase")]
174pub struct Fallback {
175 pub state_mutability: StateMutability,
179}
180
181#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
182#[serde(rename_all = "camelCase")]
183pub enum StateMutability {
184 Pure,
185 View,
186 Nonpayable,
187 Payable,
188}
189
190#[derive(Debug, Serialize, Deserialize)]
192#[serde(rename_all = "camelCase")]
193pub struct Event {
194 pub name: String,
196 pub inputs: Vec<Parameter>,
198 pub anonymous: bool,
200}
201
202impl Event {
203 pub fn signature(&self) -> String {
205 let tuple = Self::to_signature(&self.inputs);
206
207 format!("{}{}", self.name, tuple)
208 }
209
210 fn to_signature(params: &[Parameter]) -> String {
211 let mut pairs = vec![];
212
213 for param in params.iter() {
214 if let Some(components) = ¶m.components {
215 let element = Self::to_signature(components);
216 match ¶m.r#type {
217 Type::Array(_) => {
218 pairs.push(format!("{}[]", element));
219 }
220 Type::ArrayM(array_m) => {
221 pairs.push(format!("{}[{}]", element, array_m.m));
222 }
223 _ => {
224 pairs.push(format!("{}", element));
225 }
226 }
227 } else {
228 pairs.push(format!("{}", param.r#type));
229 }
230 }
231
232 format!("({})", pairs.join(","))
233 }
234}
235
236#[derive(Debug, Serialize, Deserialize)]
238#[serde(rename_all = "camelCase")]
239pub struct Error {
240 pub name: String,
242 pub inputs: Vec<Parameter>,
244}
245
246impl Error {
247 pub fn signature(&self) -> String {
249 let tuple = Self::to_signature(&self.inputs);
250
251 format!("{}{}", self.name, tuple)
252 }
253
254 fn to_signature(params: &[Parameter]) -> String {
255 let mut pairs = vec![];
256
257 for param in params.iter() {
258 if let Some(components) = ¶m.components {
259 let element = Self::to_signature(components);
260 match ¶m.r#type {
261 Type::Array(_) => {
262 pairs.push(format!("{}[]", element));
263 }
264 Type::ArrayM(array_m) => {
265 pairs.push(format!("{}[{}]", element, array_m.m));
266 }
267 _ => {
268 pairs.push(format!("{}", element));
269 }
270 }
271 } else {
272 pairs.push(format!("{}", param.r#type));
273 }
274 }
275
276 format!("({})", pairs.join(","))
277 }
278}
279#[derive(Debug, Clone, Serialize, Deserialize)]
281#[serde(rename_all = "camelCase")]
282pub struct Parameter {
283 pub name: String,
285 pub r#type: Type,
287 pub components: Option<Vec<Parameter>>,
289 #[serde(default = "default_indexed")]
291 pub indexed: bool,
292 pub internal_type: Option<String>,
294}
295
296fn default_indexed() -> bool {
297 false
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
302#[serde(rename_all = "camelCase")]
303pub enum SimpleType {
304 Address,
305 Uint,
306 Int,
307 Bool,
308 Fixed,
309 Ufixed,
310 Function,
312 Bytes,
313 String,
314 Tuple,
315}
316
317impl ToString for SimpleType {
318 fn to_string(&self) -> String {
319 match self {
321 Self::Ufixed => "fixed128x18".into(),
322 Self::Fixed => "ufixed128x18".into(),
323 Self::Int => "int256".into(),
324 Self::Uint => "uint256".into(),
325 _ => {
326 let data = serde_json::to_string(self).unwrap();
327
328 data[1..data.len() - 1].to_string()
329 }
330 }
331 }
332}
333
334impl SimpleType {
335 pub fn is_tuple(&self) -> bool {
336 match self {
337 Self::Tuple => true,
338 _ => false,
339 }
340 }
341}
342
343#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
344pub struct FixedMN {
346 pub m: usize,
347 pub n: usize,
348 pub signed: bool,
349}
350
351impl Display for FixedMN {
352 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
353 let value = serde_json::to_string(self).expect("Serialize type to json");
354 write!(f, "{}", &value[1..value.len() - 1])
355 }
356}
357
358impl Serialize for FixedMN {
359 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
360 where
361 S: serde::Serializer,
362 {
363 if self.signed {
364 serializer.serialize_str(&format!("fixed{}x{}", self.m, self.n))
365 } else {
366 serializer.serialize_str(&format!("ufixed{}x{}", self.m, self.n))
367 }
368 }
369}
370
371fn fixed_regex() -> Regex {
372 Regex::new(r"^(u){0,1}fixed(\d{1,3})x(\d{1,3})$").unwrap()
373}
374
375impl<'de> Deserialize<'de> for FixedMN {
376 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
377 where
378 D: serde::Deserializer<'de>,
379 {
380 let data = String::deserialize(deserializer)?;
381
382 if let Some(captures) = fixed_regex().captures(&data) {
383 let signed = captures.get(1).map(|_| false).unwrap_or(true);
384
385 let m: usize = (&captures[2]).parse().map_err(serde::de::Error::custom)?;
386 let n: usize = (&captures[3]).parse().map_err(serde::de::Error::custom)?;
387
388 if m < 8 || m > 256 || m % 8 != 0 {
389 return Err(AbiError::FixedMN(
390 data,
391 "M bits must meet the condition 0 < M <= 256, M % 8 == 0".to_string(),
392 ))
393 .map_err(serde::de::Error::custom);
394 }
395
396 if n > 80 {
397 return Err(AbiError::FixedMN(
398 data,
399 "decimal numbers N must meet the condition 0 < N <= 80".to_string(),
400 ))
401 .map_err(serde::de::Error::custom);
402 }
403
404 Ok(Self { signed, m, n })
405 } else {
406 return Err(AbiError::FixedMN(
407 data,
408 "{u}fixed<M>x<N>: fixed-point decimal number of M bits, 8 <= M <= 256, M % 8 == 0, and 0 < N <= 80"
409 .to_string(),
410 ))
411 .map_err(serde::de::Error::custom);
412 }
413 }
414}
415
416#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
418pub struct IntegerM {
419 pub signed: bool,
420 pub m: usize,
421}
422
423impl Display for IntegerM {
424 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
425 let value = serde_json::to_string(self).expect("Serialize type to json");
426 write!(f, "{}", &value[1..value.len() - 1])
427 }
428}
429
430impl Serialize for IntegerM {
431 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
432 where
433 S: serde::Serializer,
434 {
435 if self.signed {
436 serializer.serialize_str(&format!("int{}", self.m,))
437 } else {
438 serializer.serialize_str(&format!("uint{}", self.m,))
439 }
440 }
441}
442
443fn integer_regex() -> Regex {
444 Regex::new(r"^(u){0,1}int(\d{1,3})$").unwrap()
445}
446
447impl<'de> Deserialize<'de> for IntegerM {
448 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
449 where
450 D: serde::Deserializer<'de>,
451 {
452 let data = String::deserialize(deserializer)?;
453
454 if let Some(captures) = integer_regex().captures(&data) {
455 let signed = captures.get(1).map(|_| false).unwrap_or(true);
456
457 let m: usize = (&captures[2]).parse().map_err(serde::de::Error::custom)?;
458
459 if m < 8 || m > 256 || m % 8 != 0 {
460 return Err(AbiError::IntegerM(
461 data,
462 "M bits must meet the condition 0 < M <= 256, M % 8 == 0".to_string(),
463 ))
464 .map_err(serde::de::Error::custom);
465 }
466
467 Ok(Self { signed, m })
468 } else {
469 return Err(AbiError::FixedMN(
470 data,
471 "{u}int<M>: unsigned integer type of M bits, 0 < M <= 256, M % 8 == 0".to_string(),
472 ))
473 .map_err(serde::de::Error::custom);
474 }
475 }
476}
477
478#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
479pub struct BytesM {
481 pub m: usize,
482}
483
484impl Display for BytesM {
485 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
486 let value = serde_json::to_string(self).expect("Serialize type to json");
487 write!(f, "{}", &value[1..value.len() - 1])
488 }
489}
490
491impl Serialize for BytesM {
492 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
493 where
494 S: serde::Serializer,
495 {
496 serializer.serialize_str(&format!("bytes{}", self.m,))
497 }
498}
499
500impl<'de> Deserialize<'de> for BytesM {
501 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
502 where
503 D: serde::Deserializer<'de>,
504 {
505 let data = String::deserialize(deserializer)?;
506
507 if data.starts_with("bytes") {
508 let m: usize = (&data[5..]).parse().map_err(serde::de::Error::custom)?;
509
510 if m > 32 {
511 return Err(AbiError::BytesM(data, "0 < M <= 32".to_string()))
512 .map_err(serde::de::Error::custom);
513 }
514
515 Ok(Self { m })
516 } else {
517 return Err(AbiError::BytesM(
518 data,
519 "bytes<M>: binary type of M bytes, 0 < M <= 32".to_string(),
520 ))
521 .map_err(serde::de::Error::custom);
522 }
523 }
524}
525
526#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
527pub enum Type {
528 Simple(SimpleType),
529
530 BytesM(BytesM),
531
532 IntegerM(IntegerM),
533
534 FixedMN(FixedMN),
535
536 ArrayM(Box<ArrayM>),
537 Array(Box<Array>),
538}
539
540impl From<Type> for String {
541 fn from(value: Type) -> Self {
542 let str = serde_json::to_string(&value).unwrap();
543
544 str[1..str.len() - 1].to_owned()
545 }
546}
547
548impl FromStr for Type {
549 type Err = serde_json::Error;
550 fn from_str(s: &str) -> Result<Self, Self::Err> {
551 serde_json::from_str(&format!("\"{}\"", s))
552 }
553}
554
555impl Display for Type {
556 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
557 let value = serde_json::to_string(self).expect("Serialize type to json");
558 write!(f, "{}", &value[1..value.len() - 1])
559 }
560}
561
562impl Serialize for Type {
563 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
564 where
565 S: serde::Serializer,
566 {
567 match self {
568 Self::Simple(simple) => simple.serialize(serializer),
569 Self::BytesM(byte_m) => byte_m.serialize(serializer),
570 Self::IntegerM(integer_m) => integer_m.serialize(serializer),
571 Self::FixedMN(fixed_m) => fixed_m.serialize(serializer),
572 Self::ArrayM(array_m) => array_m.serialize(serializer),
573 Self::Array(array) => array.serialize(serializer),
574 }
575 }
576}
577
578impl<'de> Deserialize<'de> for Type {
579 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
580 where
581 D: serde::Deserializer<'de>,
582 {
583 let data = String::deserialize(deserializer)?;
584
585 let data = format!("\"{}\"", data);
586
587 if let Ok(array_m) = serde_json::from_str::<ArrayM>(&data) {
588 return Ok(Self::ArrayM(Box::new(array_m)));
589 }
590
591 if let Ok(array) = serde_json::from_str::<Array>(&data) {
592 return Ok(Self::Array(Box::new(array)));
593 }
594
595 if let Ok(fixed_m_n) = serde_json::from_str::<FixedMN>(&data) {
596 return Ok(Self::FixedMN(fixed_m_n));
597 }
598
599 if let Ok(integer_m) = serde_json::from_str::<IntegerM>(&data) {
600 return Ok(Self::IntegerM(integer_m));
601 }
602
603 if let Ok(bytes_m) = serde_json::from_str::<BytesM>(&data) {
604 return Ok(Self::BytesM(bytes_m));
605 }
606
607 if let Ok(simple_type) = serde_json::from_str::<SimpleType>(&data) {
608 return Ok(Self::Simple(simple_type));
609 }
610
611 return Err(AbiError::UnknownType(data)).map_err(serde::de::Error::custom);
612 }
613}
614
615#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
616pub struct ArrayM {
618 pub element: Type,
619 pub m: usize,
621}
622
623impl Display for ArrayM {
624 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
625 let value = serde_json::to_string(self).expect("Serialize type to json");
626 write!(f, "{}", &value[1..value.len() - 1])
627 }
628}
629
630impl Serialize for ArrayM {
631 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
632 where
633 S: serde::Serializer,
634 {
635 let element = serde_json::to_string(&self.element).map_err(serde::ser::Error::custom)?;
636
637 serializer.serialize_str(&format!("{}[{}]", &element[1..element.len() - 1], self.m))
638 }
639}
640
641fn array_m_regex() -> Regex {
642 Regex::new(r"\[(\d{1,3})\]$").unwrap()
643}
644
645impl<'de> Deserialize<'de> for ArrayM {
646 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
647 where
648 D: serde::Deserializer<'de>,
649 {
650 let array_m = String::deserialize(deserializer)?;
651
652 let end_with_regex = array_m_regex();
653
654 if let Some(caps) = end_with_regex.captures(&array_m) {
655 let m: usize = (&caps[1]).parse().map_err(serde::de::Error::custom)?;
656
657 let data = format!("\"{}\"", &array_m[..array_m.len() - caps.len() - 2]);
658
659 let element: Type = serde_json::from_str(&data).map_err(serde::de::Error::custom)?;
660
661 return Ok(Self { element, m });
662 } else {
663 return Err(AbiError::ArrayM(
664 array_m,
665 "<type>[M]: a fixed-length array of M elements, M >= 0, of the given type"
666 .to_string(),
667 ))
668 .map_err(serde::de::Error::custom);
669 }
670 }
671}
672
673#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
674pub struct Array {
676 pub element: Type,
677}
678
679impl Display for Array {
680 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
681 let value = serde_json::to_string(self).expect("Serialize type to json");
682 write!(f, "{}", &value[1..value.len() - 1])
683 }
684}
685
686impl Serialize for Array {
687 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
688 where
689 S: serde::Serializer,
690 {
691 let element = serde_json::to_string(&self.element).map_err(serde::ser::Error::custom)?;
692
693 serializer.serialize_str(&format!("{}[]", &element[1..element.len() - 1]))
694 }
695}
696
697impl<'de> Deserialize<'de> for Array {
698 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
699 where
700 D: serde::Deserializer<'de>,
701 {
702 let array_m = String::deserialize(deserializer)?;
703
704 if array_m.ends_with("[]") {
705 let data = format!("\"{}\"", &array_m[..array_m.len() - 2]);
706 let element: Type = serde_json::from_str(&data).map_err(serde::de::Error::custom)?;
707
708 return Ok(Self { element });
709 } else {
710 return Err(AbiError::Array(
711 array_m,
712 "<type>[]: a variable-length array of elements of the given type.".to_string(),
713 ))
714 .map_err(serde::de::Error::custom);
715 }
716 }
717}
718
719#[cfg(test)]
720mod tests {
721
722 use super::*;
723
724 #[test]
725 fn test_fixed_regex() {
726 let re = fixed_regex();
728
729 assert!(re.is_match("ufixed100x18"));
730
731 assert!(re.is_match("fixed100x18"));
732
733 assert!(!re.is_match("fixed1000x18"));
734
735 assert!(!re.is_match("ufixed1000x18"));
736 assert!(!re.is_match("uufixed1000x18"));
737
738 assert!(!re.is_match("fixed-100x18"));
739
740 if let Some(captures) = fixed_regex().captures("fixed128x18") {
741 assert_eq!(captures.get(1), None);
742 assert_eq!(captures.get(2).map(|c| c.as_str()), Some("128"));
743 assert_eq!(captures.get(3).map(|c| c.as_str()), Some("18"));
744 }
745 }
746
747 #[test]
748 fn test_fixed_json() {
749 let fixed: FixedMN = serde_json::from_str(r#""fixed128x18""#).expect("Parse fixed");
750
751 assert_eq!(fixed.signed, true);
752 assert_eq!(fixed.m, 128);
753 assert_eq!(fixed.n, 18);
754
755 let fixed: FixedMN = serde_json::from_str(r#""ufixed128x18""#).expect("Parse fixed");
756
757 assert_eq!(fixed.signed, false);
758 assert_eq!(fixed.m, 128);
759 assert_eq!(fixed.n, 18);
760
761 serde_json::from_str::<FixedMN>(r#""ufixed100x18""#).expect_err("M % 8 == 0");
762
763 serde_json::from_str::<FixedMN>(r#""ufixed128x180""#).expect_err("N <= 80");
764 }
765
766 #[test]
767 fn test_int_json() {
768 let fixed: IntegerM = serde_json::from_str(r#""int128""#).expect("Parse integer");
769
770 assert_eq!(fixed.signed, true);
771 assert_eq!(fixed.m, 128);
772
773 let fixed: IntegerM = serde_json::from_str(r#""uint128""#).expect("Parse integer");
774
775 assert_eq!(fixed.signed, false);
776 assert_eq!(fixed.m, 128);
777
778 serde_json::from_str::<IntegerM>(r#""uint100""#).expect_err("M % 8 == 0");
779 }
780
781 #[test]
782 fn test_end_with() {
783 let end_with_regex = array_m_regex();
784
785 let caps = end_with_regex.captures("Hello[1][123]").unwrap();
786
787 assert_eq!(&caps[1], "123");
788 }
789
790 #[test]
791 fn test_type_serde() {
792 fn check(expect: &str) {
794 let t: Type = expect.parse().expect("Parse type string");
795
796 let data: String = t.into();
797
798 assert_eq!(data, expect);
799 }
800
801 let test_vector = vec![
802 "uint256",
803 "int256",
804 "address",
805 "int8",
806 "uint",
807 "int",
808 "bool",
809 "fixed128x16",
810 "ufixed128x16",
811 "fixed",
812 "ufixed",
813 "bytes",
814 "bytes24",
815 "tuple",
816 "function",
817 "string",
818 "tuple[]",
819 "tuple[][32]",
820 "bool[20]",
821 "uint256[20]",
822 ];
823
824 for v in test_vector {
825 check(v);
826 }
827 }
828
829 #[test]
830 fn test_hardhat_artifact() {
831 let _: HardhatArtifact =
832 serde_json::from_str(include_str!("abi.json")).expect("Parse hardhat artifact");
833 }
834
835 #[test]
836 fn test_field() {
837 let data = r#"
838 {
839 "inputs": [
840 {
841 "internalType": "address",
842 "name": "WETH_",
843 "type": "address"
844 }
845 ],
846 "stateMutability": "nonpayable",
847 "type": "constructor"
848 }
849 "#;
850
851 _ = serde_json::from_str::<AbiField>(data).expect("Parse abi field");
852 }
853}