diff --git a/Cargo.lock b/Cargo.lock index 8c62d7b9..67cd7ff8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1110,6 +1110,8 @@ dependencies = [ "inf1-core", "inf1-pp-ag-std", "inf1-svc-ag-std", + "inf1-test-utils", + "solana-pubkey 3.0.0", ] [[package]] diff --git a/core/src/quote/liquidity/add.rs b/core/src/quote/liquidity/add.rs index fba42a12..32d34501 100644 --- a/core/src/quote/liquidity/add.rs +++ b/core/src/quote/liquidity/add.rs @@ -53,6 +53,7 @@ pub type AddLiqQuoteResult = Result>; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum AddLiqQuoteErr { InpCalc(I), + InpDisabled, Overflow, Pricing(P), ZeroValue, @@ -62,9 +63,10 @@ impl Display for AddLiqQuoteErr { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { + Self::InpCalc(e) => e.fmt(f), + Self::InpDisabled => f.write_str("LST input disabled"), Self::Overflow => f.write_str("arithmetic overflow"), Self::Pricing(e) => e.fmt(f), - Self::InpCalc(e) => e.fmt(f), Self::ZeroValue => f.write_str("zero value"), } } diff --git a/core/src/quote/swap/err.rs b/core/src/quote/swap/err.rs index d1566998..b56e0a20 100644 --- a/core/src/quote/swap/err.rs +++ b/core/src/quote/swap/err.rs @@ -5,9 +5,10 @@ use crate::err::NotEnoughLiquidityErr; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum SwapQuoteErr { InpCalc(I), + InpDisabled, + NotEnoughLiquidity(NotEnoughLiquidityErr), OutCalc(O), Overflow, - NotEnoughLiquidity(NotEnoughLiquidityErr), Pricing(P), ZeroValue, } @@ -16,11 +17,12 @@ impl Display for SwapQuoteErr { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { + Self::InpDisabled => f.write_str("LST input disabled"), + Self::InpCalc(e) => e.fmt(f), + Self::NotEnoughLiquidity(e) => e.fmt(f), Self::OutCalc(e) => e.fmt(f), Self::Overflow => f.write_str("arithmetic overflow"), - Self::NotEnoughLiquidity(e) => e.fmt(f), Self::Pricing(e) => e.fmt(f), - Self::InpCalc(e) => e.fmt(f), Self::ZeroValue => f.write_str("zero value"), } } diff --git a/jiminy/src/lib.rs b/jiminy/src/lib.rs index 004f0e11..9ce0f143 100644 --- a/jiminy/src/lib.rs +++ b/jiminy/src/lib.rs @@ -21,11 +21,12 @@ impl< sol_log(&msg); match e { SwapQuoteErr::InpCalc(e) => e.into(), - SwapQuoteErr::OutCalc(e) => e.into(), - SwapQuoteErr::Overflow => Inf1CtlCustomProgErr(Inf1CtlErr::MathError).into(), + SwapQuoteErr::InpDisabled => Inf1CtlCustomProgErr(Inf1CtlErr::LstInputDisabled).into(), SwapQuoteErr::NotEnoughLiquidity(_) => { Inf1CtlCustomProgErr(Inf1CtlErr::NotEnoughLiquidity).into() } + SwapQuoteErr::OutCalc(e) => e.into(), + SwapQuoteErr::Overflow => Inf1CtlCustomProgErr(Inf1CtlErr::MathError).into(), SwapQuoteErr::Pricing(e) => e.into(), SwapQuoteErr::ZeroValue => Inf1CtlCustomProgErr(Inf1CtlErr::ZeroValue).into(), } @@ -42,10 +43,13 @@ impl, P: Display + Into> let msg = e.to_string(); sol_log(&msg); match e { - AddLiqQuoteErr::Overflow => Inf1CtlCustomProgErr(Inf1CtlErr::MathError).into(), - AddLiqQuoteErr::ZeroValue => Inf1CtlCustomProgErr(Inf1CtlErr::ZeroValue).into(), AddLiqQuoteErr::InpCalc(e) => e.into(), + AddLiqQuoteErr::InpDisabled => { + Inf1CtlCustomProgErr(Inf1CtlErr::LstInputDisabled).into() + } + AddLiqQuoteErr::Overflow => Inf1CtlCustomProgErr(Inf1CtlErr::MathError).into(), AddLiqQuoteErr::Pricing(e) => e.into(), + AddLiqQuoteErr::ZeroValue => Inf1CtlCustomProgErr(Inf1CtlErr::ZeroValue).into(), } } } diff --git a/sol-val-calc/ag/std/src/lib.rs b/sol-val-calc/ag/std/src/lib.rs index 7ddd3d8b..3fe21cf3 100644 --- a/sol-val-calc/ag/std/src/lib.rs +++ b/sol-val-calc/ag/std/src/lib.rs @@ -7,6 +7,10 @@ use inf1_svc_wsol_std::WsolSvcStd; // Re-exports pub use inf1_svc_ag_core::*; +pub use inf1_svc_lido_std; +pub use inf1_svc_marinade_std; +pub use inf1_svc_spl_std; +pub use inf1_svc_wsol_std; pub mod update; diff --git a/sol-val-calc/lido/core/src/calc.rs b/sol-val-calc/lido/core/src/calc.rs index 871fb4b3..2229b848 100644 --- a/sol-val-calc/lido/core/src/calc.rs +++ b/sol-val-calc/lido/core/src/calc.rs @@ -4,7 +4,7 @@ use inf1_svc_core::traits::SolValCalc; use sanctum_token_ratio_compat::floor_ratio_u64_u64_reverse; use solido_legacy_core::{ExchangeRate, Lido}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] pub struct LidoCalc { pub exchange_rate: ExchangeRate, pub current_epoch: u64, diff --git a/sol-val-calc/lido/std/src/lib.rs b/sol-val-calc/lido/std/src/lib.rs index 8e073f95..8e780d28 100644 --- a/sol-val-calc/lido/std/src/lib.rs +++ b/sol-val-calc/lido/std/src/lib.rs @@ -9,7 +9,7 @@ pub mod update; pub struct LidoSvcStd { /// Might be `None` at initialization before accounts required /// to create the calc have been fetched - calc: Option, + pub calc: Option, } impl Default for LidoSvcStd { diff --git a/sol-val-calc/marinade/std/src/lib.rs b/sol-val-calc/marinade/std/src/lib.rs index ea072df7..9a6e7506 100644 --- a/sol-val-calc/marinade/std/src/lib.rs +++ b/sol-val-calc/marinade/std/src/lib.rs @@ -9,7 +9,7 @@ pub mod update; pub struct MarinadeSvcStd { /// Might be `None` at initialization before accounts required /// to create the calc have been fetched - calc: Option, + pub calc: Option, } impl Default for MarinadeSvcStd { diff --git a/sol-val-calc/spl/std/src/lib.rs b/sol-val-calc/spl/std/src/lib.rs index d1490a8c..2bfabf3b 100644 --- a/sol-val-calc/spl/std/src/lib.rs +++ b/sol-val-calc/spl/std/src/lib.rs @@ -16,8 +16,8 @@ pub type SplSvcStd = GenSplSvcStd; pub struct GenSplSvcStd { /// Might be `None` at initialization before accounts required /// to create the calc have been fetched - calc: Option, - accs: A, + pub calc: Option, + pub accs: A, } /// Constructors diff --git a/std/Cargo.toml b/std/Cargo.toml index c9a67e9d..81b61ed1 100644 --- a/std/Cargo.toml +++ b/std/Cargo.toml @@ -8,3 +8,7 @@ version.workspace = true inf1-core = { workspace = true } inf1-pp-ag-std = { workspace = true } inf1-svc-ag-std = { workspace = true } + +[dev-dependencies] +inf1-test-utils = { workspace = true } +solana-pubkey = { workspace = true } diff --git a/std/src/trade/quote.rs b/std/src/trade/quote.rs index 784fee21..f2faa5c5 100644 --- a/std/src/trade/quote.rs +++ b/std/src/trade/quote.rs @@ -1,7 +1,7 @@ #![allow(deprecated)] use inf1_core::{ - inf1_ctl_core::typedefs::lst_state::LstState, + inf1_ctl_core::typedefs::{lst_state::LstState, u8bool::U8Bool}, inf1_pp_core::{ pair::Pair, traits::{ @@ -14,7 +14,10 @@ use inf1_core::{ add::{quote_add_liq, AddLiqQuote, AddLiqQuoteArgs, AddLiqQuoteErr}, remove::{quote_remove_liq, RemoveLiqQuote, RemoveLiqQuoteArgs, RemoveLiqQuoteErr}, }, - swap::{exact_in::quote_exact_in, exact_out::quote_exact_out, SwapQuote, SwapQuoteArgs}, + swap::{ + err::SwapQuoteErr, exact_in::quote_exact_in, exact_out::quote_exact_out, SwapQuote, + SwapQuoteArgs, + }, }, }; use inf1_svc_ag_std::calc::{SvcCalcAg, SvcCalcAgErr}; @@ -110,10 +113,18 @@ impl Option<[u8; 32]>> Inf { } #[inline] - pub fn quote_add_liq(&self, inp_mint: &[u8; 32], amt: u64) -> Result { - let (inp_lst_state, inp_calc) = self.lst_state_and_calc(inp_mint)?; + fn quote_add_liq_inner( + &self, + inp_mint: &[u8; 32], + amt: u64, + inp_lst_state: &LstState, + inp_calc: &SvcCalcAg, + ) -> Result { + if U8Bool(&inp_lst_state.is_input_disabled).to_bool() { + return Err(InfErr::AddLiqQuote(AddLiqQuoteErr::InpDisabled)); + } let (lp_token_supply, pool_total_sol_value, _reserves) = - self.quote_liq_common(inp_mint, &inp_lst_state, &inp_calc, |e| { + self.quote_liq_common(inp_mint, inp_lst_state, inp_calc, |e| { InfErr::AddLiqQuote(AddLiqQuoteErr::InpCalc(e)) })?; let pricing = self @@ -133,6 +144,12 @@ impl Option<[u8; 32]>> Inf { .map_err(InfErr::AddLiqQuote) } + #[inline] + pub fn quote_add_liq(&self, inp_mint: &[u8; 32], amt: u64) -> Result { + let (inp_lst_state, inp_calc) = self.lst_state_and_calc(inp_mint)?; + self.quote_add_liq_inner(inp_mint, amt, &inp_lst_state, &inp_calc) + } + #[inline] pub fn quote_add_liq_mut( &mut self, @@ -140,36 +157,19 @@ impl Option<[u8; 32]>> Inf { amt: u64, ) -> Result { let (inp_lst_state, inp_calc) = self.lst_state_and_calc_mut(inp_mint)?; - let (lp_token_supply, pool_total_sol_value, _reserves) = - self.quote_liq_common(inp_mint, &inp_lst_state, &inp_calc, |e| { - InfErr::AddLiqQuote(AddLiqQuoteErr::InpCalc(e)) - })?; - let pricing = self - .pricing - .price_lp_tokens_to_mint_for(inp_mint) - .map_err(InfErr::PricingProg)?; - quote_add_liq(AddLiqQuoteArgs { - amt, - lp_token_supply, - pool_total_sol_value, - lp_protocol_fee_bps: self.pool.lp_protocol_fee_bps, - inp_mint: *inp_mint, - lp_mint: self.pool.lp_token_mint, - inp_calc, - pricing, - }) - .map_err(InfErr::AddLiqQuote) + self.quote_add_liq_inner(inp_mint, amt, &inp_lst_state, &inp_calc) } #[inline] - pub fn quote_remove_liq( + fn quote_remove_liq_inner( &self, out_mint: &[u8; 32], amt: u64, + out_lst_state: &LstState, + out_calc: &SvcCalcAg, ) -> Result { - let (out_lst_state, out_calc) = self.lst_state_and_calc(out_mint)?; let (lp_token_supply, pool_total_sol_value, out_reserves) = - self.quote_liq_common(out_mint, &out_lst_state, &out_calc, |e| { + self.quote_liq_common(out_mint, out_lst_state, out_calc, |e| { InfErr::RemoveLiqQuote(RemoveLiqQuoteErr::OutCalc(e)) })?; let pricing = self @@ -190,6 +190,16 @@ impl Option<[u8; 32]>> Inf { .map_err(InfErr::RemoveLiqQuote) } + #[inline] + pub fn quote_remove_liq( + &self, + out_mint: &[u8; 32], + amt: u64, + ) -> Result { + let (out_lst_state, out_calc) = self.lst_state_and_calc(out_mint)?; + self.quote_remove_liq_inner(out_mint, amt, &out_lst_state, &out_calc) + } + #[inline] pub fn quote_remove_liq_mut( &mut self, @@ -197,35 +207,23 @@ impl Option<[u8; 32]>> Inf { amt: u64, ) -> Result { let (out_lst_state, out_calc) = self.lst_state_and_calc_mut(out_mint)?; - let (lp_token_supply, pool_total_sol_value, out_reserves) = - self.quote_liq_common(out_mint, &out_lst_state, &out_calc, |e| { - InfErr::RemoveLiqQuote(RemoveLiqQuoteErr::OutCalc(e)) - })?; - let pricing = self - .pricing - .price_lp_tokens_to_redeem_for(out_mint) - .map_err(InfErr::PricingProg)?; - quote_remove_liq(RemoveLiqQuoteArgs { - amt, - lp_token_supply, - pool_total_sol_value, - lp_protocol_fee_bps: self.pool.lp_protocol_fee_bps, - out_mint: *out_mint, - lp_mint: self.pool.lp_token_mint, - out_calc, - pricing, - out_reserves, - }) - .map_err(InfErr::RemoveLiqQuote) + self.quote_remove_liq_inner(out_mint, amt, &out_lst_state, &out_calc) } #[inline] - pub fn quote_exact_in(&self, pair: &Pair<&[u8; 32]>, amt: u64) -> Result { - let Pair { - inp: (_, inp_calc), + fn quote_exact_in_inner( + &self, + pair: &Pair<&[u8; 32]>, + amt: u64, + Pair { + inp: (inp_lst_state, inp_calc), out: (out_lst_state, out_calc), - } = pair.try_map(|mint| self.lst_state_and_calc(mint))?; - let out_reserves = self.reserves_balance_checked(pair.out, &out_lst_state)?; + }: &Pair<(LstState, SvcCalcAg)>, + ) -> Result { + if U8Bool(&inp_lst_state.is_input_disabled).to_bool() { + return Err(InfErr::SwapQuote(SwapQuoteErr::InpDisabled)); + } + let out_reserves = self.reserves_balance_checked(pair.out, out_lst_state)?; let pricing = self .pricing .price_exact_in_for(pair) @@ -243,41 +241,36 @@ impl Option<[u8; 32]>> Inf { .map_err(InfErr::SwapQuote) } + #[inline] + pub fn quote_exact_in(&self, pair: &Pair<&[u8; 32]>, amt: u64) -> Result { + let lsc = pair.try_map(|mint| self.lst_state_and_calc(mint))?; + self.quote_exact_in_inner(pair, amt, &lsc) + } + #[inline] pub fn quote_exact_in_mut( &mut self, pair: &Pair<&[u8; 32]>, amt: u64, ) -> Result { - let Pair { - inp: (_, inp_calc), - out: (out_lst_state, out_calc), - } = pair.try_map(|mint| self.lst_state_and_calc_mut(mint))?; - let out_reserves = self.reserves_balance_checked(pair.out, &out_lst_state)?; - let pricing = self - .pricing - .price_exact_in_for(pair) - .map_err(InfErr::PricingProg)?; - quote_exact_in(SwapQuoteArgs { - amt, - inp_mint: *pair.inp, - out_mint: *pair.out, - inp_calc, - out_calc, - pricing, - out_reserves, - trading_protocol_fee_bps: self.pool.trading_protocol_fee_bps, - }) - .map_err(InfErr::SwapQuote) + let lsc = pair.try_map(|mint| self.lst_state_and_calc_mut(mint))?; + self.quote_exact_in_inner(pair, amt, &lsc) } #[inline] - pub fn quote_exact_out(&self, pair: &Pair<&[u8; 32]>, amt: u64) -> Result { - let Pair { - inp: (_, inp_calc), + fn quote_exact_out_inner( + &self, + pair: &Pair<&[u8; 32]>, + amt: u64, + Pair { + inp: (inp_lst_state, inp_calc), out: (out_lst_state, out_calc), - } = pair.try_map(|mint| self.lst_state_and_calc(mint))?; - let out_reserves = self.reserves_balance_checked(pair.out, &out_lst_state)?; + }: &Pair<(LstState, SvcCalcAg)>, + ) -> Result { + if U8Bool(&inp_lst_state.is_input_disabled).to_bool() { + return Err(InfErr::SwapQuote(SwapQuoteErr::InpDisabled)); + } + let out_reserves = self.reserves_balance_checked(pair.out, out_lst_state)?; let pricing = self .pricing .price_exact_out_for(pair) @@ -295,31 +288,19 @@ impl Option<[u8; 32]>> Inf { .map_err(InfErr::SwapQuote) } + #[inline] + pub fn quote_exact_out(&self, pair: &Pair<&[u8; 32]>, amt: u64) -> Result { + let lsc = pair.try_map(|mint| self.lst_state_and_calc(mint))?; + self.quote_exact_out_inner(pair, amt, &lsc) + } + #[inline] pub fn quote_exact_out_mut( &mut self, pair: &Pair<&[u8; 32]>, amt: u64, ) -> Result { - let Pair { - inp: (_, inp_calc), - out: (out_lst_state, out_calc), - } = pair.try_map(|mint| self.lst_state_and_calc_mut(mint))?; - let out_reserves = self.reserves_balance_checked(pair.out, &out_lst_state)?; - let pricing = self - .pricing - .price_exact_out_for(pair) - .map_err(InfErr::PricingProg)?; - quote_exact_out(SwapQuoteArgs { - amt, - inp_mint: *pair.inp, - out_mint: *pair.out, - inp_calc, - out_calc, - pricing, - out_reserves, - trading_protocol_fee_bps: self.pool.trading_protocol_fee_bps, - }) - .map_err(InfErr::SwapQuote) + let lsc = pair.try_map(|mint| self.lst_state_and_calc_mut(mint))?; + self.quote_exact_out_inner(pair, amt, &lsc) } } diff --git a/std/tests/common/fixtures.rs b/std/tests/common/fixtures.rs new file mode 100644 index 00000000..1009c867 --- /dev/null +++ b/std/tests/common/fixtures.rs @@ -0,0 +1,24 @@ +use inf1_std::inf1_ctl_core::{ + accounts::{ + lst_state_list::LstStatePackedList, + pool_state::{PoolState, PoolStatePacked}, + }, + keys::{LST_STATE_LIST_ID, POOL_STATE_ID}, + typedefs::lst_state::LstState, +}; +use inf1_test_utils::ALL_FIXTURES; + +pub fn pool_state_fixture() -> PoolState { + PoolStatePacked::of_acc_data(&ALL_FIXTURES[&POOL_STATE_ID.into()].data) + .unwrap() + .into_pool_state() +} + +pub fn lst_state_list_fixture() -> Vec { + LstStatePackedList::of_acc_data(&ALL_FIXTURES[&LST_STATE_LIST_ID.into()].data) + .unwrap() + .0 + .iter() + .map(|l| l.into_lst_state()) + .collect() +} diff --git a/std/tests/common/mod.rs b/std/tests/common/mod.rs new file mode 100644 index 00000000..150421bb --- /dev/null +++ b/std/tests/common/mod.rs @@ -0,0 +1,5 @@ +mod fixtures; +mod pda; + +pub use fixtures::*; +pub use pda::*; diff --git a/std/tests/common/pda.rs b/std/tests/common/pda.rs new file mode 100644 index 00000000..bdde3889 --- /dev/null +++ b/std/tests/common/pda.rs @@ -0,0 +1,12 @@ +use solana_pubkey::Pubkey; + +pub fn find_pda(seeds: &[&[u8]], prog_id: &[u8; 32]) -> Option<([u8; 32], u8)> { + Pubkey::try_find_program_address(seeds, &Pubkey::new_from_array(*prog_id)) + .map(|(a, b)| (a.to_bytes(), b)) +} + +pub fn create_pda(seeds: &[&[u8]], prog_id: &[u8; 32]) -> Option<[u8; 32]> { + Pubkey::create_program_address(seeds, &Pubkey::new_from_array(*prog_id)) + .ok() + .map(|a| a.to_bytes()) +} diff --git a/std/tests/mod.rs b/std/tests/mod.rs new file mode 100644 index 00000000..908799a7 --- /dev/null +++ b/std/tests/mod.rs @@ -0,0 +1,2 @@ +mod common; +mod tests; diff --git a/std/tests/tests/mod.rs b/std/tests/tests/mod.rs new file mode 100644 index 00000000..9d118d2e --- /dev/null +++ b/std/tests/tests/mod.rs @@ -0,0 +1 @@ +mod quote; diff --git a/std/tests/tests/quote/errs.rs b/std/tests/tests/quote/errs.rs new file mode 100644 index 00000000..a6ce79fc --- /dev/null +++ b/std/tests/tests/quote/errs.rs @@ -0,0 +1,115 @@ +#![allow(deprecated)] + +use std::collections::HashMap; + +use inf1_pp_ag_std::update::all::Pair; +use inf1_std::{ + err::InfErr, + inf1_ctl_core::{accounts::pool_state::PoolState, typedefs::lst_state::LstState}, + quote::{liquidity::add::AddLiqQuoteErr, swap::err::SwapQuoteErr}, + InfStd, +}; +use inf1_svc_ag_std::{ + inf1_svc_lido_std::{solido_legacy_core::STSOL_MINT_ADDR, LidoSvcStd}, + inf1_svc_wsol_std::WsolSvcStd, + SvcAg, SvcAgStd, +}; +use inf1_test_utils::{bool_to_u8, WSOL_MINT}; + +use crate::common::{create_pda, find_pda, lst_state_list_fixture, pool_state_fixture}; + +const DISABLED_MINT: [u8; 32] = STSOL_MINT_ADDR; +const DUMMY_AMT: u64 = 1_000_000_000; +const DISABLED_INP_PAIR: Pair<&[u8; 32]> = Pair { + inp: &DISABLED_MINT, + out: WSOL_MINT.as_array(), +}; + +fn disable_lst_input(list: &mut [LstState], disable: &[u8; 32]) { + list.iter_mut() + .find(|s| s.mint == *disable) + .unwrap() + .is_input_disabled = bool_to_u8(true) +} + +fn svcs_for_test() -> HashMap<[u8; 32], SvcAgStd> { + [ + ( + DISABLED_MINT, + SvcAgStd(SvcAg::Lido(LidoSvcStd { + calc: Some(Default::default()), + })), + ), + (WSOL_MINT.to_bytes(), SvcAgStd(SvcAg::Wsol(WsolSvcStd))), + ] + .into_iter() + .collect() +} + +fn inf_for_test(pool: PoolState, list: &[LstState]) -> InfStd { + InfStd::new( + pool, + list.iter().flat_map(|s| *s.as_acc_data_arr()).collect(), + Some(1_000_000_000), + None, + Default::default(), + svcs_for_test(), + Default::default(), + find_pda, + create_pda, + ) + .unwrap() +} + +fn inp_disabled_setup() -> InfStd { + let pool = pool_state_fixture(); + let mut list = lst_state_list_fixture(); + disable_lst_input(&mut list, &DISABLED_MINT); + inf_for_test(pool, &list) +} + +#[test] +fn quote_add_liq_inp_disabled_fixture() { + const EXPECTED_ERR: InfErr = InfErr::AddLiqQuote(AddLiqQuoteErr::InpDisabled); + + let mut inf = inp_disabled_setup(); + + let e = inf.quote_add_liq(&DISABLED_MINT, DUMMY_AMT).unwrap_err(); + let em = inf + .quote_add_liq_mut(&DISABLED_MINT, DUMMY_AMT) + .unwrap_err(); + assert_eq!(e, EXPECTED_ERR); + assert_eq!(em, EXPECTED_ERR); +} + +#[test] +fn quote_exact_in_inp_disabled_fixture() { + const EXPECTED_ERR: InfErr = InfErr::SwapQuote(SwapQuoteErr::InpDisabled); + + let mut inf = inp_disabled_setup(); + + let e = inf + .quote_exact_in(&DISABLED_INP_PAIR, DUMMY_AMT) + .unwrap_err(); + let em = inf + .quote_exact_in_mut(&DISABLED_INP_PAIR, DUMMY_AMT) + .unwrap_err(); + assert_eq!(e, EXPECTED_ERR); + assert_eq!(em, EXPECTED_ERR); +} + +#[test] +fn quote_exact_out_inp_disabled_fixture() { + const EXPECTED_ERR: InfErr = InfErr::SwapQuote(SwapQuoteErr::InpDisabled); + + let mut inf = inp_disabled_setup(); + + let e = inf + .quote_exact_out(&DISABLED_INP_PAIR, DUMMY_AMT) + .unwrap_err(); + let em = inf + .quote_exact_out_mut(&DISABLED_INP_PAIR, DUMMY_AMT) + .unwrap_err(); + assert_eq!(e, EXPECTED_ERR); + assert_eq!(em, EXPECTED_ERR); +} diff --git a/std/tests/tests/quote/mod.rs b/std/tests/tests/quote/mod.rs new file mode 100644 index 00000000..2e474063 --- /dev/null +++ b/std/tests/tests/quote/mod.rs @@ -0,0 +1 @@ +mod errs; diff --git a/ts/sdk/src/err.rs b/ts/sdk/src/err.rs index 0398f6d8..8badc6cd 100644 --- a/ts/sdk/src/err.rs +++ b/ts/sdk/src/err.rs @@ -241,6 +241,13 @@ fn zero_value_err() -> InfError { } } +fn lst_input_disabled_err() -> InfError { + InfError { + code: InfErr::PoolErr, + cause: Some("LST input disabled".to_owned()), + } +} + macro_rules! impl_from_acc_deser_err { ($Enum:ty) => { impl From<$Enum> for InfError { @@ -399,6 +406,7 @@ impl, E2: Into> From> for In fn from(e: AddLiqQuoteErr) -> Self { match e { AddLiqQuoteErr::InpCalc(e) => e.into(), + AddLiqQuoteErr::InpDisabled => lst_input_disabled_err(), AddLiqQuoteErr::Overflow => overflow_err(), AddLiqQuoteErr::ZeroValue => zero_value_err(), AddLiqQuoteErr::Pricing(e) => e.into(), @@ -436,6 +444,7 @@ impl, E2: Into, E3: Into> From) -> Self { match e { SwapQuoteErr::InpCalc(e) => e.into(), + SwapQuoteErr::InpDisabled => lst_input_disabled_err(), SwapQuoteErr::OutCalc(e) => e.into(), SwapQuoteErr::Overflow => overflow_err(), SwapQuoteErr::NotEnoughLiquidity(e) => e.into(),