use std::fmt;
use alloy_primitives::{Address, B256, U256};
use crate::{OrderKind, TokenBalance};
#[derive(Debug, Clone)]
pub struct UnsignedOrder {
pub sell_token: Address,
pub buy_token: Address,
pub receiver: Address,
pub sell_amount: U256,
pub buy_amount: U256,
pub valid_to: u32,
pub app_data: B256,
pub fee_amount: U256,
pub kind: OrderKind,
pub partially_fillable: bool,
pub sell_token_balance: TokenBalance,
pub buy_token_balance: TokenBalance,
}
impl UnsignedOrder {
#[must_use]
pub const fn sell(
sell_token: Address,
buy_token: Address,
sell_amount: U256,
buy_amount: U256,
) -> Self {
Self {
sell_token,
buy_token,
receiver: Address::ZERO,
sell_amount,
buy_amount,
valid_to: 0,
app_data: B256::ZERO,
fee_amount: U256::ZERO,
kind: OrderKind::Sell,
partially_fillable: false,
sell_token_balance: TokenBalance::Erc20,
buy_token_balance: TokenBalance::Erc20,
}
}
#[must_use]
pub const fn buy(
sell_token: Address,
buy_token: Address,
sell_amount: U256,
buy_amount: U256,
) -> Self {
Self {
sell_token,
buy_token,
receiver: Address::ZERO,
sell_amount,
buy_amount,
valid_to: 0,
app_data: B256::ZERO,
fee_amount: U256::ZERO,
kind: OrderKind::Buy,
partially_fillable: false,
sell_token_balance: TokenBalance::Erc20,
buy_token_balance: TokenBalance::Erc20,
}
}
#[must_use]
pub const fn with_receiver(mut self, receiver: Address) -> Self {
self.receiver = receiver;
self
}
#[must_use]
pub const fn with_valid_to(mut self, valid_to: u32) -> Self {
self.valid_to = valid_to;
self
}
#[must_use]
pub const fn with_app_data(mut self, app_data: B256) -> Self {
self.app_data = app_data;
self
}
#[must_use]
pub const fn with_fee_amount(mut self, fee_amount: U256) -> Self {
self.fee_amount = fee_amount;
self
}
#[must_use]
pub const fn with_partially_fillable(mut self) -> Self {
self.partially_fillable = true;
self
}
#[must_use]
pub const fn with_sell_token_balance(mut self, balance: TokenBalance) -> Self {
self.sell_token_balance = balance;
self
}
#[must_use]
pub const fn with_buy_token_balance(mut self, balance: TokenBalance) -> Self {
self.buy_token_balance = balance;
self
}
#[must_use]
pub const fn is_expired(&self, timestamp: u64) -> bool {
timestamp > self.valid_to as u64
}
#[must_use]
pub const fn is_sell(&self) -> bool {
self.kind.is_sell()
}
#[must_use]
pub const fn is_buy(&self) -> bool {
self.kind.is_buy()
}
#[must_use]
pub fn has_custom_receiver(&self) -> bool {
!self.receiver.is_zero()
}
#[must_use]
pub fn has_app_data(&self) -> bool {
!self.app_data.is_zero()
}
#[must_use]
pub fn has_fee(&self) -> bool {
!self.fee_amount.is_zero()
}
#[must_use]
pub const fn is_partially_fillable(&self) -> bool {
self.partially_fillable
}
#[must_use]
pub const fn total_amount(&self) -> U256 {
self.sell_amount.saturating_add(self.buy_amount)
}
}
impl fmt::Display for UnsignedOrder {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} {:#x} → {:#x}", self.kind, self.sell_token, self.buy_token)
}
}