Skip to content

Commit 9b30818

Browse files
committed
only subsidize when sum of prices < 1
1 parent c0212a7 commit 9b30818

File tree

2 files changed

+67
-52
lines changed

2 files changed

+67
-52
lines changed

pallets/subtensor/src/coinbase/run_coinbase.rs

Lines changed: 59 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,23 @@ impl<T: Config> Pallet<T> {
3434
// 2. Get subnets to emit to and emissions
3535
let subnet_emissions = Self::get_subnet_block_emissions(&subnets, block_emission);
3636
let subnets_to_emit_to: Vec<NetUid> = subnet_emissions.keys().copied().collect();
37+
// --- 2. Get sum of moving alpha prices
38+
let mut acc_total_moving_prices = U96F32::saturating_from_num(0.0);
39+
// Only get price EMA for subnets that we emit to.
40+
for netuid_i in subnets_to_emit_to.iter() {
41+
acc_total_moving_prices =
42+
acc_total_moving_prices.saturating_add(Self::get_moving_alpha_price(*netuid_i));
43+
}
44+
let total_moving_prices = acc_total_moving_prices;
45+
log::debug!("total_moving_prices: {total_moving_prices:?}");
3746

3847
// --- 3. Get subnet terms (tao_in, alpha_in, and alpha_out)
3948
// Computation is described in detail in the dtao whitepaper.
4049
let mut tao_in: BTreeMap<NetUid, U96F32> = BTreeMap::new();
4150
let mut alpha_in: BTreeMap<NetUid, U96F32> = BTreeMap::new();
4251
let mut alpha_out: BTreeMap<NetUid, U96F32> = BTreeMap::new();
43-
let mut tao_to_stake = U96F32::saturating_from_num(0.0);
52+
let mut is_subsidized: BTreeMap<NetUid, bool> = BTreeMap::new();
53+
let mut subsidy_amount: BTreeMap<NetUid, U96F32> = BTreeMap::new();
4454

4555
// Only calculate for subnets that we are emitting to.
4656
for netuid_i in subnets_to_emit_to.iter() {
@@ -67,15 +77,37 @@ impl<T: Config> Pallet<T> {
6777

6878
let mut alpha_in_i: U96F32;
6979
let mut tao_in_i: U96F32;
70-
let min_alpha_emission = alpha_emission_i.min(block_emission);
71-
if default_alpha_in_i > min_alpha_emission {
80+
if default_alpha_in_i > alpha_emission_i
81+
|| total_moving_prices < U96F32::saturating_from_num(1.0)
82+
{
83+
let min_alpha_emission =
84+
default_alpha_in_i.min(alpha_emission_i).min(block_emission);
7285
alpha_in_i = min_alpha_emission;
7386
tao_in_i = alpha_in_i.saturating_mul(price_i);
74-
let difference_tao: U96F32 = default_tao_in_i.saturating_sub(tao_in_i);
75-
tao_to_stake = tao_to_stake.saturating_add(difference_tao);
87+
88+
if total_moving_prices < U96F32::saturating_from_num(1.0) {
89+
let difference_tao: U96F32 = default_tao_in_i.saturating_sub(tao_in_i);
90+
// Difference becomes buy.
91+
let buy_swap_result = Self::swap_tao_for_alpha(
92+
*netuid_i,
93+
tou64!(difference_tao).into(),
94+
T::SwapInterface::max_price(),
95+
true,
96+
);
97+
if let Ok(buy_swap_result_ok) = buy_swap_result {
98+
let bought_alpha = AlphaCurrency::from(buy_swap_result_ok.amount_paid_out);
99+
SubnetAlphaOut::<T>::mutate(*netuid_i, |total| {
100+
*total = total.saturating_sub(bought_alpha);
101+
});
102+
}
103+
is_subsidized.insert(*netuid_i, true);
104+
subsidy_amount.insert(*netuid_i, difference_tao);
105+
}
76106
} else {
77107
alpha_in_i = default_alpha_in_i;
78108
tao_in_i = default_tao_in_i;
109+
is_subsidized.insert(*netuid_i, false);
110+
subsidy_amount.insert(*netuid_i, asfloat!(0.0));
79111
}
80112
log::debug!("tao_in_i: {tao_in_i:?}");
81113
log::debug!("alpha_in_i: {alpha_in_i:?}");
@@ -96,29 +128,6 @@ impl<T: Config> Pallet<T> {
96128
alpha_out.insert(*netuid_i, alpha_out_i);
97129
}
98130

99-
let amount_per_subnet: U96F32 = tao_to_stake.safe_div_or(
100-
U96F32::saturating_from_num(subnets_to_emit_to.len()),
101-
U96F32::saturating_from_num(0.0),
102-
);
103-
104-
if amount_per_subnet > asfloat!(0.0) {
105-
for netuid_i in subnets_to_emit_to.iter() {
106-
let buy_swap_result = Self::swap_tao_for_alpha(
107-
*netuid_i,
108-
tou64!(amount_per_subnet).into(),
109-
T::SwapInterface::max_price().into(),
110-
true,
111-
);
112-
if let Ok(buy_swap_result_ok) = buy_swap_result {
113-
let bought_alpha = AlphaCurrency::from(buy_swap_result_ok.amount_paid_out);
114-
SubnetAlphaOut::<T>::mutate(*netuid_i, |total| {
115-
*total = total.saturating_sub(bought_alpha);
116-
});
117-
}
118-
}
119-
}
120-
121-
log::debug!("tao_to_stake: {tao_to_stake:?}");
122131
log::debug!("tao_in: {tao_in:?}");
123132
log::debug!("alpha_in: {alpha_in:?}");
124133
log::debug!("alpha_out: {alpha_out:?}");
@@ -141,20 +150,25 @@ impl<T: Config> Pallet<T> {
141150
SubnetAlphaOut::<T>::mutate(*netuid_i, |total| {
142151
*total = total.saturating_add(alpha_out_i);
143152
});
153+
144154
// Inject TAO in.
145155
let tao_in_i: TaoCurrency =
146156
tou64!(*tao_in.get(netuid_i).unwrap_or(&asfloat!(0))).into();
157+
let subsidy_tao: TaoCurrency =
158+
tou64!(*subsidy_amount.get(netuid_i).unwrap_or(&asfloat!(0))).into();
147159
SubnetTaoInEmission::<T>::insert(*netuid_i, TaoCurrency::from(tao_in_i));
160+
161+
// No need to add subsidy_tao here as it is captured from the swap result above.
148162
SubnetTAO::<T>::mutate(*netuid_i, |total| {
149163
*total = total.saturating_add(tao_in_i.into());
150164
});
151-
152165
TotalStake::<T>::mutate(|total| {
153166
*total = total.saturating_add(tao_in_i.into());
154167
});
168+
// Here we add subsidy tao as it is technically as issuance
155169
TotalIssuance::<T>::mutate(|total| {
156170
*total = total.saturating_add(tao_in_i.into());
157-
*total = total.saturating_add(tou64!(amount_per_subnet).into());
171+
*total = total.saturating_add(subsidy_tao.into());
158172
});
159173
// Adjust protocol liquidity based on new reserves
160174
T::SwapInterface::adjust_protocol_liquidity(*netuid_i, tao_in_i, alpha_in_i);
@@ -212,19 +226,21 @@ impl<T: Config> Pallet<T> {
212226
// Get pending alpha as original alpha_out - root_alpha.
213227
let pending_alpha: U96F32 = alpha_out_i.saturating_sub(root_alpha);
214228
log::debug!("pending_alpha: {pending_alpha:?}");
215-
// Sell root emission through the pool (do not pay fees)
216-
let swap_result = Self::swap_alpha_for_tao(
217-
*netuid_i,
218-
tou64!(root_alpha).into(),
219-
T::SwapInterface::min_price().into(),
220-
true,
221-
);
222-
if let Ok(ok_result) = swap_result {
223-
let root_tao: u64 = ok_result.amount_paid_out;
224-
// Accumulate root divs for subnet.
225-
PendingRootDivs::<T>::mutate(*netuid_i, |total| {
226-
*total = total.saturating_add(root_tao.into());
227-
});
229+
let subsidized: bool = *is_subsidized.get(netuid_i).unwrap_or(&false);
230+
if !subsidized {
231+
let swap_result = Self::swap_alpha_for_tao(
232+
*netuid_i,
233+
tou64!(root_alpha).into(),
234+
T::SwapInterface::min_price(),
235+
true,
236+
);
237+
if let Ok(ok_result) = swap_result {
238+
let root_tao = ok_result.amount_paid_out;
239+
// Accumulate root divs for subnet.
240+
PendingRootDivs::<T>::mutate(*netuid_i, |total| {
241+
*total = total.saturating_add(root_tao);
242+
});
243+
}
228244
}
229245
// Accumulate alpha emission in pending.
230246
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)