evmlib/contract/payment_vault/
error.rs1use crate::contract::payment_vault::interface::IPaymentVault;
2use crate::retry;
3
4#[derive(thiserror::Error, Debug)]
5pub enum Error {
6 #[error("Contract error: {0}")]
7 Contract(#[from] alloy::contract::Error),
8 #[error("RPC error: {0}")]
9 Rpc(String),
10 #[error(transparent)]
11 Transaction(#[from] retry::TransactionError),
12
13 #[error("ANT token address is null")]
15 AntTokenNull,
16 #[error("Batch limit exceeded")]
17 BatchLimitExceeded,
18 #[error("Merkle tree depth {depth} exceeds maximum allowed depth {max_depth}")]
19 DepthTooLarge { depth: u8, max_depth: u8 },
20 #[error("Invalid input length")]
21 InvalidInputLength,
22 #[error("Payment already exists for pool hash: {0}")]
23 PaymentAlreadyExists(String),
24 #[error("Payment not found for pool hash: {0}")]
25 PaymentNotFound(String),
26 #[error("Wrong pool count: expected {expected}, got {actual}")]
27 WrongPoolCount { expected: u64, actual: u64 },
28}
29
30impl Error {
31 pub(crate) fn try_decode_revert(data: &[u8]) -> Option<Self> {
33 use alloy::sol_types::SolInterface;
34
35 if data.len() < 4 {
37 return None;
38 }
39
40 let selector: [u8; 4] = data[..4].try_into().ok()?;
41 let error_data = &data[4..];
42
43 if let Ok(contract_error) =
45 IPaymentVault::IPaymentVaultErrors::abi_decode_raw(selector, error_data)
46 {
47 return Some(Self::from_contract_error(contract_error));
48 }
49
50 None
51 }
52
53 fn from_contract_error(error: IPaymentVault::IPaymentVaultErrors) -> Self {
55 use IPaymentVault::IPaymentVaultErrors;
56
57 match error {
58 IPaymentVaultErrors::AntTokenNull(_) => Self::AntTokenNull,
59 IPaymentVaultErrors::BatchLimitExceeded(_) => Self::BatchLimitExceeded,
60 IPaymentVaultErrors::DepthTooLarge(e) => Self::DepthTooLarge {
61 depth: e.depth,
62 max_depth: e.maxDepth,
63 },
64 IPaymentVaultErrors::InvalidInputLength(_) => Self::InvalidInputLength,
65 IPaymentVaultErrors::PaymentAlreadyExists(e) => {
66 Self::PaymentAlreadyExists(hex::encode(e.winnerPoolHash))
67 }
68 IPaymentVaultErrors::WrongPoolCount(e) => Self::WrongPoolCount {
69 expected: e.expected.try_into().unwrap_or(u64::MAX),
70 actual: e.actual.try_into().unwrap_or(u64::MAX),
71 },
72 IPaymentVaultErrors::SafeERC20FailedOperation(e) => {
73 Self::Rpc(format!("SafeERC20 transfer failed for token: {}", e.token))
74 }
75 }
76 }
77}