Skip to content

Commit

Permalink
auth-server: add output net of fees
Browse files Browse the repository at this point in the history
  • Loading branch information
sehyunc committed Jan 21, 2025
1 parent f4feb0e commit ef6fe5b
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 42 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions auth/auth-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ renegade-circuit-types = { workspace = true }
renegade-common = { workspace = true }
renegade-constants = { workspace = true }
renegade-config = { workspace = true }
renegade-crypto = { workspace = true }
renegade-util = { workspace = true }
renegade-api = { workspace = true }

Expand Down
43 changes: 35 additions & 8 deletions auth/auth-server/src/telemetry/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ use crate::{
ASSET_METRIC_TAG, BASE_ASSET_METRIC_TAG, EXTERNAL_MATCH_BASE_VOLUME,
EXTERNAL_MATCH_FILL_RATIO, EXTERNAL_MATCH_QUOTE_VOLUME, EXTERNAL_MATCH_SETTLED_BASE_VOLUME,
EXTERNAL_MATCH_SETTLED_QUOTE_VOLUME, EXTERNAL_ORDER_BASE_VOLUME,
EXTERNAL_ORDER_QUOTE_VOLUME, NUM_EXTERNAL_MATCH_REQUESTS, OUR_OUTPUT_NET_OF_GAS_TAG,
OUR_PRICE_TAG, QUOTE_NET_OUT_VALUE_DIFF_BPS_METRIC, QUOTE_PRICE_DIFF_BPS_METRIC,
SETTLEMENT_STATUS_TAG, SOURCE_NAME_TAG, SOURCE_OUTPUT_NET_OF_GAS_TAG, SOURCE_PRICE_TAG,
EXTERNAL_ORDER_QUOTE_VOLUME, NUM_EXTERNAL_MATCH_REQUESTS, OUR_OUTPUT_NET_OF_FEE_TAG,
OUR_OUTPUT_NET_OF_GAS_TAG, OUR_PRICE_TAG, QUOTE_OUTPUT_NET_OF_FEE_DIFF_BPS_METRIC,
QUOTE_OUTPUT_NET_OF_GAS_DIFF_BPS_METRIC, QUOTE_PRICE_DIFF_BPS_METRIC,
SETTLEMENT_STATUS_TAG, SOURCE_NAME_TAG, SOURCE_OUTPUT_NET_OF_FEE_TAG,
SOURCE_OUTPUT_NET_OF_GAS_TAG, SOURCE_PRICE_TAG,
},
};

Expand Down Expand Up @@ -334,7 +336,7 @@ pub(crate) fn record_comparison(
labels = extend_labels_with_base_asset(&base_token.get_addr(), labels);

let price_diff_bps = comparison.price_diff_bps(side);
metrics::gauge!(QUOTE_PRICE_DIFF_BPS_METRIC, labels.as_slice()).set(price_diff_bps as f64);
metrics::gauge!(QUOTE_PRICE_DIFF_BPS_METRIC, labels.as_slice()).set(price_diff_bps);
}

/// Record a quote comparison net of gas cost
Expand All @@ -346,9 +348,8 @@ pub(crate) fn record_output_value_net_of_gas_comparison(
let usdc_per_gas = comparison.usdc_per_gas;
let output_diff_bps = comparison.output_value_net_of_gas_diff_bps(usdc_per_gas, side);

let our_output_net_of_gas = comparison.our_quote.output_value_net_of_gas(usdc_per_gas, side);
let source_output_net_of_gas =
comparison.source_quote.output_value_net_of_gas(usdc_per_gas, side);
let our_output_net_of_gas = comparison.our_quote.output_net_of_gas(usdc_per_gas, side);
let source_output_net_of_gas = comparison.source_quote.output_net_of_gas(usdc_per_gas, side);

let side_label = if side == OrderSide::Sell { "sell" } else { "buy" };
let base_token = Token::from_addr(&comparison.our_quote.base_mint);
Expand All @@ -361,5 +362,31 @@ pub(crate) fn record_output_value_net_of_gas_comparison(
labels.extend(extra_labels.iter().cloned());
labels = extend_labels_with_base_asset(&base_token.get_addr(), labels);

metrics::gauge!(QUOTE_NET_OUT_VALUE_DIFF_BPS_METRIC, labels.as_slice()).set(output_diff_bps);
metrics::gauge!(QUOTE_OUTPUT_NET_OF_GAS_DIFF_BPS_METRIC, labels.as_slice())
.set(output_diff_bps);
}

/// Record a quote comparison net of fee
pub(crate) fn record_output_value_net_of_fee_comparison(
comparison: &QuoteComparison,
side: OrderSide,
extra_labels: &[(String, String)],
) {
let fee_diff_bps = comparison.output_value_net_of_fee_diff_bps(side);

let our_output_net_of_fee = comparison.our_quote.output_net_of_fee(side);
let source_output_net_of_fee = comparison.source_quote.output_net_of_fee(side);

let side_label = if side == OrderSide::Sell { "sell" } else { "buy" };
let base_token = Token::from_addr(&comparison.our_quote.base_mint);
let mut labels = vec![
(SIDE_TAG.to_string(), side_label.to_string()),
(SOURCE_NAME_TAG.to_string(), comparison.source_quote.name.to_string()),
(OUR_OUTPUT_NET_OF_FEE_TAG.to_string(), our_output_net_of_fee.to_string()),
(SOURCE_OUTPUT_NET_OF_FEE_TAG.to_string(), source_output_net_of_fee.to_string()),
];
labels.extend(extra_labels.iter().cloned());
labels = extend_labels_with_base_asset(&base_token.get_addr(), labels);

metrics::gauge!(QUOTE_OUTPUT_NET_OF_FEE_DIFF_BPS_METRIC, labels.as_slice()).set(fee_diff_bps);
}
13 changes: 10 additions & 3 deletions auth/auth-server/src/telemetry/labels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ pub const EXTERNAL_MATCH_SETTLED_QUOTE_VOLUME: &str = "external_match_settled_qu
/// Metric describing the difference in price between our quote and the source
/// quote, in basis points
pub const QUOTE_PRICE_DIFF_BPS_METRIC: &str = "quote.price_diff_bps";
/// Metric describing the difference in net output value between our quote and
/// the source quote, in basis points
pub const QUOTE_NET_OUT_VALUE_DIFF_BPS_METRIC: &str = "quote.net_out_value_diff_bps";
/// Metric describing the difference in output value net of gas between our
/// quote and the source quote, in basis points
pub const QUOTE_OUTPUT_NET_OF_GAS_DIFF_BPS_METRIC: &str = "quote.output_net_of_gas_diff_bps";
/// Metric describing the difference in output value net of fee between our
/// quote and the source quote, in basis points
pub const QUOTE_OUTPUT_NET_OF_FEE_DIFF_BPS_METRIC: &str = "quote.output_net_of_fee_diff_bps";

// ---------------
// | METRIC TAGS |
Expand Down Expand Up @@ -66,3 +69,7 @@ pub const SOURCE_PRICE_TAG: &str = "source_price";
pub const OUR_OUTPUT_NET_OF_GAS_TAG: &str = "our_output_net_of_gas";
/// Metric tag for the comparison source's output net of gas
pub const SOURCE_OUTPUT_NET_OF_GAS_TAG: &str = "source_output_net_of_gas";
/// Metric tag for our output net of fee
pub const OUR_OUTPUT_NET_OF_FEE_TAG: &str = "our_output_net_of_fee";
/// Metric tag for the comparison source's output net of fee
pub const SOURCE_OUTPUT_NET_OF_FEE_TAG: &str = "source_output_net_of_fee";
3 changes: 2 additions & 1 deletion auth/auth-server/src/telemetry/quote_comparison/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::telemetry::helpers::record_output_value_net_of_gas_comparison;
use crate::{
error::AuthServerError,
telemetry::{
helpers::record_comparison,
helpers::{record_comparison, record_output_value_net_of_fee_comparison},
sources::{QuoteResponse, QuoteSource},
},
};
Expand Down Expand Up @@ -82,6 +82,7 @@ impl QuoteComparisonHandler {

record_comparison(&comparison, side, &labels);
record_output_value_net_of_gas_comparison(&comparison, side, &labels);
record_output_value_net_of_fee_comparison(&comparison, side, &labels);
Ok(())
}
}
Expand Down
43 changes: 28 additions & 15 deletions auth/auth-server/src/telemetry/quote_comparison/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ use super::sources::QuoteResponse;
/// Multiplier to convert decimal to basis points (1 basis point = 0.01%)
const DECIMAL_TO_BPS: f64 = 10_000.0;

/// Calculate the difference between two values in basis points.
///
/// Formula: ((value - baseline) / baseline) * 10000
///
/// Returns the relative difference in basis points. A positive result means
/// `value` is higher than the `baseline` by that many basis points.
fn calc_bps_diff(value: f64, baseline: f64) -> f64 {
let diff_ratio = (value - baseline) / baseline;
diff_ratio * DECIMAL_TO_BPS
}

/// Represents a single quote comparison between quotes from different sources
pub struct QuoteComparison<'a> {
/// Our quote
Expand All @@ -25,29 +36,31 @@ impl<'a> QuoteComparison<'a> {
/// Positive bps indicates a better quote for the given side:
/// - Sell: our price > source price
/// - Buy: source price > our price
pub fn price_diff_bps(&self, side: OrderSide) -> i32 {
pub fn price_diff_bps(&self, side: OrderSide) -> f64 {
let our_price = self.our_quote.price();
let source_price = self.source_quote.price();
let price_diff_ratio = match side {
OrderSide::Sell => (our_price - source_price) / source_price,
OrderSide::Buy => (source_price - our_price) / our_price,
};

(price_diff_ratio * DECIMAL_TO_BPS) as i32
match side {
OrderSide::Sell => calc_bps_diff(our_price, source_price),
OrderSide::Buy => calc_bps_diff(source_price, our_price),
}
}

/// Calculate the output value net of gas difference in basis points (bps).
/// Positive bps indicates our quote is better.
pub fn output_value_net_of_gas_diff_bps(&self, usdc_per_gas: f64, side: OrderSide) -> i32 {
let our_output_value_net_of_gas =
self.our_quote.output_value_net_of_gas(usdc_per_gas, side);
pub fn output_value_net_of_gas_diff_bps(&self, usdc_per_gas: f64, side: OrderSide) -> f64 {
let our_output_value_net_of_gas = self.our_quote.output_net_of_gas(usdc_per_gas, side);
let source_output_value_net_of_gas =
self.source_quote.output_value_net_of_gas(usdc_per_gas, side);
self.source_quote.output_net_of_gas(usdc_per_gas, side);

let diff_ratio = (our_output_value_net_of_gas - source_output_value_net_of_gas)
/ source_output_value_net_of_gas;
let bps_diff = diff_ratio * DECIMAL_TO_BPS;
calc_bps_diff(our_output_value_net_of_gas, source_output_value_net_of_gas)
}

/// Calculate the output value net of fee difference in basis points (bps).
/// Positive bps indicates our quote is better.
pub fn output_value_net_of_fee_diff_bps(&self, side: OrderSide) -> f64 {
let our_output_value_net_of_fee = self.our_quote.output_net_of_fee(side);
let source_output_value_net_of_fee = self.source_quote.output_net_of_fee(side);

bps_diff as i32
calc_bps_diff(our_output_value_net_of_fee, source_output_value_net_of_fee)
}
}
49 changes: 35 additions & 14 deletions auth/auth-server/src/telemetry/sources/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub struct QuoteResponse {
pub gas: u64,
/// The name of the source that provided the quote
pub name: String,
/// The fee taken by the source, in units of the received token
pub fee_take: Amount,
}

impl QuoteResponse {
Expand All @@ -48,41 +50,60 @@ impl QuoteResponse {
gas_total * usdc_per_gas
}

/// Calculates the net output value of a trade, accounting for gas costs.
pub fn output_value_net_of_gas(&self, usdc_per_gas: f64, side: OrderSide) -> f64 {
// Get decimal corrected amounts
let base_token = Token::from_addr(&self.base_mint);
let quote_token = Token::from_addr(&self.quote_mint);

let base_amt = base_token.convert_to_decimal(self.base_amount);
let quote_amt = quote_token.convert_to_decimal(self.quote_amount);
/// Calculates output value with gas costs deducted
pub fn output_net_of_gas(&self, usdc_per_gas: f64, side: OrderSide) -> f64 {
let (amount, token) = self.get_receive_amount_mint(side);
let value = token.convert_to_decimal(amount);
self.deduct_gas(value, side, usdc_per_gas)
}

// Get gas cost in USDC
let usdc_gas_cost = self.gas_cost(usdc_per_gas);
/// Calculates output value with fees deducted
pub fn output_net_of_fee(&self, side: OrderSide) -> f64 {
let (amount, token) = self.get_receive_amount_mint(side);
self.deduct_fees(amount, &token)
}

// Subtract gas cost from net output value
/// Helper to apply gas cost deduction based on order side
fn deduct_gas(&self, value: f64, side: OrderSide, usdc_per_gas: f64) -> f64 {
let gas_cost_usdc = self.gas_cost(usdc_per_gas);
match side {
OrderSide::Sell => quote_amt - usdc_gas_cost,
OrderSide::Sell => value - gas_cost_usdc,
OrderSide::Buy => {
let usdc_per_base = self.price();
let gas_cost_in_base = usdc_gas_cost / usdc_per_base;
base_amt - gas_cost_in_base
let gas_cost_in_base = gas_cost_usdc / usdc_per_base;
value - gas_cost_in_base
},
}
}

/// Helper to apply fee deduction
fn deduct_fees(&self, amount: Amount, token: &Token) -> f64 {
let net_amount = amount - self.fee_take;
token.convert_to_decimal(net_amount)
}

/// Gets the amount and token that would be received based on order side
fn get_receive_amount_mint(&self, side: OrderSide) -> (Amount, Token) {
match side {
OrderSide::Sell => (self.quote_amount, Token::from_addr(&self.quote_mint)),
OrderSide::Buy => (self.base_amount, Token::from_addr(&self.base_mint)),
}
}
}

/// Converts the `AtomicMatchApiBundle` into a `QuoteResponse`.
impl From<&AtomicMatchApiBundle> for QuoteResponse {
fn from(bundle: &AtomicMatchApiBundle) -> Self {
let gas = bundle.settlement_tx.gas().map_or(DEFAULT_GAS_ESTIMATION, |gas| gas.as_u64());
let fee_take = bundle.fees.total();
Self {
quote_mint: bundle.match_result.quote_mint.clone(),
base_mint: bundle.match_result.base_mint.clone(),
quote_amount: bundle.match_result.quote_amount,
base_amount: bundle.match_result.base_amount,
gas,
name: RENEGADE_SOURCE_NAME.to_string(),
fee_take,
}
}
}
Expand Down
15 changes: 14 additions & 1 deletion auth/auth-server/src/telemetry/sources/odos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ mod error;
mod types;

use super::QuoteResponse;
use renegade_circuit_types::order::OrderSide;
use renegade_circuit_types::{fixed_point::FixedPoint, order::OrderSide};
use renegade_common::types::token::Token;

use client::OdosClient;

pub use client::OdosConfig;
use renegade_constants::Scalar;
use renegade_crypto::fields::scalar_to_u128;

// -------------
// | Constants |
Expand All @@ -17,6 +19,11 @@ pub use client::OdosConfig;
/// The name of the Odos quote source
const SOURCE_NAME: &str = "odos";

/// The fee rate for Odos Simple Swap using "volatile tokens".
///
/// This is defined in https://docs.odos.xyz/build/fees#swap-fees
const ODOS_FEE_RATE: f64 = 0.0025; // 0.25%

// ----------
// | Source |
// ----------
Expand Down Expand Up @@ -66,13 +73,19 @@ impl OdosQuoteSource {
OrderSide::Sell => (quote.get_in_amount().unwrap(), quote.get_out_amount().unwrap()),
};

// Calculate the fee take
let fee_rate = FixedPoint::from_f64_round_down(ODOS_FEE_RATE);
let receive_amount = Scalar::from(quote.get_out_amount().unwrap());
let fee_take = (fee_rate * receive_amount).floor();

QuoteResponse {
base_amount,
base_mint,
quote_amount,
quote_mint,
gas: quote.gas_estimate as u64,
name: SOURCE_NAME.to_string(),
fee_take: scalar_to_u128(&fee_take),
}
}
}
Expand Down

0 comments on commit ef6fe5b

Please sign in to comment.