Skip to content

Commit 930d079

Browse files
authored
Merge pull request #1621 from opentensor/sasha/feat/uniswapv3-lp
Fix tick index math rounding
2 parents 5351bcf + ddbcabd commit 930d079

File tree

10 files changed

+155
-89
lines changed

10 files changed

+155
-89
lines changed

pallets/subtensor/src/macros/dispatches.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,17 +2189,29 @@ mod dispatches {
21892189
);
21902190

21912191
// Add or remove liquidity
2192-
let result = T::SwapInterface::modify_position(netuid, &coldkey, &hotkey, position_id, liquidity_delta)?;
2192+
let result = T::SwapInterface::modify_position(
2193+
netuid,
2194+
&coldkey,
2195+
&hotkey,
2196+
position_id,
2197+
liquidity_delta,
2198+
)?;
21932199

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

21992205
let alpha_provided = Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(
2200-
&hotkey, &coldkey, netuid, result.alpha,
2206+
&hotkey,
2207+
&coldkey,
2208+
netuid,
2209+
result.alpha,
2210+
);
2211+
ensure!(
2212+
alpha_provided == result.alpha,
2213+
Error::<T>::InsufficientBalance
22012214
);
2202-
ensure!(alpha_provided == result.alpha, Error::<T>::InsufficientBalance);
22032215

22042216
// Emit an event
22052217
Self::deposit_event(Event::LiquidityAdded {

pallets/subtensor/src/tests/children.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,14 +2416,14 @@ fn test_revoke_child_no_min_stake_check() {
24162416
add_network(netuid, 13, 0);
24172417
register_ok_neuron(netuid, parent, coldkey, 0);
24182418

2419-
let reserve = 1_000_000_000_000_000;
2420-
mock::setup_reserves(netuid, reserve, reserve);
2421-
mock::setup_reserves(root, reserve, reserve);
2419+
let reserve = 1_000_000_000_000_000;
2420+
mock::setup_reserves(netuid, reserve, reserve);
2421+
mock::setup_reserves(root, reserve, reserve);
24222422

24232423
// Set minimum stake for setting children
24242424
StakeThreshold::<Test>::put(1_000_000_000_000);
24252425

2426-
let (_, fee) = mock::swap_tao_to_alpha(root, StakeThreshold::<Test>::get());
2426+
let (_, fee) = mock::swap_tao_to_alpha(root, StakeThreshold::<Test>::get());
24272427
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
24282428
&parent,
24292429
&coldkey,
@@ -2494,12 +2494,12 @@ fn test_do_set_child_registration_disabled() {
24942494
add_network(netuid, 13, 0);
24952495
register_ok_neuron(netuid, parent, coldkey, 0);
24962496

2497-
let reserve = 1_000_000_000_000_000;
2498-
mock::setup_reserves(netuid, reserve, reserve);
2497+
let reserve = 1_000_000_000_000_000;
2498+
mock::setup_reserves(netuid, reserve, reserve);
24992499

25002500
// Set minimum stake for setting children
25012501
StakeThreshold::<Test>::put(1_000_000_000_000);
2502-
let (_, fee) = mock::swap_tao_to_alpha(netuid, StakeThreshold::<Test>::get());
2502+
let (_, fee) = mock::swap_tao_to_alpha(netuid, StakeThreshold::<Test>::get());
25032503
SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet(
25042504
&parent,
25052505
&coldkey,

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,8 +1980,8 @@ fn test_run_coinbase_not_started() {
19801980
// Set weight-set limit to 0.
19811981
SubtensorModule::set_weights_set_rate_limit(netuid, 0);
19821982

1983-
let reserve = init_stake * 1000;
1984-
mock::setup_reserves(netuid, reserve, reserve);
1983+
let reserve = init_stake * 1000;
1984+
mock::setup_reserves(netuid, reserve, reserve);
19851985

19861986
register_ok_neuron(netuid, hotkey, coldkey, 0);
19871987
register_ok_neuron(netuid, miner_hk, miner_ck, 0);

pallets/subtensor/src/tests/mock.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,4 +899,3 @@ pub(crate) fn swap_alpha_to_tao(netuid: u16, alpha: u64) -> (u64, u64) {
899899

900900
(result.amount_paid_out, result.fee_paid)
901901
}
902-

pallets/subtensor/src/tests/senate.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,19 @@ fn test_senate_vote_works() {
191191
stake
192192
));
193193

194-
let approx_expected = stake - fee;
194+
let approx_expected = stake - fee;
195195
assert_abs_diff_eq!(
196196
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
197197
&hotkey_account_id,
198198
&staker_coldkey,
199199
netuid
200200
),
201-
approx_expected,
201+
approx_expected,
202202
epsilon = approx_expected / 1000
203203
);
204204
assert_abs_diff_eq!(
205205
SubtensorModule::get_stake_for_hotkey_on_subnet(&hotkey_account_id, netuid),
206-
approx_expected,
206+
approx_expected,
207207
epsilon = approx_expected / 1000
208208
);
209209

pallets/subtensor/src/tests/swap_hotkey.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ fn test_swap_total_hotkey_stake() {
7979

8080
// Add stake
8181
let (expected_alpha, _) = mock::swap_tao_to_alpha(netuid, amount);
82-
assert!(expected_alpha > 0);
82+
assert!(expected_alpha > 0);
8383
assert_ok!(SubtensorModule::add_stake(
8484
RuntimeOrigin::signed(coldkey),
8585
old_hotkey,
@@ -88,7 +88,10 @@ fn test_swap_total_hotkey_stake() {
8888
));
8989

9090
// Check if stake has increased
91-
assert_eq!(TotalHotkeyAlpha::<Test>::get(old_hotkey, netuid), expected_alpha);
91+
assert_eq!(
92+
TotalHotkeyAlpha::<Test>::get(old_hotkey, netuid),
93+
expected_alpha
94+
);
9295
assert_abs_diff_eq!(
9396
SubtensorModule::get_total_stake_for_hotkey(&new_hotkey),
9497
0,
@@ -109,7 +112,10 @@ fn test_swap_total_hotkey_stake() {
109112
0,
110113
epsilon = 1,
111114
);
112-
assert_eq!(TotalHotkeyAlpha::<Test>::get(new_hotkey, netuid), expected_alpha);
115+
assert_eq!(
116+
TotalHotkeyAlpha::<Test>::get(new_hotkey, netuid),
117+
expected_alpha
118+
);
113119
});
114120
}
115121

pallets/swap/src/pallet/impls.rs

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use sp_arithmetic::helpers_128bit;
77
use sp_runtime::traits::AccountIdConversion;
88
use substrate_fixed::types::{U64F64, U96F32};
99
use subtensor_swap_interface::{
10-
LiquidityDataProvider, UpdateLiquidityResult, SwapHandler, SwapResult,
10+
LiquidityDataProvider, SwapHandler, SwapResult, UpdateLiquidityResult,
1111
};
1212

1313
use super::pallet::*;
@@ -90,14 +90,14 @@ impl<T: Config> SwapStep<T> {
9090
lq = one.safe_div(TickIndex::min_sqrt_price());
9191
}
9292
lq
93-
},
93+
}
9494
OrderType::Buy => {
9595
let mut lq = TickIndex::max_sqrt_price().min(sqrt_price_limit.into());
9696
if lq < current_price {
9797
lq = TickIndex::max_sqrt_price();
9898
}
9999
lq
100-
},
100+
}
101101
};
102102

103103
Self {
@@ -228,10 +228,8 @@ impl<T: Config> SwapStep<T> {
228228
delta_fixed.saturating_mul(u16_max.safe_div(u16_max.saturating_sub(fee_rate)));
229229

230230
// Hold the fees
231-
let fee = Pallet::<T>::calculate_fee_amount(
232-
self.netuid,
233-
total_cost.saturating_to_num::<u64>(),
234-
);
231+
let fee =
232+
Pallet::<T>::calculate_fee_amount(self.netuid, total_cost.saturating_to_num::<u64>());
235233
Pallet::<T>::add_fees(self.netuid, self.order_type, fee);
236234
let delta_out = Pallet::<T>::convert_deltas(self.netuid, self.order_type, self.delta_in);
237235

@@ -336,14 +334,11 @@ impl<T: Config> Pallet<T> {
336334
let epsilon = U64F64::saturating_from_num(0.000001);
337335

338336
let current_sqrt_price = price.checked_sqrt(epsilon).unwrap_or(U64F64::from_num(0));
339-
AlphaSqrtPrice::<T>::set(
340-
netuid,
341-
current_sqrt_price,
342-
);
337+
AlphaSqrtPrice::<T>::set(netuid, current_sqrt_price);
343338

344339
// Set current tick
345340
let current_tick = TickIndex::from_sqrt_price_bounded(current_sqrt_price);
346-
CurrentTick::<T>::set(netuid, current_tick);
341+
CurrentTick::<T>::set(netuid, current_tick);
347342

348343
// Set initial (protocol owned) liquidity and positions
349344
// Protocol liquidity makes one position from TickIndex::MIN to TickIndex::MAX
@@ -1174,8 +1169,14 @@ impl<T: Config> SwapHandler<T::AccountId> for Pallet<T> {
11741169
position_id: u128,
11751170
liquidity_delta: i64,
11761171
) -> Result<UpdateLiquidityResult, DispatchError> {
1177-
Self::modify_position(netuid.into(), coldkey_account_id, hotkey_account_id, position_id.into(), liquidity_delta)
1178-
.map_err(Into::into)
1172+
Self::modify_position(
1173+
netuid.into(),
1174+
coldkey_account_id,
1175+
hotkey_account_id,
1176+
position_id.into(),
1177+
liquidity_delta,
1178+
)
1179+
.map_err(Into::into)
11791180
}
11801181

11811182
fn approx_fee_amount(netuid: u16, amount: u64) -> u64 {
@@ -1298,7 +1299,7 @@ mod tests {
12981299
assert_eq!(sqrt_price, expected_sqrt_price);
12991300

13001301
// Verify that current tick is set
1301-
let current_tick = CurrentTick::<Test>::get(netuid);
1302+
let current_tick = CurrentTick::<Test>::get(netuid);
13021303
let expected_current_tick = TickIndex::from_sqrt_price_bounded(expected_sqrt_price);
13031304
assert_eq!(current_tick, expected_current_tick);
13041305

@@ -1729,15 +1730,14 @@ mod tests {
17291730

17301731
// Modify liquidity (also causes claiming of fees)
17311732
let liquidity_before = CurrentLiquidity::<Test>::get(netuid);
1732-
let modify_result =
1733-
Pallet::<Test>::modify_position(
1734-
netuid,
1735-
&OK_COLDKEY_ACCOUNT_ID,
1736-
&OK_HOTKEY_ACCOUNT_ID,
1737-
position_id,
1738-
-1_i64 * ((liquidity / 10) as i64),
1739-
)
1740-
.unwrap();
1733+
let modify_result = Pallet::<Test>::modify_position(
1734+
netuid,
1735+
&OK_COLDKEY_ACCOUNT_ID,
1736+
&OK_HOTKEY_ACCOUNT_ID,
1737+
position_id,
1738+
-1_i64 * ((liquidity / 10) as i64),
1739+
)
1740+
.unwrap();
17411741
assert_abs_diff_eq!(modify_result.alpha, alpha / 10, epsilon = alpha / 1000);
17421742
assert!(modify_result.fee_tao > 0);
17431743
assert_eq!(modify_result.fee_alpha, 0);
@@ -1753,22 +1753,20 @@ mod tests {
17531753

17541754
// Position liquidity is reduced
17551755
let position =
1756-
Positions::<Test>::get(&(netuid, OK_COLDKEY_ACCOUNT_ID, position_id))
1757-
.unwrap();
1756+
Positions::<Test>::get(&(netuid, OK_COLDKEY_ACCOUNT_ID, position_id)).unwrap();
17581757
assert_eq!(position.liquidity, liquidity * 9 / 10);
17591758
assert_eq!(position.tick_low, tick_low);
17601759
assert_eq!(position.tick_high, tick_high);
17611760

17621761
// Modify liquidity again (ensure fees aren't double-collected)
1763-
let modify_result =
1764-
Pallet::<Test>::modify_position(
1765-
netuid,
1766-
&OK_COLDKEY_ACCOUNT_ID,
1767-
&OK_HOTKEY_ACCOUNT_ID,
1768-
position_id,
1769-
-1_i64 * ((liquidity / 100) as i64),
1770-
)
1771-
.unwrap();
1762+
let modify_result = Pallet::<Test>::modify_position(
1763+
netuid,
1764+
&OK_COLDKEY_ACCOUNT_ID,
1765+
&OK_HOTKEY_ACCOUNT_ID,
1766+
position_id,
1767+
-1_i64 * ((liquidity / 100) as i64),
1768+
)
1769+
.unwrap();
17721770

17731771
assert_abs_diff_eq!(modify_result.alpha, alpha / 100, epsilon = alpha / 1000);
17741772
assert_eq!(modify_result.fee_tao, 0);
@@ -1913,9 +1911,10 @@ mod tests {
19131911
}
19141912

19151913
// Assert that current tick is updated
1916-
let current_tick = CurrentTick::<Test>::get(netuid);
1917-
let expected_current_tick = TickIndex::from_sqrt_price_bounded(sqrt_current_price_after);
1918-
assert_eq!(current_tick, expected_current_tick);
1914+
let current_tick = CurrentTick::<Test>::get(netuid);
1915+
let expected_current_tick =
1916+
TickIndex::from_sqrt_price_bounded(sqrt_current_price_after);
1917+
assert_eq!(current_tick, expected_current_tick);
19191918
},
19201919
);
19211920
});
@@ -2390,13 +2389,12 @@ mod tests {
23902389

23912390
let current_price = SqrtPrice::from_num(0.50000051219212275465);
23922391
let tick = TickIndex::try_from_sqrt_price(current_price).unwrap();
2392+
23932393
let round_trip_price = TickIndex::try_to_sqrt_price(&tick).unwrap();
23942394
assert!(round_trip_price <= current_price);
23952395

23962396
let roundtrip_tick = TickIndex::try_from_sqrt_price(round_trip_price).unwrap();
23972397
assert!(tick == roundtrip_tick);
23982398
});
23992399
}
2400-
2401-
24022400
}

pallets/swap/src/pallet/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ mod pallet {
170170
/// Provided liquidity parameter is invalid (likely too small)
171171
InvalidLiquidityValue,
172172

173-
/// Reserves too low for operation.
174-
ReservesTooLow,
173+
/// Reserves too low for operation.
174+
ReservesTooLow,
175175
}
176176

177177
#[pallet::call]

pallets/swap/src/position.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,10 @@ impl Position {
107107
fee_tao = liquidity_frac.saturating_mul(fee_tao);
108108
fee_alpha = liquidity_frac.saturating_mul(fee_alpha);
109109

110-
(fee_tao.saturating_to_num::<u64>(), fee_alpha.saturating_to_num::<u64>())
110+
(
111+
fee_tao.saturating_to_num::<u64>(),
112+
fee_alpha.saturating_to_num::<u64>(),
113+
)
111114
}
112115

113116
/// Get fees in a position's range

0 commit comments

Comments
 (0)