use alloy_primitives::U256;
use crate::types::{HUNDRED_THOUSANDS, ONE_HUNDRED_BPS, OrderKind};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QuoteAmounts {
pub sell_amount: U256,
pub buy_amount: U256,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QuoteNetworkFee {
pub amount_in_sell_currency: U256,
pub amount_in_buy_currency: U256,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct QuoteFeeComponent {
pub amount: U256,
pub bps: f64,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct QuoteCosts {
pub network_fee: QuoteNetworkFee,
pub partner_fee: QuoteFeeComponent,
pub protocol_fee: QuoteFeeComponent,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct QuoteAmountsAndCostsResult {
pub is_sell: bool,
pub costs: QuoteCosts,
pub before_all_fees: QuoteAmounts,
pub before_network_costs: QuoteAmounts,
pub after_protocol_fees: QuoteAmounts,
pub after_network_costs: QuoteAmounts,
pub after_partner_fees: QuoteAmounts,
pub after_slippage: QuoteAmounts,
pub amounts_to_sign: QuoteAmounts,
}
#[derive(Debug, Clone)]
pub struct QuoteOrderParams {
pub kind: OrderKind,
pub sell_amount: U256,
pub buy_amount: U256,
pub fee_amount: U256,
}
#[derive(Debug, Clone)]
pub struct QuoteAmountsAndCostsParams {
pub order_params: QuoteOrderParams,
pub protocol_fee_bps: Option<f64>,
pub partner_fee_bps: Option<u32>,
pub slippage_percent_bps: u32,
}
#[derive(Debug, Clone)]
pub struct ProtocolFeeAmountParams {
pub order_params: QuoteOrderParams,
pub protocol_fee_bps: f64,
}
#[must_use]
pub fn get_protocol_fee_amount(params: &ProtocolFeeAmountParams) -> U256 {
let ProtocolFeeAmountParams { order_params, protocol_fee_bps } = params;
if *protocol_fee_bps <= 0.0 {
return U256::ZERO;
}
let is_sell = order_params.kind.is_sell();
let sell_amount = order_params.sell_amount;
let buy_amount = order_params.buy_amount;
let fee_amount = order_params.fee_amount;
let protocol_fee_scale = U256::from(HUNDRED_THOUSANDS);
let protocol_fee_bps_scaled = (*protocol_fee_bps * HUNDRED_THOUSANDS as f64).round() as u64;
let protocol_fee_bps_big = U256::from(protocol_fee_bps_scaled);
if protocol_fee_bps_big.is_zero() {
return U256::ZERO;
}
let one_hundred_bps = U256::from(ONE_HUNDRED_BPS);
if is_sell {
let denominator = one_hundred_bps * protocol_fee_scale - protocol_fee_bps_big;
buy_amount * protocol_fee_bps_big / denominator
} else {
let denominator = one_hundred_bps * protocol_fee_scale + protocol_fee_bps_big;
(sell_amount + fee_amount) * protocol_fee_bps_big / denominator
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PartnerFeeResult {
pub partner_fee_amount: U256,
pub after_partner_fees: QuoteAmounts,
}
#[must_use]
pub fn get_quote_amounts_after_partner_fee(
after_network_costs: &QuoteAmounts,
before_all_fees: &QuoteAmounts,
is_sell: bool,
partner_fee_bps: u32,
) -> PartnerFeeResult {
let one_hundred_bps = U256::from(ONE_HUNDRED_BPS);
let surplus_amount =
if is_sell { before_all_fees.buy_amount } else { before_all_fees.sell_amount };
let partner_fee_amount = if partner_fee_bps > 0 {
surplus_amount * U256::from(partner_fee_bps) / one_hundred_bps
} else {
U256::ZERO
};
let after_partner_fees = if is_sell {
QuoteAmounts {
sell_amount: after_network_costs.sell_amount,
buy_amount: after_network_costs.buy_amount - partner_fee_amount,
}
} else {
QuoteAmounts {
sell_amount: after_network_costs.sell_amount + partner_fee_amount,
buy_amount: after_network_costs.buy_amount,
}
};
PartnerFeeResult { partner_fee_amount, after_partner_fees }
}
#[must_use]
pub fn get_quote_amounts_after_slippage(
after_partner_fees: &QuoteAmounts,
is_sell: bool,
slippage_bps: u32,
) -> QuoteAmounts {
let one_hundred_bps = U256::from(ONE_HUNDRED_BPS);
let slippage_bps_big = U256::from(slippage_bps);
let slippage = |amount: U256| -> U256 { amount * slippage_bps_big / one_hundred_bps };
if is_sell {
QuoteAmounts {
sell_amount: after_partner_fees.sell_amount,
buy_amount: after_partner_fees.buy_amount - slippage(after_partner_fees.buy_amount),
}
} else {
QuoteAmounts {
sell_amount: after_partner_fees.sell_amount + slippage(after_partner_fees.sell_amount),
buy_amount: after_partner_fees.buy_amount,
}
}
}
#[must_use]
pub fn get_quote_amounts_and_costs(
params: &QuoteAmountsAndCostsParams,
) -> QuoteAmountsAndCostsResult {
let QuoteAmountsAndCostsParams {
order_params,
protocol_fee_bps,
partner_fee_bps,
slippage_percent_bps,
} = params;
let partner_fee = partner_fee_bps.map_or(0, |v| v);
let protocol_fee = protocol_fee_bps.map_or(0.0, |v| v);
let is_sell = order_params.kind.is_sell();
let sell_amount = order_params.sell_amount;
let buy_amount = order_params.buy_amount;
let network_cost_amount = order_params.fee_amount;
let network_cost_in_buy = if sell_amount.is_zero() {
U256::ZERO
} else {
buy_amount * network_cost_amount / sell_amount
};
let protocol_fee_amount = get_protocol_fee_amount(&ProtocolFeeAmountParams {
order_params: order_params.clone(),
protocol_fee_bps: protocol_fee,
});
let before_all_fees = if is_sell {
QuoteAmounts {
sell_amount: sell_amount + network_cost_amount,
buy_amount: buy_amount + network_cost_in_buy + protocol_fee_amount,
}
} else {
QuoteAmounts { sell_amount: sell_amount - protocol_fee_amount, buy_amount }
};
let after_protocol_fees = if is_sell {
QuoteAmounts {
sell_amount: before_all_fees.sell_amount,
buy_amount: before_all_fees.buy_amount - protocol_fee_amount,
}
} else {
QuoteAmounts { sell_amount, buy_amount: before_all_fees.buy_amount }
};
let after_network_costs = if is_sell {
QuoteAmounts { sell_amount, buy_amount }
} else {
QuoteAmounts {
sell_amount: sell_amount + network_cost_amount,
buy_amount: after_protocol_fees.buy_amount,
}
};
let PartnerFeeResult { partner_fee_amount, after_partner_fees } =
get_quote_amounts_after_partner_fee(
&after_network_costs,
&before_all_fees,
is_sell,
partner_fee,
);
let after_slippage =
get_quote_amounts_after_slippage(&after_partner_fees, is_sell, *slippage_percent_bps);
let amounts_to_sign = if is_sell {
QuoteAmounts {
sell_amount: before_all_fees.sell_amount,
buy_amount: after_slippage.buy_amount,
}
} else {
QuoteAmounts {
sell_amount: after_slippage.sell_amount,
buy_amount: before_all_fees.buy_amount,
}
};
QuoteAmountsAndCostsResult {
is_sell,
costs: QuoteCosts {
network_fee: QuoteNetworkFee {
amount_in_sell_currency: network_cost_amount,
amount_in_buy_currency: network_cost_in_buy,
},
partner_fee: QuoteFeeComponent { amount: partner_fee_amount, bps: partner_fee as f64 },
protocol_fee: QuoteFeeComponent { amount: protocol_fee_amount, bps: protocol_fee },
},
before_all_fees,
before_network_costs: after_protocol_fees,
after_protocol_fees,
after_network_costs,
after_partner_fees,
after_slippage,
amounts_to_sign,
}
}
#[must_use]
pub fn transform_order(mut order: super::Order) -> super::Order {
let executed_fee_amount: U256 = order.executed_fee_amount.parse().map_or(U256::ZERO, |v| v);
let executed_fee: U256 =
order.executed_fee.as_deref().and_then(|s| s.parse().ok()).map_or(U256::ZERO, |v| v);
order.total_fee = Some((executed_fee_amount + executed_fee).to_string());
if let Some(ref ethflow_data) = order.ethflow_data {
order.valid_to = ethflow_data.user_valid_to;
if let Some(user) = order.onchain_user {
order.owner = user;
}
order.sell_token = crate::config::NATIVE_CURRENCY_ADDRESS;
}
order
}
#[cfg(test)]
mod tests {
use super::*;
fn sell_order() -> QuoteOrderParams {
QuoteOrderParams {
kind: OrderKind::Sell,
sell_amount: U256::from_str_radix("156144455961718918", 10).unwrap(),
fee_amount: U256::from_str_radix("3855544038281082", 10).unwrap(),
buy_amount: U256::from_str_radix("18632013982", 10).unwrap(),
}
}
fn buy_order() -> QuoteOrderParams {
QuoteOrderParams {
kind: OrderKind::Buy,
sell_amount: U256::from_str_radix("168970833896526983", 10).unwrap(),
fee_amount: U256::from_str_radix("2947344072902629", 10).unwrap(),
buy_amount: U256::from_str_radix("2000000000", 10).unwrap(),
}
}
#[test]
fn sell_after_network_costs_equals_api_sell_amount() {
let order_params = sell_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: None,
});
assert_eq!(result.after_network_costs.sell_amount, order_params.sell_amount);
}
#[test]
fn sell_before_network_costs_is_sell_plus_fee() {
let order_params = sell_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: None,
});
assert_eq!(
result.before_network_costs.sell_amount,
order_params.sell_amount + order_params.fee_amount
);
}
#[test]
fn buy_after_network_costs_is_sell_plus_fee() {
let order_params = buy_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: None,
});
assert_eq!(
result.after_network_costs.sell_amount,
order_params.sell_amount + order_params.fee_amount
);
}
#[test]
fn buy_before_network_costs_is_raw_sell() {
let order_params = buy_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: None,
});
assert_eq!(result.before_network_costs.sell_amount, order_params.sell_amount);
}
#[test]
fn sell_buy_amount_includes_network_cost_in_buy_currency() {
let order_params = sell_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: None,
});
let network_cost_in_buy =
order_params.buy_amount * order_params.fee_amount / order_params.sell_amount;
assert_eq!(
result.before_network_costs.buy_amount,
order_params.buy_amount + network_cost_in_buy
);
assert_eq!(result.after_network_costs.buy_amount, order_params.buy_amount);
}
#[test]
fn buy_buy_amount_unchanged_by_network_costs() {
let order_params = buy_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: None,
});
assert_eq!(result.after_network_costs.buy_amount, result.before_network_costs.buy_amount);
}
#[test]
fn sell_partner_fee_subtracted_from_buy() {
let order_params = sell_order();
let partner_fee_bps = 100u32;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: Some(partner_fee_bps),
protocol_fee_bps: None,
});
let network_cost_in_buy =
order_params.buy_amount * order_params.fee_amount / order_params.sell_amount;
let buy_before_all_fees = order_params.buy_amount + network_cost_in_buy;
let expected =
buy_before_all_fees * U256::from(partner_fee_bps) / U256::from(ONE_HUNDRED_BPS);
assert_eq!(result.costs.partner_fee.amount, expected);
}
#[test]
fn buy_partner_fee_added_to_sell() {
let order_params = buy_order();
let partner_fee_bps = 100u32;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: Some(partner_fee_bps),
protocol_fee_bps: None,
});
let expected =
order_params.sell_amount * U256::from(partner_fee_bps) / U256::from(ONE_HUNDRED_BPS);
assert_eq!(result.costs.partner_fee.amount, expected);
}
#[test]
fn sell_slippage_subtracted_from_buy() {
let order_params = sell_order();
let slippage_bps = 200u32;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: slippage_bps,
partner_fee_bps: None,
protocol_fee_bps: None,
});
let buy_after_network = order_params.buy_amount;
let slippage = buy_after_network * U256::from(slippage_bps) / U256::from(ONE_HUNDRED_BPS);
assert_eq!(result.after_slippage.buy_amount, buy_after_network - slippage);
}
#[test]
fn buy_slippage_added_to_sell() {
let order_params = buy_order();
let slippage_bps = 200u32;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: slippage_bps,
partner_fee_bps: None,
protocol_fee_bps: None,
});
let sell_after_network = order_params.sell_amount + order_params.fee_amount;
let slippage = sell_after_network * U256::from(slippage_bps) / U256::from(ONE_HUNDRED_BPS);
assert_eq!(result.after_slippage.sell_amount, sell_after_network + slippage);
}
#[test]
fn sell_protocol_fee_calculated_correctly() {
let order_params = sell_order();
let protocol_fee_bps = 20.0;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: Some(protocol_fee_bps),
});
let bps = U256::from(protocol_fee_bps as u64);
let denominator = U256::from(ONE_HUNDRED_BPS) - bps;
let expected = order_params.buy_amount * bps / denominator;
assert_eq!(result.costs.protocol_fee.amount, expected);
}
#[test]
fn buy_protocol_fee_calculated_correctly() {
let order_params = buy_order();
let protocol_fee_bps = 20.0;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: Some(protocol_fee_bps),
});
let sell_after_network = order_params.sell_amount + order_params.fee_amount;
let bps = U256::from(protocol_fee_bps as u64);
let denominator = U256::from(ONE_HUNDRED_BPS) + bps;
let expected = sell_after_network * bps / denominator;
assert_eq!(result.costs.protocol_fee.amount, expected);
}
#[test]
fn sell_before_all_fees_includes_protocol_fee_once() {
let order_params = sell_order();
let protocol_fee_bps = 20.0;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: Some(protocol_fee_bps),
});
assert_eq!(
result.before_all_fees.buy_amount,
result.before_network_costs.buy_amount + result.costs.protocol_fee.amount
);
}
#[test]
fn buy_before_all_fees_includes_protocol_fee_once() {
let order_params = buy_order();
let protocol_fee_bps = 20.0;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: Some(protocol_fee_bps),
});
assert_eq!(
result.before_all_fees.sell_amount,
result.before_network_costs.sell_amount - result.costs.protocol_fee.amount
);
}
#[test]
fn sell_fractional_protocol_fee_bps() {
let order_params = sell_order();
let protocol_fee_bps: f64 = 0.003;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: Some(protocol_fee_bps),
});
let bps = U256::from((protocol_fee_bps * HUNDRED_THOUSANDS as f64) as u64);
let denominator = U256::from(ONE_HUNDRED_BPS) * U256::from(HUNDRED_THOUSANDS) - bps;
let expected = order_params.buy_amount * bps / denominator;
assert_eq!(result.costs.protocol_fee.amount, expected);
assert_eq!(result.costs.protocol_fee.amount, U256::from(5589u64));
}
#[test]
fn buy_fractional_protocol_fee_bps() {
let order_params = buy_order();
let protocol_fee_bps: f64 = 0.00071;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 0,
partner_fee_bps: None,
protocol_fee_bps: Some(protocol_fee_bps),
});
assert_eq!(result.costs.protocol_fee.amount, U256::from(12_206_189_769u64));
}
#[test]
fn sell_partner_fee_with_protocol_fee() {
let order_params = sell_order();
let protocol_fee_bps = 20.0;
let partner_fee_bps = 100u32;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: Some(partner_fee_bps),
protocol_fee_bps: Some(protocol_fee_bps),
});
let buy_after = order_params.buy_amount;
let protocol_bps = U256::from(protocol_fee_bps as u64);
let protocol_denom = U256::from(ONE_HUNDRED_BPS) - protocol_bps;
let protocol_fee = buy_after * protocol_bps / protocol_denom;
let network_cost_in_buy = buy_after * order_params.fee_amount / order_params.sell_amount;
let buy_before_all_fees = buy_after + network_cost_in_buy + protocol_fee;
let expected_partner =
buy_before_all_fees * U256::from(partner_fee_bps) / U256::from(ONE_HUNDRED_BPS);
assert_eq!(result.costs.partner_fee.amount, expected_partner);
assert_eq!(result.after_partner_fees.buy_amount, buy_after - expected_partner);
}
#[test]
fn buy_partner_fee_with_protocol_fee() {
let order_params = buy_order();
let protocol_fee_bps = 20.0;
let partner_fee_bps = 100u32;
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params: order_params.clone(),
slippage_percent_bps: 0,
partner_fee_bps: Some(partner_fee_bps),
protocol_fee_bps: Some(protocol_fee_bps),
});
let sell_amount = order_params.sell_amount;
let fee_amount = order_params.fee_amount;
let sell_after_network = sell_amount + fee_amount;
let protocol_bps = U256::from(protocol_fee_bps as u64);
let protocol_denom = U256::from(ONE_HUNDRED_BPS) + protocol_bps;
let protocol_fee = sell_after_network * protocol_bps / protocol_denom;
let sell_before_all_fees = sell_amount - protocol_fee;
let expected_partner =
sell_before_all_fees * U256::from(partner_fee_bps) / U256::from(ONE_HUNDRED_BPS);
assert_eq!(result.costs.partner_fee.amount, expected_partner);
assert_eq!(result.after_partner_fees.sell_amount, sell_after_network + expected_partner);
}
#[test]
fn sell_protocol_fee_zero_bps() {
let order_params = sell_order();
let amount = get_protocol_fee_amount(&ProtocolFeeAmountParams {
order_params,
protocol_fee_bps: 0.0,
});
assert_eq!(amount, U256::ZERO);
}
#[test]
fn sell_protocol_fee_negative_bps() {
let order_params = sell_order();
let amount = get_protocol_fee_amount(&ProtocolFeeAmountParams {
order_params,
protocol_fee_bps: -1.0,
});
assert_eq!(amount, U256::ZERO);
}
#[test]
fn sell_order_zero_sell_amount() {
let order_params = QuoteOrderParams {
kind: OrderKind::Sell,
sell_amount: U256::ZERO,
buy_amount: U256::from(1000u64),
fee_amount: U256::from(100u64),
};
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 50,
partner_fee_bps: None,
protocol_fee_bps: None,
});
assert_eq!(result.costs.network_fee.amount_in_buy_currency, U256::ZERO);
}
#[test]
fn partner_fee_zero_bps() {
let amounts =
QuoteAmounts { sell_amount: U256::from(1000u64), buy_amount: U256::from(500u64) };
let result = get_quote_amounts_after_partner_fee(&amounts, &amounts, true, 0);
assert_eq!(result.partner_fee_amount, U256::ZERO);
assert_eq!(result.after_partner_fees.buy_amount, U256::from(500u64));
}
#[test]
fn sell_slippage_reduces_buy_amount() {
let amounts =
QuoteAmounts { sell_amount: U256::from(1000u64), buy_amount: U256::from(10_000u64) };
let result = get_quote_amounts_after_slippage(&amounts, true, 100); assert_eq!(result.sell_amount, U256::from(1000u64));
assert!(result.buy_amount < U256::from(10_000u64));
}
#[test]
fn buy_slippage_increases_sell_amount() {
let amounts =
QuoteAmounts { sell_amount: U256::from(10_000u64), buy_amount: U256::from(1000u64) };
let result = get_quote_amounts_after_slippage(&amounts, false, 100); assert!(result.sell_amount > U256::from(10_000u64));
assert_eq!(result.buy_amount, U256::from(1000u64));
}
#[test]
fn buy_order_amounts_to_sign_correct() {
let order_params = buy_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 50,
partner_fee_bps: Some(50),
protocol_fee_bps: Some(10.0),
});
assert_eq!(result.amounts_to_sign.sell_amount, result.after_slippage.sell_amount);
assert_eq!(result.amounts_to_sign.buy_amount, result.before_all_fees.buy_amount);
assert!(!result.is_sell);
}
#[test]
fn sell_order_amounts_to_sign_correct() {
let order_params = sell_order();
let result = get_quote_amounts_and_costs(&QuoteAmountsAndCostsParams {
order_params,
slippage_percent_bps: 50,
partner_fee_bps: Some(50),
protocol_fee_bps: Some(10.0),
});
assert_eq!(result.amounts_to_sign.sell_amount, result.before_all_fees.sell_amount);
assert_eq!(result.amounts_to_sign.buy_amount, result.after_slippage.buy_amount);
assert!(result.is_sell);
}
#[test]
fn transform_order_sets_total_fee() {
let json = serde_json::json!({
"uid": "0xmockuid",
"sellToken": "0xfff9976782d46cc05630d1f6ebab18b2324d6b14",
"buyToken": "0x1c7d4b196cb0c7b01d743fbc6116a902379c7238",
"receiver": "0x0000000000000000000000000000000000000000",
"sellAmount": "1000",
"buyAmount": "500",
"validTo": 1700000000u32,
"appData": "0x0000000000000000000000000000000000000000000000000000000000000000",
"feeAmount": "10",
"kind": "sell",
"partiallyFillable": false,
"creationDate": "2024-01-01T00:00:00Z",
"owner": "0x0000000000000000000000000000000000000000",
"executedSellAmount": "100",
"executedSellAmountBeforeFees": "100",
"executedBuyAmount": "50",
"executedFeeAmount": "5",
"invalidated": false,
"status": "open",
"signingScheme": "eip712",
"signature": "0x",
});
let order: super::super::Order = serde_json::from_value(json).unwrap();
let enriched = transform_order(order);
assert!(enriched.total_fee.is_some());
assert_eq!(enriched.total_fee.unwrap(), "5");
}
}