use async_trait::async_trait;
use serde::Serialize;
use crate::action::{Request, U256};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
pub enum CallKind {
Call,
DelegateCall,
StaticCall,
Create,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct BalanceChange {
pub owner: String,
pub token: String,
pub delta: i128,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ApprovalChange {
pub token: String,
pub owner: String,
pub spender: String,
pub amount: U256,
}
impl ApprovalChange {
#[must_use]
pub fn is_unlimited(&self) -> bool {
crate::action::u256_is_unlimited(&self.amount)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct CallFrame {
pub kind: CallKind,
pub to: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct SimulationReport {
pub success: bool,
pub balance_changes: Vec<BalanceChange>,
pub approvals: Vec<ApprovalChange>,
pub calls: Vec<CallFrame>,
}
impl SimulationReport {
#[must_use]
pub fn clean() -> Self {
Self {
success: true,
balance_changes: Vec::new(),
approvals: Vec::new(),
calls: Vec::new(),
}
}
#[must_use]
pub fn reverted() -> Self {
Self {
success: false,
..Self::clean()
}
}
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum SimError {
#[error("simulator unavailable: {0}")]
Unavailable(String),
#[error("simulator reply malformed: {0}")]
Malformed(String),
}
#[async_trait]
pub trait Simulator: Send + Sync {
async fn simulate(&self, request: &Request) -> Result<SimulationReport, SimError>;
}