Skip to content

Commit

Permalink
Add preferred_fee_rate to pair
Browse files Browse the repository at this point in the history
  • Loading branch information
Natarajan Arvind Krishnan committed Dec 17, 2023
1 parent b136479 commit f6d8c44
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 53 deletions.
15 changes: 10 additions & 5 deletions cli/src/display/pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ pub struct PairRawData {
mints: (Pubkey, Pubkey),
#[serde(with = "pubkey_pair")]
fee_collector: (Pubkey, Pubkey),
fee_rates: (u16, u16),
normal_fee_rates: (u16, u16),
preferred_fee_rates: (u16, u16),
total_fees_generated_native: (u128, u128),
total_historical_volume: u128,
total_internally_swapped: (u128, u128),
Expand Down Expand Up @@ -98,7 +99,8 @@ impl From<&PairAccountAndVaults> for PairRawData {
pool_registry: value.pair.pool_registry,
mints: value.pair.mints,
fee_collector: value.pair.fee_collector,
fee_rates: value.pair.fee_rates,
normal_fee_rates: value.pair.normal_fee_rates,
preferred_fee_rates: value.pair.preferred_fee_rates,
total_fees_generated_native,
total_historical_volume,
total_internally_swapped,
Expand Down Expand Up @@ -129,7 +131,8 @@ pub struct PairSideUiData {
mint_name: Option<String>,
#[serde(with = "pubkey")]
fee_collector: Pubkey,
fee_rate: String,
normal_fee_rate: String,
preferred_fee_rate: String,
total_fees_generated_native: Option<String>,
total_internally_swapped: Option<String>,
main_vault: MainVaultUiData,
Expand All @@ -154,7 +157,8 @@ impl From<&PairAccountAndVaults> for PairUiData {
mint: value.pair.mints.0,
mint_name: mint_ui_name(value.pair.mints.0),
fee_collector: value.pair.fee_collector.0,
fee_rate: u16_to_bps(value.pair.fee_rates.0).to_string(),
normal_fee_rate: u16_to_bps(value.pair.normal_fee_rates.0).to_string(),
preferred_fee_rate: u16_to_bps(value.pair.preferred_fee_rates.0).to_string(),
total_fees_generated_native: u128_ui_amount(total_fees_generated_native.0, mint_dec),
total_internally_swapped: u128_ui_amount(total_internally_swapped.0, mint_dec),
main_vault: MainVaultUiData::from(&value.mint_one_main_vault),
Expand All @@ -165,7 +169,8 @@ impl From<&PairAccountAndVaults> for PairUiData {
mint: value.pair.mints.1,
mint_name: mint_ui_name(value.pair.mints.1),
fee_collector: value.pair.fee_collector.1,
fee_rate: u16_to_bps(value.pair.fee_rates.1).to_string(),
normal_fee_rate: u16_to_bps(value.pair.normal_fee_rates.1).to_string(),
preferred_fee_rate: u16_to_bps(value.pair.preferred_fee_rates.1).to_string(),
total_fees_generated_native: u128_ui_amount(total_fees_generated_native.1, mint_dec),
total_internally_swapped: u128_ui_amount(total_internally_swapped.1, mint_dec),
main_vault: MainVaultUiData::from(&value.mint_two_main_vault),
Expand Down
30 changes: 19 additions & 11 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,11 @@ pub enum Subcommand {
#[clap(long, parse(try_from_str=Pubkey::try_from))]
fee_destination: Option<Pubkey>,
#[clap(long)]
/// Configures the pair to a new fee BPS for the specified mint.
fee_bps: Option<u16>,
/// Configures the pair to a new normal fee BPS for the specified mint.
normal_fee_bps: Option<u16>,
#[clap(long)]
/// Configures the pair to a new preferred fee BPS for the specified mint.
preferred_fee_bps: Option<u16>,
},
/// Crank all price histories under a pool registry.
/// This is compute-intensive and likely will not succeed
Expand Down Expand Up @@ -757,8 +760,10 @@ impl Opt {
anyhow!("Failed to get pool registry at {}: {}", pool_registry, e)
})?;
let ix = create_pair(
pair_params.0.fee_bps,
pair_params.1.fee_bps,
pair_params.0.normal_fee_bps,
pair_params.1.normal_fee_bps,
pair_params.0.preferred_fee_bps,
pair_params.1.preferred_fee_bps,
pool_registry_data.admin,
pool_registry,
pair_params.0.mint,
Expand Down Expand Up @@ -792,7 +797,8 @@ impl Opt {
pair,
mint,
fee_destination,
fee_bps,
normal_fee_bps,
preferred_fee_bps,
} => {
let pool_registry_data = get_pool_registry_blocking(&pool_registry, &client)
.map_err(|e| {
Expand All @@ -808,10 +814,10 @@ impl Opt {
return Err(anyhow!("Mint not found in pair"));
}

let (mint_one_fee_rate, mint_two_fee_rate) = if is_mint_one {
(fee_bps, None)
let (mint_one_normal_fee_rate, mint_one_preferred_fee_rate, mint_two_normal_fee_rate, mint_two_preferred_fee_rate) = if is_mint_one {
(normal_fee_bps, preferred_fee_bps, None, None)
} else {
(None, fee_bps)
(None, None, normal_fee_bps, preferred_fee_bps)
};
let (mint_one_fee_dest, mint_two_fee_dest) = if is_mint_one {
(fee_destination, None)
Expand All @@ -823,8 +829,10 @@ impl Opt {
pool_registry,
pair.mints.0,
pair.mints.1,
mint_one_fee_rate,
mint_two_fee_rate,
mint_one_normal_fee_rate,
mint_two_normal_fee_rate,
mint_one_preferred_fee_rate,
mint_two_preferred_fee_rate,
mint_one_fee_dest,
mint_two_fee_dest,
);
Expand Down Expand Up @@ -1145,7 +1153,7 @@ impl Opt {
mint_out,
)
})?;
let (_, fee_destination, _) = pair
let (_, _, fee_destination, _) = pair
.find_fee_attrs(mint_in, mint_out)
.map_err(|_| anyhow!("Could not resolve fee destination from pair"))?;
let compute_budget_ix = Instruction::new_with_borsh(
Expand Down
3 changes: 2 additions & 1 deletion cli/src/ssl_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ pub struct PairMintParams {
#[serde(with = "pubkey")]
pub fee_destination: Pubkey,
/// In basis-points, max 10,000
pub fee_bps: u16,
pub normal_fee_bps: u16,
pub preferred_fee_bps: u16,
}

/// For Anchor instruction encoding.
Expand Down
12 changes: 8 additions & 4 deletions programs/gfx-ssl-v2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,20 @@ pub mod gfx_ssl_v2 {

pub fn create_pair(
ctx: Context<CreatePair>,
mint_one_fee_rate: u16,
mint_two_fee_rate: u16,
mint_one_normal_fee_rate: u16,
mint_two_normal_fee_rate: u16,
mint_one_preferred_fee_rate: u16,
mint_two_preferred_fee_rate: u16
) -> Result<()> {
Ok(())
}

pub fn config_pair(
ctx: Context<ConfigPair>,
mint_one_fee_rate: Option<u16>,
mint_two_fee_rate: Option<u16>,
mint_one_normal_fee_rate: Option<u16>,
mint_two_normal_fee_rate: Option<u16>,
mint_one_preferred_fee_rate: Option<u16>,
mint_two_preferred_fee_rate: Option<u16>,
) -> Result<()> {
Ok(())
}
Expand Down
94 changes: 81 additions & 13 deletions programs/gfx-ssl-v2/src/state/pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
use crate::utils::{u128_from_bytes, u16_to_bps};
use crate::{utils::token_amount, PDAIdentifier, SSLV2Error};
use anchor_lang::prelude::*;
use bytemuck::{Zeroable, Pod};
use rust_decimal::Decimal;
#[cfg(feature = "no-entrypoint")]
use std::fmt::{Display, Formatter};
use std::mem;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use borsh::{BorshSerialize, BorshDeserialize};


/// Scale used to record the historical USD volume swapped.
const USD_VOLUME_DECIMALS: u32 = 6;
Expand All @@ -31,7 +35,7 @@ pub struct Pair {
/// Matched to mints.0 and mints.1 respectively.
/// Fee rates are allowed to be different depending on the input mint.
/// They are expressed as BPS (theoretical maximum = 10_000).
pub fee_rates: (u16, u16),
pub normal_fee_rates: (u16, u16),

/// Historical value that records the total amount of fees collected
/// over the lifetime of the pair.
Expand All @@ -47,7 +51,9 @@ pub struct Pair {
/// Recorded as native token amounts.
pub total_internally_swapped: ([u8; 16], [u8; 16]),

pub _space: [u8; 128],
pub preferred_fee_rates: (u16, u16),

pub _space: Space124,
}

// Compile-time struct size check. Successful deserialization requires
Expand All @@ -60,11 +66,12 @@ impl Default for Pair {
pool_registry: Default::default(),
mints: (Default::default(), Default::default()),
fee_collector: (Default::default(), Default::default()),
fee_rates: (0, 0),
normal_fee_rates: (0, 0),
total_fees_generated_native: ([0; 16], [0; 16]),
total_historical_volume: [0; 16],
total_internally_swapped: ([0; 16], [0; 16]),
_space: [0; 128],
preferred_fee_rates: (0, 0),
_space: Space124 { _padding: [0; 124] },
}
}
}
Expand All @@ -83,7 +90,8 @@ impl Display for Pair {
)?;
writeln!(f, "Mint A: {}", self.mints.0)?;
writeln!(f, "\tExternal Fee Destination: {}", self.fee_collector.0)?;
writeln!(f, "\tFee Rate {}", u16_to_bps(self.fee_rates.0))?;
writeln!(f, "\tNormal Fee Rate {}", u16_to_bps(self.normal_fee_rates.0))?;
writeln!(f, "\tPreferred Fee Rate {}", u16_to_bps(self.preferred_fee_rates.0))?;
writeln!(
f,
"\tFees Generated (Native): {}",
Expand All @@ -97,7 +105,8 @@ impl Display for Pair {
writeln!(f, "")?;
writeln!(f, "Mint B: {}", self.mints.1)?;
writeln!(f, "\tExternal Fee Destination: {}", self.fee_collector.1)?;
writeln!(f, "\tFee Rate {}", u16_to_bps(self.fee_rates.1))?;
writeln!(f, "\tNormal Fee Rate {}", u16_to_bps(self.normal_fee_rates.1))?;
writeln!(f, "\tPreferred Fee Rate {}", u16_to_bps(self.preferred_fee_rates.1))?;
writeln!(
f,
"\tFees Generated (Native): {}",
Expand Down Expand Up @@ -139,13 +148,16 @@ impl Pair {
mint_two: Pubkey,
mint_one_fee_destination: Pubkey,
mint_two_fee_destination: Pubkey,
mint_one_fee_rate: u16,
mint_two_fee_rate: u16,
mint_one_normal_fee_rate: u16,
mint_two_normal_fee_rate: u16,
mint_one_preferred_fee_rate: u16,
mint_two_preferred_fee_rate: u16,
) {
self.pool_registry = pool_registry;
self.mints = (mint_one, mint_two);
self.fee_collector = (mint_one_fee_destination, mint_two_fee_destination);
self.fee_rates = (mint_one_fee_rate, mint_two_fee_rate);
self.normal_fee_rates = (mint_one_normal_fee_rate, mint_two_normal_fee_rate);
self.preferred_fee_rates = (mint_one_preferred_fee_rate, mint_two_preferred_fee_rate);
}

/// Find the appropriate fee rate and collector, and verify the in/out mints match the pair.
Expand All @@ -154,18 +166,20 @@ impl Pair {
&self,
mint_in: Pubkey,
mint_out: Pubkey,
) -> std::result::Result<(Decimal, Pubkey, SwapIxMintOrdering), SSLV2Error> {
) -> std::result::Result<(Decimal, Decimal, Pubkey, SwapIxMintOrdering), SSLV2Error> {
if (mint_in, mint_out) == self.mints {
Ok((
Decimal::new(self.fee_rates.1 as i64, 4),
Decimal::new(self.normal_fee_rates.1 as i64, 4),
Decimal::new(self.preferred_fee_rates.1 as i64, 4),
self.fee_collector.1,
SwapIxMintOrdering::InOut,
))
} else if (mint_out, mint_in) == self.mints {
Ok((
Decimal::new(self.fee_rates.0 as i64, 4),
Decimal::new(self.normal_fee_rates.0 as i64, 4),
Decimal::new(self.preferred_fee_rates.0 as i64, 4),
self.fee_collector.0,
SwapIxMintOrdering::InOut,
SwapIxMintOrdering::OutIn,
))
} else {
Err(SSLV2Error::MintNotFound)
Expand Down Expand Up @@ -208,3 +222,57 @@ pub enum SwapIxMintOrdering {
/// When pair.mints = (mint_out, mint_in)
OutIn,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq,)]
#[repr(C)]
pub struct Space124 {
pub _padding: [u8; 124],
}

impl Default for Space124 {
fn default() -> Self {
Self { _padding: [0u8; 124] }
}
}

impl Serialize for Space124 {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_bytes(&self._padding)
}
}

impl<'de> Deserialize<'de> for Space124 {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let bytes: &[u8] = serde::Deserialize::deserialize(deserializer)?;
let mut array = [0u8; 124];
array[..bytes.len()].copy_from_slice(bytes);
Ok(Self { _padding: array })
}
}

unsafe impl Zeroable for Space124 {}
unsafe impl Pod for Space124 {}

impl BorshSerialize for Space124 {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::result::Result<(), std::io::Error> {
writer.write_all(&self._padding)?;
Ok(())
}
}

impl BorshDeserialize for Space124 {
fn deserialize(buf: &mut &[u8]) -> std::result::Result<Self, std::io::Error> {
let mut array = [0u8; 124];
// copy from buf to array
let (src, dst) = buf.split_at(std::cmp::min(buf.len(), array.len()));
array[..src.len()].copy_from_slice(src);
*buf = dst;
Ok(Self { _padding: array })
}
}
Loading

0 comments on commit f6d8c44

Please sign in to comment.