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
2 changes: 1 addition & 1 deletion pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<T: Config> Pallet<T> {
*total = total.saturating_add(tao_in_i);
});
// Adjust protocol liquidity based on new reserves
T::SwapInterface::adjust_protocol_liquidity(*netuid_i);
T::SwapInterface::adjust_protocol_liquidity(*netuid_i, tao_in_i, alpha_in_i);
}

// --- 5. Compute owner cuts and remove them from alpha_out remaining.
Expand Down
11 changes: 10 additions & 1 deletion pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,6 @@ pub mod pallet {
StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultZeroU64<T>>;
#[pallet::storage]
/// --- MAP ( netuid ) --> alpha_supply_in_subnet | Returns the amount of alpha in the subnet.
/// TODO: Deprecate, not accurate and not used in v3 anymore
pub type SubnetAlphaOut<T: Config> =
StorageMap<_, Identity, NetUid, u64, ValueQuery, DefaultZeroU64<T>>;
#[pallet::storage] // --- MAP ( cold ) --> Vec<hot> | Maps coldkey to hotkeys that stake to it
Expand Down Expand Up @@ -2573,6 +2572,11 @@ impl<T: Config + pallet_balances::Config<Balance = u64>>
Error::<T>::HotKeyAccountNotExists
);

// Increse alpha out counter
SubnetAlphaOut::<T>::mutate(netuid, |total| {
*total = total.saturating_add(alpha);
});

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

Ok(())
Expand All @@ -2589,6 +2593,11 @@ impl<T: Config + pallet_balances::Config<Balance = u64>>
Error::<T>::HotKeyAccountNotExists
);

// Decrese alpha out counter
SubnetAlphaOut::<T>::mutate(netuid, |total| {
*total = total.saturating_sub(alpha);
});

Ok(Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
hotkey, coldkey, netuid, alpha,
))
Expand Down
3 changes: 2 additions & 1 deletion pallets/swap-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub trait SwapHandler<AccountId> {
fn current_alpha_price(netuid: NetUid) -> U96F32;
fn max_price() -> u64;
fn min_price() -> u64;
fn adjust_protocol_liquidity(netuid: NetUid);
fn adjust_protocol_liquidity(netuid: NetUid, tao_delta: u64, alpha_delta: u64);
fn is_user_liquidity_enabled(netuid: NetUid) -> bool;
}

Expand All @@ -47,4 +47,5 @@ pub struct UpdateLiquidityResult {
pub alpha: u64,
pub fee_tao: u64,
pub fee_alpha: u64,
pub removed: bool,
}
43 changes: 29 additions & 14 deletions pallets/swap/src/pallet/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,23 +326,30 @@ impl<T: Config> Pallet<T> {
}

/// Adjusts protocol liquidity with new values of TAO and Alpha reserve
pub(super) fn adjust_protocol_liquidity(netuid: NetUid) {
// Get updated reserves, calculate liquidity
let tao_reserve = <T as Config>::SubnetInfo::tao_reserve(netuid.into());
let alpha_reserve = <T as Config>::SubnetInfo::alpha_reserve(netuid.into());
let liquidity =
helpers_128bit::sqrt((tao_reserve as u128).saturating_mul(alpha_reserve as u128))
as u64;

pub(super) fn adjust_protocol_liquidity(netuid: NetUid, tao_delta: u64, alpha_delta: u64) {
// Update protocol position with new liquidity
let protocol_account_id = Self::protocol_account_id();
let mut positions =
Positions::<T>::iter_prefix_values((netuid, protocol_account_id.clone()))
.collect::<sp_std::vec::Vec<_>>();

if let Some(position) = positions.get_mut(0) {
position.liquidity = liquidity;
Positions::<T>::insert((netuid, protocol_account_id, position.id), position.clone());
let current_sqrt_price = Pallet::<T>::current_price_sqrt(netuid);
let maybe_token_amounts = position.to_token_amounts(current_sqrt_price);
if let Ok((tao, alpha)) = maybe_token_amounts {
// Get updated reserves, calculate liquidity
let new_tao_reserve = tao.saturating_add(tao_delta);
let new_alpha_reserve = alpha.saturating_add(alpha_delta);
let new_liquidity = helpers_128bit::sqrt(
(new_tao_reserve as u128).saturating_mul(new_alpha_reserve as u128),
) as u64;

position.liquidity = new_liquidity;
Positions::<T>::insert(
(netuid, protocol_account_id, position.id),
position.clone(),
);
}
}
}

Expand Down Expand Up @@ -855,6 +862,7 @@ impl<T: Config> Pallet<T> {
alpha,
fee_tao,
fee_alpha,
removed: true,
})
}

Expand Down Expand Up @@ -938,10 +946,12 @@ impl<T: Config> Pallet<T> {

// If delta brings the position liquidity below MinimumLiquidity, eliminate position and
// withdraw full amounts
let mut remove = false;
if (liquidity_delta < 0)
&& (position.liquidity.saturating_sub(delta_liquidity_abs) < T::MinimumLiquidity::get())
{
delta_liquidity_abs = position.liquidity;
remove = true;
}

// Adjust liquidity at the ticks based on the delta sign
Expand All @@ -960,15 +970,20 @@ impl<T: Config> Pallet<T> {
// Remove liquidity from user position
position.liquidity = position.liquidity.saturating_sub(delta_liquidity_abs);
}
Positions::<T>::insert(&(netuid, coldkey_account_id, position.id), position);

// TODO: Withdraw balances and update pool reserves
// Update or, in case if full liquidity is removed, remove the position
if remove {
Positions::<T>::remove((netuid, coldkey_account_id, position_id));
} else {
Positions::<T>::insert(&(netuid, coldkey_account_id, position.id), position);
}

Ok(UpdateLiquidityResult {
tao: tao.saturating_to_num::<u64>(),
alpha: alpha.saturating_to_num::<u64>(),
fee_tao,
fee_alpha,
removed: remove,
})
}

Expand Down Expand Up @@ -1173,8 +1188,8 @@ impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
.saturating_to_num()
}

fn adjust_protocol_liquidity(netuid: NetUid) {
Self::adjust_protocol_liquidity(netuid);
fn adjust_protocol_liquidity(netuid: NetUid, tao_delta: u64, alpha_delta: u64) {
Self::adjust_protocol_liquidity(netuid, tao_delta, alpha_delta);
}

fn is_user_liquidity_enabled(netuid: NetUid) -> bool {
Expand Down
76 changes: 60 additions & 16 deletions pallets/swap/src/pallet/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::num::NonZeroU64;
use core::ops::Neg;

use frame_support::{PalletId, pallet_prelude::*, traits::Get};
use frame_system::pallet_prelude::*;
Expand Down Expand Up @@ -149,11 +150,11 @@ mod pallet {
/// First enable even indicates a switch from V2 to V3 swap.
UserLiquidityToggled { netuid: NetUid, enable: bool },

/// Event emitted when liquidity is added to a subnet's liquidity pool.
/// Event emitted when a liquidity position 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
/// The hotkey account where Alpha comes from
hotkey: T::AccountId,
/// The subnet identifier
netuid: NetUid,
Expand All @@ -167,10 +168,12 @@ mod pallet {
alpha: u64,
},

/// Event emitted when liquidity is removed from a subnet's liquidity pool.
/// Event emitted when a liquidity position is removed from a subnet's liquidity pool.
LiquidityRemoved {
/// The coldkey account that owns the position
coldkey: T::AccountId,
/// The hotkey account where Alpha goes to
hotkey: T::AccountId,
/// The subnet identifier
netuid: NetUid,
/// Unique identifier for the liquidity position
Expand All @@ -184,6 +187,29 @@ mod pallet {
/// The amount of Alpha fees earned from the position
fee_alpha: u64,
},

/// Event emitted when a liquidity position is modified in a subnet's liquidity pool.
/// Modifying causes the fees to be claimed.
LiquidityModified {
/// The coldkey account that owns the position
coldkey: T::AccountId,
/// The hotkey account where Alpha comes from or goes to
hotkey: T::AccountId,
/// The subnet identifier
netuid: NetUid,
/// Unique identifier for the liquidity position
position_id: PositionId,
/// The amount of liquidity added to or removed from the position
liquidity: i64,
/// The amount of TAO tokens returned to the user
tao: i64,
/// The amount of Alpha tokens returned to the user
alpha: i64,
/// The amount of TAO fees earned from the position
fee_tao: u64,
/// The amount of Alpha fees earned from the position
fee_alpha: u64,
},
}

#[pallet::error]
Expand Down Expand Up @@ -402,6 +428,7 @@ mod pallet {
// Emit an event
Self::deposit_event(Event::LiquidityRemoved {
coldkey,
hotkey,
netuid: netuid.into(),
position_id,
tao: result.tao,
Expand Down Expand Up @@ -456,30 +483,47 @@ mod pallet {
);

// Emit an event
Self::deposit_event(Event::LiquidityAdded {
Self::deposit_event(Event::LiquidityModified {
coldkey: coldkey.clone(),
hotkey: hotkey.clone(),
netuid,
position_id,
liquidity: liquidity_delta as u64,
tao: result.tao,
alpha: result.alpha,
liquidity: liquidity_delta,
tao: result.tao as i64,
alpha: result.alpha as i64,
fee_tao: result.fee_tao,
fee_alpha: result.fee_alpha,
});
} else {
// Credit the returned tao and alpha to the account
T::BalanceOps::increase_balance(&coldkey, result.tao);
T::BalanceOps::increase_stake(&coldkey, &hotkey, netuid.into(), result.alpha)?;

// Emit an event
Self::deposit_event(Event::LiquidityRemoved {
coldkey: coldkey.clone(),
netuid,
position_id,
tao: result.tao,
alpha: result.alpha,
fee_tao: result.fee_tao,
fee_alpha: result.fee_alpha,
});
if result.removed {
Self::deposit_event(Event::LiquidityRemoved {
coldkey: coldkey.clone(),
hotkey: hotkey.clone(),
netuid,
position_id,
tao: result.tao,
alpha: result.alpha,
fee_tao: result.fee_tao,
fee_alpha: result.fee_alpha,
});
} else {
Self::deposit_event(Event::LiquidityModified {
coldkey: coldkey.clone(),
hotkey: hotkey.clone(),
netuid,
position_id,
liquidity: liquidity_delta,
tao: (result.tao as i64).neg(),
alpha: (result.alpha as i64).neg(),
fee_tao: result.fee_tao,
fee_alpha: result.fee_alpha,
});
}
}

// Credit accrued fees to user account (no matter if liquidity is added or removed)
Expand Down
Loading