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
1 change: 0 additions & 1 deletion pallets/admin-utils/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ parameter_types! {

impl pallet_subtensor_swap::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AdminOrigin = EnsureRoot<AccountId>;
type SubnetInfo = SubtensorModule;
type BalanceOps = SubtensorModule;
type ProtocolId = SwapProtocolId;
Expand Down
4 changes: 4 additions & 0 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2439,6 +2439,10 @@ impl<T: Config + pallet_balances::Config<Balance = u64>>
fn mechanism(netuid: u16) -> u16 {
SubnetMechanism::<T>::get(netuid)
}

fn is_owner(account_id: &T::AccountId, netuid: u16) -> bool {
SubnetOwner::<T>::get(netuid) == *account_id
}
}

impl<T: Config + pallet_balances::Config<Balance = u64>>
Expand Down
1 change: 0 additions & 1 deletion pallets/subtensor/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ parameter_types! {

impl pallet_subtensor_swap::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AdminOrigin = EnsureRoot<AccountId>;
type SubnetInfo = SubtensorModule;
type BalanceOps = SubtensorModule;
type ProtocolId = SwapProtocolId;
Expand Down
1 change: 1 addition & 0 deletions pallets/swap-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub trait SubnetInfo<AccountId> {
fn alpha_reserve(netuid: u16) -> u64;
fn exists(netuid: u16) -> bool;
fn mechanism(netuid: u16) -> u16;
fn is_owner(account_id: &AccountId, netuid: u16) -> bool;
}

pub trait BalanceOps<AccountId> {
Expand Down
16 changes: 14 additions & 2 deletions pallets/swap/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use substrate_fixed::types::U64F64;
use crate::{
NetUid,
pallet::{
AlphaSqrtPrice, Call, Config, CurrentLiquidity, CurrentTick, Pallet, Positions,
SwapV3Initialized,
AlphaSqrtPrice, Call, Config, CurrentLiquidity, CurrentTick, EnabledUserLiquidity, Pallet,
Positions, SwapV3Initialized,
},
position::{Position, PositionId},
tick::TickIndex,
Expand Down Expand Up @@ -125,5 +125,17 @@ mod benchmarks {
);
}

#[benchmark]
fn set_enabled_user_liquidity() {
let netuid = NetUid::from(101);

assert!(!EnabledUserLiquidity::<T>::get(netuid));

#[extrinsic_call]
set_enabled_user_liquidity(RawOrigin::Root, netuid.into());

assert!(EnabledUserLiquidity::<T>::get(netuid));
}

impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test);
}
24 changes: 19 additions & 5 deletions pallets/swap/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ use frame_support::{
PalletId, parameter_types,
traits::{ConstU32, Everything},
};
use frame_system::{self as system, EnsureRoot};
use frame_system::{self as system};
use sp_core::H256;
use sp_runtime::{
BuildStorage,
traits::{BlakeTwo256, IdentityLookup},
};
use subtensor_swap_interface::{BalanceOps, SubnetInfo};

use crate::{NetUid, pallet::EnabledUserLiquidity};

construct_runtime!(
pub enum Test {
System: frame_system = 0,
Expand All @@ -27,6 +29,8 @@ pub type Block = frame_system::mocking::MockBlock<Test>;
pub type AccountId = u32;
pub const OK_COLDKEY_ACCOUNT_ID: AccountId = 1;
pub const OK_HOTKEY_ACCOUNT_ID: AccountId = 1000;
pub const NOT_SUBNET_OWNER: AccountId = 666;
pub const NON_EXISTENT_NETUID: u16 = 999;

parameter_types! {
pub const BlockHashCount: u64 = 250;
Expand Down Expand Up @@ -91,13 +95,17 @@ impl SubnetInfo<AccountId> for MockLiquidityProvider {
}
}

fn exists(_netuid: u16) -> bool {
true
fn exists(netuid: u16) -> bool {
netuid != NON_EXISTENT_NETUID
}

fn mechanism(netuid: u16) -> u16 {
if netuid == 0 { 0 } else { 1 }
}

fn is_owner(account_id: &AccountId, _netuid: u16) -> bool {
*account_id != NOT_SUBNET_OWNER
}
}

pub struct MockBalanceOps;
Expand Down Expand Up @@ -148,7 +156,6 @@ impl BalanceOps<AccountId> for MockBalanceOps {

impl crate::pallet::Config for Test {
type RuntimeEvent = RuntimeEvent;
type AdminOrigin = EnsureRoot<AccountId>;
type SubnetInfo = MockLiquidityProvider;
type BalanceOps = MockBalanceOps;
type ProtocolId = SwapProtocolId;
Expand All @@ -165,6 +172,13 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
.build_storage()
.unwrap();
let mut ext = sp_io::TestExternalities::new(storage);
ext.execute_with(|| System::set_block_number(1));
ext.execute_with(|| {
System::set_block_number(1);

for netuid in 0u16..=100 {
// enable V3 for this range of netuids
EnabledUserLiquidity::<Test>::set(NetUid::from(netuid), true);
}
});
ext
}
118 changes: 89 additions & 29 deletions pallets/swap/src/pallet/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,11 @@ impl<T: Config> Pallet<T> {
tick_high: TickIndex,
liquidity: u64,
) -> Result<(PositionId, u64, u64), Error<T>> {
ensure!(
EnabledUserLiquidity::<T>::get(netuid),
Error::<T>::UserLiquidityDisabled
);

let (position, tao, alpha) = Self::add_liquidity_not_insert(
netuid,
coldkey_account_id,
Expand Down Expand Up @@ -747,22 +752,6 @@ impl<T: Config> Pallet<T> {
let current_price = AlphaSqrtPrice::<T>::get(netuid);
let (tao, alpha) = position.to_token_amounts(current_price)?;

// If this is a user transaction, withdraw balances and update reserves
// TODO this should be returned (tao, alpha) from this function to prevent
// mutation of outside storage - the logic should be passed to the user of
// subtensor_swap_interface
// if !protocol {
// let current_price = self.state_ops.get_alpha_sqrt_price();
// let (tao, alpha) = position.to_token_amounts(current_price)?;
// self.state_ops.withdraw_balances(coldkey_account_id, tao, alpha)?;

// // Update reserves
// let new_tao_reserve = self.state_ops.get_tao_reserve().saturating_add(tao);
// self.state_ops.set_tao_reserve(new_tao_reserve);
// let new_alpha_reserve = self.state_ops.get_alpha_reserve().saturating_add(alpha);
// self.state_ops.set_alpha_reserve(new_alpha_reserve);
// }

SwapV3Initialized::<T>::set(netuid, true);

Ok((position, tao, alpha))
Expand All @@ -776,6 +765,11 @@ impl<T: Config> Pallet<T> {
coldkey_account_id: &T::AccountId,
position_id: PositionId,
) -> Result<UpdateLiquidityResult, Error<T>> {
ensure!(
EnabledUserLiquidity::<T>::get(netuid),
Error::<T>::UserLiquidityDisabled
);

let Some(mut position) = Positions::<T>::get((netuid, coldkey_account_id, position_id))
else {
return Err(Error::<T>::LiquidityNotFound);
Expand All @@ -801,18 +795,6 @@ impl<T: Config> Pallet<T> {
// Remove user position
Positions::<T>::remove((netuid, coldkey_account_id, position_id));

{
// TODO we move this logic to the outside depender to prevent mutating its state
// // Deposit balances
// self.state_ops.deposit_balances(account_id, tao, alpha);

// // Update reserves
// let new_tao_reserve = self.state_ops.get_tao_reserve().saturating_sub(tao);
// self.state_ops.set_tao_reserve(new_tao_reserve);
// let new_alpha_reserve = self.state_ops.get_alpha_reserve().saturating_sub(alpha);
// self.state_ops.set_alpha_reserve(new_alpha_reserve);
}

Ok(UpdateLiquidityResult {
tao,
alpha,
Expand All @@ -828,6 +810,11 @@ impl<T: Config> Pallet<T> {
position_id: PositionId,
liquidity_delta: i64,
) -> Result<UpdateLiquidityResult, Error<T>> {
ensure!(
EnabledUserLiquidity::<T>::get(netuid),
Error::<T>::UserLiquidityDisabled
);

// Find the position
let Some(mut position) = Positions::<T>::get((netuid, coldkey_account_id, position_id))
else {
Expand Down Expand Up @@ -1138,7 +1125,7 @@ pub enum SwapStepAction {
#[cfg(test)]
mod tests {
use approx::assert_abs_diff_eq;
use frame_support::{assert_err, assert_ok};
use frame_support::{assert_err, assert_noop, assert_ok};
use sp_arithmetic::helpers_128bit;

use super::*;
Expand Down Expand Up @@ -2441,4 +2428,77 @@ mod tests {
}
});
}

#[test]
fn test_user_liquidity_disabled() {
new_test_ext().execute_with(|| {
// Use a netuid above 100 since our mock enables liquidity for 0-100
let netuid = NetUid::from(101);
let tick_low = TickIndex::new_unchecked(-1000);
let tick_high = TickIndex::new_unchecked(1000);
let position_id = 1;
let liquidity = 1_000_000_000;
let liquidity_delta = 500_000_000;

assert!(!EnabledUserLiquidity::<Test>::get(netuid));

assert_noop!(
Swap::do_add_liquidity(
netuid,
&OK_COLDKEY_ACCOUNT_ID,
&OK_HOTKEY_ACCOUNT_ID,
tick_low,
tick_high,
liquidity
),
Error::<Test>::UserLiquidityDisabled
);

assert_noop!(
Swap::do_remove_liquidity(netuid, &OK_COLDKEY_ACCOUNT_ID, position_id.into()),
Error::<Test>::UserLiquidityDisabled
);

assert_noop!(
Swap::modify_position(
RuntimeOrigin::signed(OK_COLDKEY_ACCOUNT_ID),
OK_HOTKEY_ACCOUNT_ID,
netuid.into(),
position_id,
liquidity_delta
),
Error::<Test>::UserLiquidityDisabled
);

assert_ok!(Swap::set_enabled_user_liquidity(
RuntimeOrigin::root(),
netuid.into()
));

let position_id = Swap::do_add_liquidity(
netuid,
&OK_COLDKEY_ACCOUNT_ID,
&OK_HOTKEY_ACCOUNT_ID,
tick_low,
tick_high,
liquidity,
)
.unwrap()
.0;

assert_ok!(Swap::do_modify_position(
netuid.into(),
&OK_COLDKEY_ACCOUNT_ID,
&OK_HOTKEY_ACCOUNT_ID,
position_id,
liquidity_delta,
));

assert_ok!(Swap::do_remove_liquidity(
netuid.into(),
&OK_COLDKEY_ACCOUNT_ID,
position_id,
));
});
}
}
Loading
Loading