Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2432,11 +2432,59 @@ impl<T: Config + pallet_balances::Config<Balance = u64>>
SubnetAlphaIn::<T>::get(netuid)
}

fn subnet_exist(netuid: u16) -> bool {
Self::if_subnet_exist(netuid)
}
}

impl<T: Config + pallet_balances::Config<Balance = u64>>
subtensor_swap_interface::BalanceOps<T::AccountId> for Pallet<T>
{
fn tao_balance(account_id: &T::AccountId) -> u64 {
pallet_balances::Pallet::<T>::free_balance(account_id)
}

fn alpha_balance(netuid: u16, coldkey: &T::AccountId, hotkey: &T::AccountId) -> u64 {
Self::get_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid)
}

fn increase_balance(coldkey: &T::AccountId, tao: u64) {
Self::add_balance_to_coldkey_account(&coldkey, tao)
}

fn decrease_balance(coldkey: &T::AccountId, tao: u64) -> Result<u64, DispatchError> {
Self::remove_balance_from_coldkey_account(&coldkey, tao)
}

fn increase_stake(
coldkey: &T::AccountId,
hotkey: &T::AccountId,
netuid: u16,
alpha: u64,
) -> Result<(), DispatchError> {
ensure!(
Self::hotkey_account_exists(&hotkey),
Error::<T>::HotKeyAccountNotExists
);

Self::increase_stake_for_hotkey_and_coldkey_on_subnet(&hotkey, &coldkey, netuid, alpha);

Ok(())
}

fn decrease_stake(
coldkey: &T::AccountId,
hotkey: &T::AccountId,
netuid: u16,
alpha: u64,
) -> Result<u64, DispatchError> {
ensure!(
Self::hotkey_account_exists(&hotkey),
Error::<T>::HotKeyAccountNotExists
);

Ok(Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey, &coldkey, netuid, alpha,
))
}
}
229 changes: 1 addition & 228 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2023,232 +2023,5 @@ mod dispatches {
) -> DispatchResult {
Self::do_burn_alpha(origin, hotkey, amount, netuid)
}

/// Add liquidity to a specific price range for a subnet.
///
/// Parameters:
/// - origin: The origin of the transaction
/// - netuid: Subnet ID
/// - tick_low: Lower bound of the price range
/// - tick_high: Upper bound of the price range
/// - liquidity: Amount of liquidity to add
///
/// Emits `Event::LiquidityAdded` on success
#[pallet::call_index(103)]
#[pallet::weight((
Weight::from_parts(50_000_000, 0)
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(4)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn add_liquidity(
origin: OriginFor<T>,
hotkey: T::AccountId,
netuid: u16,
tick_low: i32,
tick_high: i32,
liquidity: u64,
) -> DispatchResult {
let coldkey = ensure_signed(origin)?;

// Ensure that the subnet exists.
ensure!(
Self::if_subnet_exist(netuid),
Error::<T>::SubNetworkDoesNotExist
);

let (position_id, tao, alpha) = T::SwapInterface::add_liquidity(
netuid, &coldkey, &hotkey, tick_low, tick_high, liquidity,
)?;

// Remove TAO and Alpha balances or fail transaction if they can't be removed exactly
let tao_provided = Self::remove_balance_from_coldkey_account(&coldkey, tao)?;
ensure!(tao_provided == tao, Error::<T>::InsufficientBalance);

let alpha_provided = Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey, &coldkey, netuid, alpha,
);
ensure!(alpha_provided == alpha, Error::<T>::InsufficientBalance);

// Emit an event
Self::deposit_event(Event::LiquidityAdded {
coldkey,
hotkey,
netuid,
position_id,
liquidity,
tao,
alpha,
});

Ok(())
}

/// Remove liquidity from a specific position.
///
/// Parameters:
/// - origin: The origin of the transaction
/// - netuid: Subnet ID
/// - position_id: ID of the position to remove
///
/// Emits `Event::LiquidityRemoved` on success
#[pallet::call_index(104)]
#[pallet::weight((
Weight::from_parts(50_000_000, 0)
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(T::DbWeight::get().writes(4)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn remove_liquidity(
origin: OriginFor<T>,
hotkey: T::AccountId,
netuid: u16,
position_id: u128,
) -> DispatchResult {
let coldkey = ensure_signed(origin)?;

// Ensure that the subnet exists.
ensure!(
Self::if_subnet_exist(netuid),
Error::<T>::SubNetworkDoesNotExist
);

// Ensure the hotkey account exists
ensure!(
Self::hotkey_account_exists(&hotkey),
Error::<T>::HotKeyAccountNotExists
);

// Remove liquidity
let result = T::SwapInterface::remove_liquidity(netuid, &coldkey, position_id)?;

// Credit the returned tao and alpha to the account
Self::add_balance_to_coldkey_account(
&coldkey,
result.tao.saturating_add(result.fee_tao),
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&coldkey,
netuid,
result.alpha.saturating_add(result.fee_alpha),
);

// Emit an event
Self::deposit_event(Event::LiquidityRemoved {
coldkey,
netuid: netuid.into(),
position_id,
tao: result.tao,
alpha: result.alpha,
fee_tao: result.fee_tao,
fee_alpha: result.fee_alpha,
});

Ok(())
}

/// Modify a liquidity position.
///
/// Parameters:
/// - origin: The origin of the transaction
/// - netuid: Subnet ID
/// - position_id: ID of the position to remove
/// - liquidity_delta: Liquidity to add (if positive) or remove (if negative)
///
/// Emits `Event::LiquidityRemoved` on success
#[pallet::call_index(105)]
#[pallet::weight((
Weight::from_parts(50_000_000, 0)
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(T::DbWeight::get().writes(4)),
DispatchClass::Operational,
Pays::Yes
))]
pub fn modify_position(
origin: OriginFor<T>,
hotkey: T::AccountId,
netuid: u16,
position_id: u128,
liquidity_delta: i64,
) -> DispatchResult {
let coldkey = ensure_signed(origin)?;

// Ensure that the subnet exists.
ensure!(
Self::if_subnet_exist(netuid),
Error::<T>::SubNetworkDoesNotExist
);

// Ensure the hotkey account exists
ensure!(
Self::hotkey_account_exists(&hotkey),
Error::<T>::HotKeyAccountNotExists
);

// Add or remove liquidity
let result = T::SwapInterface::modify_position(
netuid,
&coldkey,
&hotkey,
position_id,
liquidity_delta,
)?;

if liquidity_delta > 0 {
// Remove TAO and Alpha balances or fail transaction if they can't be removed exactly
let tao_provided = Self::remove_balance_from_coldkey_account(&coldkey, result.tao)?;
ensure!(tao_provided == result.tao, Error::<T>::InsufficientBalance);

let alpha_provided = Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&coldkey,
netuid,
result.alpha,
);
ensure!(
alpha_provided == result.alpha,
Error::<T>::InsufficientBalance
);

// Emit an event
Self::deposit_event(Event::LiquidityAdded {
coldkey,
hotkey,
netuid,
position_id,
liquidity: liquidity_delta as u64,
tao: result.tao,
alpha: result.alpha,
});
} else {
// Credit the returned tao and alpha to the account
Self::add_balance_to_coldkey_account(
&coldkey,
result.tao.saturating_add(result.fee_tao),
);
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey,
&coldkey,
netuid,
result.alpha.saturating_add(result.fee_alpha),
);

// Emit an event
Self::deposit_event(Event::LiquidityRemoved {
coldkey,
netuid: netuid.into(),
position_id,
tao: result.tao,
alpha: result.alpha,
fee_tao: result.fee_tao,
fee_alpha: result.fee_alpha,
});
}

Ok(())
}
}
}
}
36 changes: 0 additions & 36 deletions pallets/subtensor/src/macros/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,41 +323,5 @@ mod events {
/// - **netuid**: The network identifier.
/// - **Enabled**: Is Commit-Reveal enabled.
CommitRevealEnabled(u16, bool),

/// Event emitted when liquidity is added to a subnet's liquidity pool.
LiquidityAdded {
/// The coldkey account that owns the position
coldkey: T::AccountId,
/// The hotkey account associated with the position
hotkey: T::AccountId,
/// The subnet identifier
netuid: u16,
/// Unique identifier for the liquidity position
position_id: u128,
/// The amount of liquidity added to the position
liquidity: u64,
/// The amount of TAO tokens committed to the position
tao: u64,
/// The amount of Alpha tokens committed to the position
alpha: u64,
},

/// Event emitted when liquidity is removed from a subnet's liquidity pool.
LiquidityRemoved {
/// The coldkey account that owns the position
coldkey: T::AccountId,
/// The subnet identifier
netuid: u16,
/// Unique identifier for the liquidity position
position_id: u128,
/// The amount of TAO tokens returned to the user
tao: u64,
/// The amount of Alpha tokens returned to the user
alpha: u64,
/// The amount of TAO fees earned from the position
fee_tao: u64,
/// The amount of Alpha fees earned from the position
fee_alpha: u64,
},
}
}
1 change: 1 addition & 0 deletions pallets/subtensor/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ impl pallet_subtensor_swap::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AdminOrigin = EnsureRoot<AccountId>;
type LiquidityDataProvider = SubtensorModule;
type BalanceOps = SubtensorModule;
type ProtocolId = SwapProtocolId;
type MaxFeeRate = SwapMaxFeeRate;
type MaxPositions = SwapMaxPositions;
Expand Down
42 changes: 18 additions & 24 deletions pallets/swap-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,6 @@ pub trait SwapHandler<AccountId> {
price_limit: u64,
should_rollback: bool,
) -> Result<SwapResult, DispatchError>;
fn add_liquidity(
netuid: u16,
coldkey_account_id: &AccountId,
hotkey_account_id: &AccountId,
tick_low: i32,
tick_high: i32,
liquidity: u64,
) -> Result<(u128, u64, u64), DispatchError>;
fn remove_liquidity(
netuid: u16,
coldkey_account_id: &AccountId,
position_id: u128,
) -> Result<UpdateLiquidityResult, DispatchError>;
fn modify_position(
netuid: u16,
coldkey_account_id: &AccountId,
hotkey_account_id: &AccountId,
position_id: u128,
liquidity_delta: i64,
) -> Result<UpdateLiquidityResult, DispatchError>;
fn approx_fee_amount(netuid: u16, amount: u64) -> u64;
fn current_alpha_price(netuid: u16) -> U96F32;
fn max_price() -> u64;
Expand All @@ -63,10 +43,24 @@ pub struct UpdateLiquidityResult {
pub trait LiquidityDataProvider<AccountId> {
fn tao_reserve(netuid: u16) -> u64;
fn alpha_reserve(netuid: u16) -> u64;
fn subnet_exist(netuid: u16) -> bool;
}

pub trait BalanceOps<AccountId> {
fn tao_balance(account_id: &AccountId) -> u64;
fn alpha_balance(
fn alpha_balance(netuid: u16, coldkey: &AccountId, hotkey: &AccountId) -> u64;
fn increase_balance(coldkey: &AccountId, tao: u64);
fn decrease_balance(coldkey: &AccountId, tao: u64) -> Result<u64, DispatchError>;
fn increase_stake(
coldkey: &AccountId,
hotkey: &AccountId,
netuid: u16,
alpha: u64,
) -> Result<(), DispatchError>;
fn decrease_stake(
coldkey: &AccountId,
hotkey: &AccountId,
netuid: u16,
coldkey_account_id: &AccountId,
hotkey_account_id: &AccountId,
) -> u64;
alpha: u64,
) -> Result<u64, DispatchError>;
}
Loading
Loading