Skip to content

Commit a4b5459

Browse files
committed
Integrate SwapStep into Swap implementation
1 parent f7726fc commit a4b5459

File tree

4 files changed

+97
-73
lines changed

4 files changed

+97
-73
lines changed

pallets/swap-interface/src/lib.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![cfg_attr(not(feature = "std"), no_std)]
2+
use core::ops::Neg;
23

34
use frame_support::pallet_prelude::*;
45
use substrate_fixed::types::U96F32;
@@ -8,17 +9,10 @@ pub use order::*;
89

910
mod order;
1011

11-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12-
pub enum OrderType {
13-
Sell,
14-
Buy,
15-
}
16-
1712
pub trait SwapHandler<AccountId> {
18-
fn swap<PaidIn, PaidOut, ReserveIn, ReserveOut>(
13+
fn swap<PaidIn, PaidOut, ReserveIn, ReserveOut, OrderT>(
1914
netuid: NetUid,
20-
order_t: OrderType,
21-
amount: PaidIn,
15+
order: OrderT,
2216
price_limit: TaoCurrency,
2317
drop_fees: bool,
2418
should_rollback: bool,
@@ -27,17 +21,20 @@ pub trait SwapHandler<AccountId> {
2721
PaidIn: Currency,
2822
PaidOut: Currency,
2923
ReserveIn: CurrencyReserve<PaidIn>,
30-
ReserveOut: CurrencyReserve<PaidOut>;
31-
fn sim_swap<PaidIn, PaidOut, ReserveIn, ReserveOut>(
24+
ReserveOut: CurrencyReserve<PaidOut>,
25+
OrderT: Order<PaidIn, PaidOut>;
26+
fn sim_swap<PaidIn, PaidOut, ReserveIn, ReserveOut, OrderT>(
3227
netuid: NetUid,
33-
order_t: OrderType,
28+
order: OrderT,
3429
amount: PaidIn,
3530
) -> Result<SwapResult<PaidIn, PaidOut>, DispatchError>
3631
where
3732
PaidIn: Currency,
3833
PaidOut: Currency,
3934
ReserveIn: CurrencyReserve<PaidIn>,
40-
ReserveOut: CurrencyReserve<PaidOut>;
35+
ReserveOut: CurrencyReserve<PaidOut>,
36+
OrderT: Order<PaidIn, PaidOut>,
37+
Self: DefaultPriceLimit<PaidIn, PaidOut>;
4138
fn approx_fee_amount<T: Currency>(netuid: NetUid, amount: T) -> T;
4239
fn current_alpha_price(netuid: NetUid) -> U96F32;
4340
fn max_price<C: Currency>() -> C;
@@ -50,6 +47,14 @@ pub trait SwapHandler<AccountId> {
5047
fn is_user_liquidity_enabled(netuid: NetUid) -> bool;
5148
}
5249

50+
pub trait DefaultPriceLimit<PaidIn, PaidOut>
51+
where
52+
PaidIn: Currency,
53+
PaidOut: Currency,
54+
{
55+
fn default_price_limit<C: Currency>() -> C;
56+
}
57+
5358
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)]
5459
pub struct SwapResult<PaidIn, PaidOut>
5560
where
@@ -59,7 +64,18 @@ where
5964
pub amount_paid_in: PaidIn,
6065
pub amount_paid_out: PaidOut,
6166
pub fee_paid: PaidIn,
62-
// For calculation of new tao/alpha reserves
63-
pub tao_reserve_delta: i128,
64-
pub alpha_reserve_delta: i128,
67+
}
68+
69+
impl<PaidIn, PaidOut> SwapResult<PaidIn, PaidOut>
70+
where
71+
PaidIn: Currency,
72+
PaidOut: Currency,
73+
{
74+
pub fn paid_in_reserve_delta(&self) -> i128 {
75+
self.amount_paid_in.to_u64() as i128
76+
}
77+
78+
pub fn paid_out_reserve_delta(&self) -> i128 {
79+
(self.amount_paid_out.to_u64() as i128).neg()
80+
}
6581
}

pallets/swap/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![cfg_attr(not(feature = "std"), no_std)]
22

33
use substrate_fixed::types::U64F64;
4-
use subtensor_swap_interface::OrderType;
54

65
pub mod pallet;
76
pub mod position;

pallets/swap/src/pallet/impls.rs

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ use substrate_fixed::types::{I64F64, U64F64, U96F32};
99
use subtensor_runtime_common::{
1010
AlphaCurrency, BalanceOps, Currency, CurrencyReserve, NetUid, SubnetInfo, TaoCurrency,
1111
};
12-
use subtensor_swap_interface::{Order as OrderT, SwapHandler, SwapResult};
12+
use subtensor_swap_interface::{DefaultPriceLimit, Order as OrderT, SwapHandler, SwapResult};
1313

1414
use super::pallet::*;
15-
use super::swap_step::{SwapStep, SwapStepAction};
15+
use super::swap_step::{BasicSwapStep, SwapStep, SwapStepAction};
1616
use crate::{
17-
OrderType, SqrtPrice,
17+
SqrtPrice,
1818
position::{Position, PositionId},
1919
tick::{ActiveTickIndexManager, Tick, TickIndex},
2020
};
@@ -72,7 +72,8 @@ impl<T: Config> Pallet<T> {
7272
}
7373

7474
// Initialize the v3:
75-
// Reserves are re-purposed, nothing to set, just query values for liquidity and price calculation
75+
// Reserves are re-purposed, nothing to set, just query values for liquidity and price
76+
// calculation
7677
let tao_reserve = T::TaoReserve::reserve(netuid.into());
7778
let alpha_reserve = T::AlphaReserve::reserve(netuid.into());
7879

@@ -168,7 +169,8 @@ impl<T: Config> Pallet<T> {
168169
/// - `order_type`: The type of the swap (e.g., Buy or Sell).
169170
/// - `amount`: The amount of tokens to swap.
170171
/// - `limit_sqrt_price`: A price limit (expressed as a square root) to bound the swap.
171-
/// - `simulate`: If `true`, the function runs in simulation mode and does not persist any changes.
172+
/// - `simulate`: If `true`, the function runs in simulation mode and does not persist any
173+
/// changes.
172174
///
173175
/// # Returns
174176
/// Returns a [`Result`] with a [`SwapResult`] on success, or a [`DispatchError`] on failure.
@@ -180,7 +182,8 @@ impl<T: Config> Pallet<T> {
180182
/// # Simulation Mode
181183
/// When `simulate` is set to `true`, the function:
182184
/// 1. Executes all logic without persisting any state changes (i.e., performs a dry run).
183-
/// 2. Skips reserve checks — it may return an `amount_paid_out` greater than the available reserve.
185+
/// 2. Skips reserve checks — it may return an `amount_paid_out` greater than the available
186+
/// reserve.
184187
///
185188
/// Use simulation mode to preview the outcome of a swap without modifying the blockchain state.
186189
pub fn do_swap<PaidIn, PaidOut, ReserveIn, ReserveOut, Order>(
@@ -196,6 +199,7 @@ impl<T: Config> Pallet<T> {
196199
ReserveIn: CurrencyReserve<PaidIn>,
197200
ReserveOut: CurrencyReserve<PaidOut>,
198201
Order: OrderT<PaidIn, PaidOut>,
202+
BasicSwapStep<T, PaidIn, PaidOut, Order>: SwapStep<T, PaidIn, PaidOut, Order>,
199203
{
200204
transactional::with_transaction(|| {
201205
let reserve = ReserveOut::reserve(netuid.into());
@@ -240,6 +244,7 @@ impl<T: Config> Pallet<T> {
240244
ReserveIn: CurrencyReserve<PaidIn>,
241245
ReserveOut: CurrencyReserve<PaidOut>,
242246
Order: OrderT<PaidIn, PaidOut>,
247+
BasicSwapStep<T, PaidIn, PaidOut, Order>: SwapStep<T, PaidIn, PaidOut, Order>,
243248
{
244249
ensure!(
245250
ReserveOut::reserve(netuid).to_u64() >= T::MinimumReserve::get().get(),
@@ -255,10 +260,10 @@ impl<T: Config> Pallet<T> {
255260
);
256261

257262
let mut amount_remaining = order.amount();
258-
let mut amount_paid_out: u64 = 0;
263+
let mut amount_paid_out = PaidOut::ZERO;
259264
let mut iteration_counter: u16 = 0;
260-
let mut in_acc: u64 = 0;
261-
let mut fee_acc: u64 = 0;
265+
let mut in_acc = PaidIn::ZERO;
266+
let mut fee_acc = PaidIn::ZERO;
262267

263268
log::trace!("======== Start Swap ========");
264269
log::trace!("Amount Remaining: {amount_remaining}");
@@ -272,22 +277,27 @@ impl<T: Config> Pallet<T> {
272277
);
273278

274279
// Create and execute a swap step
275-
let mut swap_step =
276-
SwapStep::<T>::new(netuid, order, amount_remaining, limit_sqrt_price, drop_fees);
280+
let mut swap_step = BasicSwapStep::<T, PaidIn, PaidOut, Order>::new(
281+
netuid,
282+
order.clone(),
283+
amount_remaining,
284+
limit_sqrt_price,
285+
drop_fees,
286+
);
277287

278288
let swap_result = swap_step.execute()?;
279289

280290
in_acc = in_acc.saturating_add(swap_result.delta_in);
281291
fee_acc = fee_acc.saturating_add(swap_result.fee_paid);
282-
amount_remaining = amount_remaining.saturating_sub(swap_result.amount_to_take.into());
292+
amount_remaining = amount_remaining.saturating_sub(swap_result.amount_to_take);
283293
amount_paid_out = amount_paid_out.saturating_add(swap_result.delta_out);
284294

285-
if swap_step.action == SwapStepAction::Stop {
295+
if swap_step.action() == SwapStepAction::Stop {
286296
amount_remaining = PaidIn::ZERO;
287297
}
288298

289299
// The swap step didn't exchange anything
290-
if swap_result.amount_to_take == 0 {
300+
if swap_result.amount_to_take.is_zero() {
291301
amount_remaining = PaidIn::ZERO;
292302
}
293303

@@ -302,17 +312,10 @@ impl<T: Config> Pallet<T> {
302312
log::trace!("\nAmount Paid Out: {amount_paid_out}");
303313
log::trace!("======== End Swap ========");
304314

305-
let (tao_reserve_delta, alpha_reserve_delta) = match order_type {
306-
OrderType::Buy => (in_acc as i128, (amount_paid_out as i128).neg()),
307-
OrderType::Sell => ((amount_paid_out as i128).neg(), in_acc as i128),
308-
};
309-
310315
Ok(SwapResult {
311-
amount_paid_in: in_acc.into(),
312-
amount_paid_out: amount_paid_out.into(),
313-
fee_paid: fee_acc.into(),
314-
tao_reserve_delta,
315-
alpha_reserve_delta,
316+
amount_paid_in: in_acc,
317+
amount_paid_out,
318+
fee_paid: fee_acc,
316319
})
317320
}
318321

@@ -788,11 +791,22 @@ impl<T: Config> Pallet<T> {
788791
}
789792
}
790793

794+
impl<T: Config> DefaultPriceLimit<TaoCurrency, AlphaCurrency> for Pallet<T> {
795+
fn default_price_limit<C: Currency>() -> C {
796+
Self::max_price_inner::<C>()
797+
}
798+
}
799+
800+
impl<T: Config> DefaultPriceLimit<AlphaCurrency, TaoCurrency> for Pallet<T> {
801+
fn default_price_limit<C: Currency>() -> C {
802+
Self::min_price_inner::<C>()
803+
}
804+
}
805+
791806
impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
792-
fn swap<PaidIn, PaidOut, ReserveIn, ReserveOut>(
807+
fn swap<PaidIn, PaidOut, ReserveIn, ReserveOut, Order>(
793808
netuid: NetUid,
794-
order_t: OrderType,
795-
amount: PaidIn,
809+
order: Order,
796810
price_limit: TaoCurrency,
797811
drop_fees: bool,
798812
should_rollback: bool,
@@ -802,47 +816,45 @@ impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
802816
PaidOut: Currency,
803817
ReserveIn: CurrencyReserve<PaidIn>,
804818
ReserveOut: CurrencyReserve<PaidOut>,
819+
Order: OrderT<PaidIn, PaidOut>,
820+
BasicSwapStep<T, PaidIn, PaidOut, Order>: SwapStep<T, PaidIn, PaidOut, Order>,
805821
{
806822
let limit_sqrt_price = SqrtPrice::saturating_from_num(price_limit.to_u64())
807823
.safe_div(SqrtPrice::saturating_from_num(1_000_000_000))
808824
.checked_sqrt(SqrtPrice::saturating_from_num(0.0000000001))
809825
.ok_or(Error::<T>::PriceLimitExceeded)?;
810826

811-
Self::do_swap::<PaidIn, PaidOut, ReserveIn, ReserveOut>(
827+
Self::do_swap::<PaidIn, PaidOut, ReserveIn, ReserveOut, Order>(
812828
NetUid::from(netuid),
813-
order_t,
814-
amount,
829+
order,
815830
limit_sqrt_price,
816831
drop_fees,
817832
should_rollback,
818833
)
819834
.map_err(Into::into)
820835
}
821836

822-
fn sim_swap<PaidIn, PaidOut, ReserveIn, ReserveOut>(
837+
fn sim_swap<PaidIn, PaidOut, ReserveIn, ReserveOut, Order>(
823838
netuid: NetUid,
824-
order_t: OrderType,
839+
order: Order,
825840
amount: PaidIn,
826841
) -> Result<SwapResult<PaidIn, PaidOut>, DispatchError>
827842
where
828843
PaidIn: Currency,
829844
PaidOut: Currency,
830845
ReserveIn: CurrencyReserve<PaidIn>,
831846
ReserveOut: CurrencyReserve<PaidOut>,
847+
Order: OrderT<PaidIn, PaidOut>,
848+
Self: DefaultPriceLimit<PaidIn, PaidOut>,
832849
{
833850
match T::SubnetInfo::mechanism(netuid) {
834851
1 => {
835-
let price_limit = match order_t {
836-
OrderType::Buy => Self::max_price::<TaoCurrency>(),
837-
OrderType::Sell => Self::min_price::<TaoCurrency>(),
838-
}
839-
.to_u64();
852+
let price_limit = Self::default_price_limit::<TaoCurrency>();
840853

841-
Self::swap::<PaidIn, PaidOut, ReserveIn, ReserveOut>(
854+
Self::swap::<PaidIn, PaidOut, ReserveIn, ReserveOut, Order>(
842855
netuid,
843-
order_t,
844-
amount,
845-
price_limit.into(),
856+
order,
857+
price_limit,
846858
false,
847859
true,
848860
)
@@ -851,8 +863,6 @@ impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
851863
amount_paid_in: amount,
852864
amount_paid_out: amount.to_u64().into(),
853865
fee_paid: 0.into(),
854-
tao_reserve_delta: 0,
855-
alpha_reserve_delta: 0,
856866
}),
857867
}
858868
}
@@ -866,11 +876,11 @@ impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
866876
}
867877

868878
fn min_price<C: Currency>() -> C {
869-
Self::min_price()
879+
Self::min_price_inner()
870880
}
871881

872882
fn max_price<C: Currency>() -> C {
873-
Self::max_price()
883+
Self::max_price_inner()
874884
}
875885

876886
fn adjust_protocol_liquidity(

pallets/swap/src/pallet/swap_step.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ where
4141
final_price: SqrtPrice,
4242
fee: PaidIn,
4343

44-
// Phantom data to use T
45-
_phantom: PhantomData<T>,
46-
_paid_in: PhantomData<PaidIn>,
47-
_paid_out: PhantomData<PaidOut>,
44+
_phantom: PhantomData<(T, PaidIn, PaidOut)>,
4845
}
4946

5047
impl<T, PaidIn, PaidOut, Order> BasicSwapStep<T, PaidIn, PaidOut, Order>
@@ -56,7 +53,7 @@ where
5653
Self: SwapStep<T, PaidIn, PaidOut, Order>,
5754
{
5855
/// Creates and initializes a new swap step
59-
fn new(
56+
pub(crate) fn new(
6057
netuid: NetUid,
6158
order: Order,
6259
amount_remaining: PaidIn,
@@ -93,8 +90,6 @@ where
9390
final_price: target_sqrt_price,
9491
fee,
9592
_phantom: PhantomData,
96-
_paid_in: PhantomData,
97-
_paid_out: PhantomData,
9893
}
9994
}
10095

@@ -231,6 +226,10 @@ where
231226
delta_out,
232227
})
233228
}
229+
230+
pub(crate) fn action(&self) -> SwapStepAction {
231+
self.action
232+
}
234233
}
235234

236235
impl<T, Order> SwapStep<T, TaoCurrency, AlphaCurrency, Order>
@@ -563,10 +562,10 @@ where
563562
PaidIn: Currency,
564563
PaidOut: Currency,
565564
{
566-
amount_to_take: PaidIn,
567-
fee_paid: PaidIn,
568-
delta_in: PaidIn,
569-
delta_out: PaidOut,
565+
pub(crate) amount_to_take: PaidIn,
566+
pub(crate) fee_paid: PaidIn,
567+
pub(crate) delta_in: PaidIn,
568+
pub(crate) delta_out: PaidOut,
570569
}
571570

572571
#[derive(Clone, Copy, Debug, PartialEq)]

0 commit comments

Comments
 (0)