use cow_sdk_core::{Address, Amount, ValidationReason};
use serde::{Deserialize, Serialize};
use crate::AppDataError;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct FlashloanHints {
pub liquidity_provider: Address,
pub protocol_adapter: Address,
pub receiver: Address,
pub token: Address,
pub amount: Amount,
}
impl FlashloanHints {
pub fn new(
liquidity_provider: Address,
protocol_adapter: Address,
receiver: Address,
token: Address,
amount: Amount,
) -> Result<Self, AppDataError> {
let hints = Self {
liquidity_provider,
protocol_adapter,
receiver,
token,
amount,
};
hints.validate()?;
Ok(hints)
}
pub fn validate(&self) -> Result<(), AppDataError> {
if self.amount == Amount::ZERO {
return Err(AppDataError::InvalidFlashloanHints {
field: "amount",
reason: ValidationReason::OutOfRange {
details: "amount must be a positive decimal integer",
},
});
}
validate_non_zero_address("liquidityProvider", &self.liquidity_provider)?;
validate_non_zero_address("protocolAdapter", &self.protocol_adapter)?;
validate_non_zero_address("receiver", &self.receiver)?;
validate_non_zero_address("token", &self.token)?;
Ok(())
}
}
fn validate_non_zero_address(field: &'static str, address: &Address) -> Result<(), AppDataError> {
if address.is_zero() {
return Err(AppDataError::InvalidFlashloanHints {
field,
reason: ValidationReason::BadShape {
details: "address must be a non-zero 20-byte Ethereum address",
},
});
}
Ok(())
}