Skip to content

Commit c57624f

Browse files
committed
only subsidize when sum of prices < 1
1 parent a5fc4ff commit c57624f

File tree

2 files changed

+59
-54
lines changed

2 files changed

+59
-54
lines changed

pallets/subtensor/src/coinbase/run_coinbase.rs

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,10 @@ impl<T: Config> Pallet<T> {
3838
.collect();
3939
log::debug!("Subnets to emit to: {subnets_to_emit_to:?}");
4040

41-
// --- 2. Get sum of tao reserves ( in a later version we will switch to prices. )
41+
// --- 2. Get sum of moving alpha prices
4242
let mut acc_total_moving_prices = U96F32::saturating_from_num(0.0);
4343
// Only get price EMA for subnets that we emit to.
4444
for netuid_i in subnets_to_emit_to.iter() {
45-
// Get and update the moving price of each subnet adding the total together.
4645
acc_total_moving_prices =
4746
acc_total_moving_prices.saturating_add(Self::get_moving_alpha_price(*netuid_i));
4847
}
@@ -54,7 +53,8 @@ impl<T: Config> Pallet<T> {
5453
let mut tao_in: BTreeMap<NetUid, U96F32> = BTreeMap::new();
5554
let mut alpha_in: BTreeMap<NetUid, U96F32> = BTreeMap::new();
5655
let mut alpha_out: BTreeMap<NetUid, U96F32> = BTreeMap::new();
57-
let mut tao_to_stake = U96F32::saturating_from_num(0.0);
56+
let mut is_subsidized: BTreeMap<NetUid, bool> = BTreeMap::new();
57+
let mut subsidy_amount: BTreeMap<NetUid, U96F32> = BTreeMap::new();
5858

5959
// Only calculate for subnets that we are emitting to.
6060
for netuid_i in subnets_to_emit_to.iter() {
@@ -84,15 +84,37 @@ impl<T: Config> Pallet<T> {
8484

8585
let mut alpha_in_i: U96F32;
8686
let mut tao_in_i: U96F32;
87-
let min_alpha_emission = alpha_emission_i.min(block_emission);
88-
if default_alpha_in_i > min_alpha_emission {
87+
if default_alpha_in_i > alpha_emission_i
88+
|| total_moving_prices < U96F32::saturating_from_num(1.0)
89+
{
90+
let min_alpha_emission =
91+
default_alpha_in_i.min(alpha_emission_i).min(block_emission);
8992
alpha_in_i = min_alpha_emission;
9093
tao_in_i = alpha_in_i.saturating_mul(price_i);
91-
let difference_tao: U96F32 = default_tao_in_i.saturating_sub(tao_in_i);
92-
tao_to_stake = tao_to_stake.saturating_add(difference_tao);
94+
95+
if total_moving_prices < U96F32::saturating_from_num(1.0) {
96+
let difference_tao: U96F32 = default_tao_in_i.saturating_sub(tao_in_i);
97+
// Difference becomes buy.
98+
let buy_swap_result = Self::swap_tao_for_alpha(
99+
*netuid_i,
100+
tou64!(difference_tao).into(),
101+
T::SwapInterface::max_price(),
102+
true,
103+
);
104+
if let Ok(buy_swap_result_ok) = buy_swap_result {
105+
let bought_alpha = AlphaCurrency::from(buy_swap_result_ok.amount_paid_out);
106+
SubnetAlphaOut::<T>::mutate(*netuid_i, |total| {
107+
*total = total.saturating_sub(bought_alpha);
108+
});
109+
}
110+
is_subsidized.insert(*netuid_i, true);
111+
subsidy_amount.insert(*netuid_i, difference_tao);
112+
}
93113
} else {
94114
alpha_in_i = default_alpha_in_i;
95115
tao_in_i = default_tao_in_i;
116+
is_subsidized.insert(*netuid_i, false);
117+
subsidy_amount.insert(*netuid_i, asfloat!(0.0));
96118
}
97119
log::debug!("tao_in_i: {tao_in_i:?}");
98120
log::debug!("alpha_in_i: {alpha_in_i:?}");
@@ -113,29 +135,6 @@ impl<T: Config> Pallet<T> {
113135
alpha_out.insert(*netuid_i, alpha_out_i);
114136
}
115137

116-
let amount_per_subnet: U96F32 = tao_to_stake.safe_div_or(
117-
U96F32::saturating_from_num(subnets_to_emit_to.len()),
118-
U96F32::saturating_from_num(0.0),
119-
);
120-
121-
if amount_per_subnet > asfloat!(0.0) {
122-
for netuid_i in subnets_to_emit_to.iter() {
123-
let buy_swap_result = Self::swap_tao_for_alpha(
124-
*netuid_i,
125-
tou64!(amount_per_subnet).into(),
126-
T::SwapInterface::max_price().into(),
127-
true,
128-
);
129-
if let Ok(buy_swap_result_ok) = buy_swap_result {
130-
let bought_alpha = AlphaCurrency::from(buy_swap_result_ok.amount_paid_out);
131-
SubnetAlphaOut::<T>::mutate(*netuid_i, |total| {
132-
*total = total.saturating_sub(bought_alpha);
133-
});
134-
}
135-
}
136-
}
137-
138-
log::debug!("tao_to_stake: {tao_to_stake:?}");
139138
log::debug!("tao_in: {tao_in:?}");
140139
log::debug!("alpha_in: {alpha_in:?}");
141140
log::debug!("alpha_out: {alpha_out:?}");
@@ -158,20 +157,25 @@ impl<T: Config> Pallet<T> {
158157
SubnetAlphaOut::<T>::mutate(*netuid_i, |total| {
159158
*total = total.saturating_add(alpha_out_i);
160159
});
160+
161161
// Inject TAO in.
162162
let tao_in_i: TaoCurrency =
163163
tou64!(*tao_in.get(netuid_i).unwrap_or(&asfloat!(0))).into();
164+
let subsidy_tao: TaoCurrency =
165+
tou64!(*subsidy_amount.get(netuid_i).unwrap_or(&asfloat!(0))).into();
164166
SubnetTaoInEmission::<T>::insert(*netuid_i, TaoCurrency::from(tao_in_i));
167+
168+
// No need to add subsidy_tao here as it is captured from the swap result above.
165169
SubnetTAO::<T>::mutate(*netuid_i, |total| {
166170
*total = total.saturating_add(tao_in_i.into());
167171
});
168-
169172
TotalStake::<T>::mutate(|total| {
170173
*total = total.saturating_add(tao_in_i.into());
171174
});
175+
// Here we add subsidy tao as it is technically as issuance
172176
TotalIssuance::<T>::mutate(|total| {
173177
*total = total.saturating_add(tao_in_i.into());
174-
*total = total.saturating_add(tou64!(amount_per_subnet).into());
178+
*total = total.saturating_add(subsidy_tao.into());
175179
});
176180
// Adjust protocol liquidity based on new reserves
177181
T::SwapInterface::adjust_protocol_liquidity(*netuid_i, tao_in_i, alpha_in_i);
@@ -229,19 +233,21 @@ impl<T: Config> Pallet<T> {
229233
// Get pending alpha as original alpha_out - root_alpha.
230234
let pending_alpha: U96F32 = alpha_out_i.saturating_sub(root_alpha);
231235
log::debug!("pending_alpha: {pending_alpha:?}");
232-
// Sell root emission through the pool (do not pay fees)
233-
let swap_result = Self::swap_alpha_for_tao(
234-
*netuid_i,
235-
tou64!(root_alpha).into(),
236-
T::SwapInterface::min_price().into(),
237-
true,
238-
);
239-
if let Ok(ok_result) = swap_result {
240-
let root_tao: u64 = ok_result.amount_paid_out;
241-
// Accumulate root divs for subnet.
242-
PendingRootDivs::<T>::mutate(*netuid_i, |total| {
243-
*total = total.saturating_add(root_tao.into());
244-
});
236+
let subsidized: bool = *is_subsidized.get(netuid_i).unwrap_or(&false);
237+
if !subsidized {
238+
let swap_result = Self::swap_alpha_for_tao(
239+
*netuid_i,
240+
tou64!(root_alpha).into(),
241+
T::SwapInterface::min_price(),
242+
true,
243+
);
244+
if let Ok(ok_result) = swap_result {
245+
let root_tao = ok_result.amount_paid_out;
246+
// Accumulate root divs for subnet.
247+
PendingRootDivs::<T>::mutate(*netuid_i, |total| {
248+
*total = total.saturating_add(root_tao);
249+
});
250+
}
245251
}
246252
// Accumulate alpha emission in pending.
247253
PendingAlphaSwapped::<T>::mutate(*netuid_i, |total| {

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,15 @@ fn test_coinbase_tao_issuance_different_prices() {
194194

195195
// Run the coinbase with the emission amount.
196196
SubtensorModule::run_coinbase(U96F32::from_num(emission));
197-
198197
// Assert tao emission is split evenly.
199198
assert_abs_diff_eq!(
200199
SubnetTAO::<Test>::get(netuid1),
201-
TaoCurrency::from(initial_tao + 45 * emission / 100),
200+
TaoCurrency::from(initial_tao + emission / 3),
202201
epsilon = 1.into(),
203202
);
204203
assert_abs_diff_eq!(
205204
SubnetTAO::<Test>::get(netuid2),
206-
TaoCurrency::from(initial_tao + 55 * emission / 100),
205+
TaoCurrency::from(initial_tao + 2 * emission / 3),
207206
epsilon = 1.into(),
208207
);
209208

@@ -429,7 +428,7 @@ fn test_coinbase_alpha_issuance_with_cap_trigger() {
429428
SubnetAlphaIn::<Test>::insert(netuid1, AlphaCurrency::from(initial_alpha)); // Make price extremely low.
430429
SubnetTAO::<Test>::insert(netuid2, TaoCurrency::from(initial));
431430
SubnetAlphaIn::<Test>::insert(netuid2, AlphaCurrency::from(initial_alpha)); // Make price extremely low.
432-
// Set subnet prices.
431+
// Set subnet prices.
433432
SubnetMovingPrice::<Test>::insert(netuid1, I96F32::from_num(1));
434433
SubnetMovingPrice::<Test>::insert(netuid2, I96F32::from_num(2));
435434
// Run coinbase
@@ -957,8 +956,8 @@ fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_am
957956

958957
// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_amounts_half_tao_weight --exact --show-output --nocapture
959958
#[test]
960-
fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_amounts_half_tao_weight()
961-
{
959+
fn test_drain_base_with_subnet_with_two_stakers_registered_and_root_different_amounts_half_tao_weight(
960+
) {
962961
new_test_ext(1).execute_with(|| {
963962
let netuid = NetUid::from(1);
964963
add_network(netuid, 1, 0);
@@ -1242,7 +1241,7 @@ fn test_get_root_children_drain() {
12421241
SubtensorModule::set_ck_burn(0);
12431242
// Set TAO weight to 1.
12441243
SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.
1245-
// Create keys.
1244+
// Create keys.
12461245
let cold_alice = U256::from(0);
12471246
let cold_bob = U256::from(1);
12481247
let alice = U256::from(2);
@@ -1404,7 +1403,7 @@ fn test_get_root_children_drain_half_proportion() {
14041403
SubtensorModule::set_ck_burn(0);
14051404
// Set TAO weight to 1.
14061405
SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.
1407-
// Create keys.
1406+
// Create keys.
14081407
let cold_alice = U256::from(0);
14091408
let cold_bob = U256::from(1);
14101409
let alice = U256::from(2);
@@ -1492,7 +1491,7 @@ fn test_get_root_children_drain_with_take() {
14921491
add_network(alpha, 1, 0);
14931492
// Set TAO weight to 1.
14941493
SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.
1495-
// Create keys.
1494+
// Create keys.
14961495
let cold_alice = U256::from(0);
14971496
let cold_bob = U256::from(1);
14981497
let alice = U256::from(2);

0 commit comments

Comments
 (0)