use alloy_primitives::{Address, U256, address};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FlashLoanProvider {
Balancer,
MakerDao,
AaveV3,
}
impl FlashLoanProvider {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Balancer => "Balancer",
Self::MakerDao => "MakerDAO",
Self::AaveV3 => "Aave V3",
}
}
#[must_use]
pub const fn contract_address(self, chain_id: u64) -> Option<Address> {
match (self, chain_id) {
(Self::Balancer, 1 | 100) => Some(address!("BA12222222228d8Ba445958a75a0704d566BF2C8")),
(Self::AaveV3, 1) => Some(address!("87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2")),
(Self::AaveV3, 100) => Some(address!("b50201558B00496A145fE76f7424749556E326D8")),
_ => None,
}
}
#[must_use]
pub const fn is_supported_on(self, chain_id: u64) -> bool {
self.contract_address(chain_id).is_some()
}
}
#[derive(Debug, Clone)]
pub struct FlashLoanParams {
pub provider: FlashLoanProvider,
pub token: Address,
pub amount: U256,
pub chain_id: u64,
}
impl FlashLoanParams {
#[must_use]
pub const fn new(
provider: FlashLoanProvider,
token: Address,
amount: U256,
chain_id: u64,
) -> Self {
Self { provider, token, amount, chain_id }
}
#[must_use]
pub const fn provider_name(&self) -> &'static str {
self.provider.name()
}
#[must_use]
pub const fn is_provider_supported(&self) -> bool {
self.provider.is_supported_on(self.chain_id)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn flash_loan_provider_name() {
assert_eq!(FlashLoanProvider::Balancer.name(), "Balancer");
assert_eq!(FlashLoanProvider::MakerDao.name(), "MakerDAO");
assert_eq!(FlashLoanProvider::AaveV3.name(), "Aave V3");
}
#[test]
fn flash_loan_provider_contract_address_balancer() {
assert!(FlashLoanProvider::Balancer.contract_address(1).is_some());
assert!(FlashLoanProvider::Balancer.contract_address(100).is_some());
assert!(FlashLoanProvider::Balancer.contract_address(42161).is_none());
}
#[test]
fn flash_loan_provider_contract_address_maker() {
assert!(FlashLoanProvider::MakerDao.contract_address(1).is_none());
assert!(FlashLoanProvider::MakerDao.contract_address(999).is_none());
}
#[test]
fn flash_loan_provider_contract_address_aave() {
assert!(FlashLoanProvider::AaveV3.contract_address(1).is_some());
assert!(FlashLoanProvider::AaveV3.contract_address(100).is_some());
assert!(FlashLoanProvider::AaveV3.contract_address(42161).is_none());
}
#[test]
fn flash_loan_provider_is_supported_on() {
assert!(FlashLoanProvider::Balancer.is_supported_on(1));
assert!(!FlashLoanProvider::Balancer.is_supported_on(42161));
}
#[test]
fn flash_loan_params_new() {
let params = FlashLoanParams::new(
FlashLoanProvider::Balancer,
Address::ZERO,
U256::from(1_000_000u64),
1,
);
assert_eq!(params.provider_name(), "Balancer");
assert!(params.is_provider_supported());
}
#[test]
fn flash_loan_params_unsupported_chain() {
let params = FlashLoanParams::new(
FlashLoanProvider::Balancer,
Address::ZERO,
U256::from(1_000_000u64),
999,
);
assert!(!params.is_provider_supported());
}
}