use alloy_primitives::{Address, Bytes, U256};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Call {
pub target: Address,
pub calldata: Bytes,
pub value: U256,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TokenApproval {
pub token: Address,
pub spender: Address,
pub min_amount: U256,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TokenAmount {
pub token: Address,
pub amount: U256,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct PlanFragment {
pub calls: Vec<Call>,
pub approvals: Vec<TokenApproval>,
pub value: U256,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SlippageBps(u16);
impl SlippageBps {
pub const fn new(bps: u16) -> Self {
assert!(bps <= 10_000, "slippage cannot exceed 100%");
Self(bps)
}
pub const fn as_bps(self) -> u16 {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::{address, bytes};
#[test]
fn call_constructs_with_zero_value() {
let call = Call {
target: address!("0x0000000000000000000000000000000000000001"),
calldata: bytes!("deadbeef"),
value: U256::ZERO,
};
assert_eq!(call.value, U256::ZERO);
assert_eq!(call.calldata.len(), 4);
}
#[test]
fn slippage_bps_accepts_10000_bps() {
let _ok = SlippageBps::new(10_000);
}
#[test]
#[should_panic(expected = "slippage cannot exceed 100%")]
fn slippage_bps_rejects_over_10000_bps() {
let _ = SlippageBps::new(10_001);
}
}