@@ -34,13 +34,15 @@ 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+ let root_sell_flag = Self :: get_network_root_sell_flag ( & subnets_to_emit_to) ;
3738
3839 // --- 3. Get subnet terms (tao_in, alpha_in, and alpha_out)
3940 // Computation is described in detail in the dtao whitepaper.
4041 let mut tao_in: BTreeMap < NetUid , U96F32 > = BTreeMap :: new ( ) ;
4142 let mut alpha_in: BTreeMap < NetUid , U96F32 > = BTreeMap :: new ( ) ;
4243 let mut alpha_out: BTreeMap < NetUid , U96F32 > = BTreeMap :: new ( ) ;
43- let mut is_subsidized: BTreeMap < NetUid , bool > = BTreeMap :: new ( ) ;
44+ let mut excess_tao: BTreeMap < NetUid , U96F32 > = BTreeMap :: new ( ) ;
45+
4446 // Only calculate for subnets that we are emitting to.
4547 for netuid_i in subnets_to_emit_to. iter ( ) {
4648 // Get subnet price.
@@ -52,6 +54,9 @@ impl<T: Config> Pallet<T> {
5254 . copied ( )
5355 . unwrap_or ( asfloat ! ( 0 ) ) ;
5456 log:: debug!( "default_tao_in_i: {default_tao_in_i:?}" ) ;
57+ let default_alpha_in_i: U96F32 =
58+ default_tao_in_i. safe_div_or ( price_i, U96F32 :: saturating_from_num ( 0.0 ) ) ;
59+ log:: debug!( "default_alpha_in_i: {default_alpha_in_i:?}" ) ;
5560 // Get alpha_emission total
5661 let alpha_emission_i: U96F32 = asfloat ! (
5762 Self :: get_block_emission_for_issuance( Self :: get_alpha_issuance( * netuid_i) . into( ) )
@@ -62,32 +67,16 @@ impl<T: Config> Pallet<T> {
6267 // Get initial alpha_in
6368 let mut alpha_in_i: U96F32 ;
6469 let mut tao_in_i: U96F32 ;
65- let tao_in_ratio: U96F32 = default_tao_in_i. safe_div_or (
66- U96F32 :: saturating_from_num ( block_emission) ,
67- U96F32 :: saturating_from_num ( 0.0 ) ,
68- ) ;
69- if price_i < tao_in_ratio {
70- tao_in_i = price_i. saturating_mul ( U96F32 :: saturating_from_num ( block_emission) ) ;
71- alpha_in_i = block_emission;
70+
71+ if default_alpha_in_i > alpha_emission_i {
72+ alpha_in_i = alpha_emission_i;
73+ tao_in_i = alpha_in_i. saturating_mul ( price_i) ;
7274 let difference_tao: U96F32 = default_tao_in_i. saturating_sub ( tao_in_i) ;
73- // Difference becomes buy.
74- let buy_swap_result = Self :: swap_tao_for_alpha (
75- * netuid_i,
76- tou64 ! ( difference_tao) . into ( ) ,
77- T :: SwapInterface :: max_price ( ) ,
78- true ,
79- ) ;
80- if let Ok ( buy_swap_result_ok) = buy_swap_result {
81- let bought_alpha = AlphaCurrency :: from ( buy_swap_result_ok. amount_paid_out ) ;
82- SubnetAlphaOut :: < T > :: mutate ( * netuid_i, |total| {
83- * total = total. saturating_sub ( bought_alpha) ;
84- } ) ;
85- }
86- is_subsidized. insert ( * netuid_i, true ) ;
75+ excess_tao. insert ( * netuid_i, difference_tao) ;
8776 } else {
8877 tao_in_i = default_tao_in_i;
89- alpha_in_i = tao_in_i . safe_div_or ( price_i , alpha_emission_i ) ;
90- is_subsidized . insert ( * netuid_i, false ) ;
78+ alpha_in_i = default_alpha_in_i ;
79+ excess_tao . insert ( * netuid_i, U96F32 :: from_num ( 0.0 ) ) ;
9180 }
9281 log:: debug!( "alpha_in_i: {alpha_in_i:?}" ) ;
9382
@@ -109,10 +98,34 @@ impl<T: Config> Pallet<T> {
10998 log:: debug!( "tao_in: {tao_in:?}" ) ;
11099 log:: debug!( "alpha_in: {alpha_in:?}" ) ;
111100 log:: debug!( "alpha_out: {alpha_out:?}" ) ;
101+ log:: debug!( "excess_tao: {excess_tao:?}" ) ;
102+ log:: debug!( "root_sell_flag: {root_sell_flag:?}" ) ;
103+
104+ // --- 4. Inject and buy Alpha with any excess TAO.
105+ for netuid_i in subnets_to_emit_to. iter ( ) {
106+ let tao_in_i: TaoCurrency =
107+ tou64 ! ( * tao_in. get( netuid_i) . unwrap_or( & asfloat!( 0 ) ) ) . into ( ) ;
108+ let alpha_in_i: AlphaCurrency =
109+ AlphaCurrency :: from ( tou64 ! ( * alpha_in. get( netuid_i) . unwrap_or( & asfloat!( 0 ) ) ) ) ;
110+ let difference_tao: U96F32 = * excess_tao. get ( netuid_i) . unwrap_or ( & asfloat ! ( 0 ) ) ;
111+
112+ T :: SwapInterface :: adjust_protocol_liquidity ( * netuid_i, tao_in_i, alpha_in_i) ;
113+
114+ if difference_tao > asfloat ! ( 0 ) {
115+ let buy_swap_result = Self :: swap_tao_for_alpha (
116+ * netuid_i,
117+ tou64 ! ( difference_tao) . into ( ) ,
118+ T :: SwapInterface :: max_price ( ) ,
119+ true ,
120+ ) ;
121+ if let Ok ( buy_swap_result_ok) = buy_swap_result {
122+ let bought_alpha = AlphaCurrency :: from ( buy_swap_result_ok. amount_paid_out ) ;
123+ Self :: recycle_subnet_alpha ( * netuid_i, bought_alpha) ;
124+ }
125+ }
126+ }
112127
113- // --- 4. Injection.
114- // Actually perform the injection of alpha_in, alpha_out and tao_in into the subnet pool.
115- // This operation changes the pool liquidity each block.
128+ // --- 5. Update counters
116129 for netuid_i in subnets_to_emit_to. iter ( ) {
117130 // Inject Alpha in.
118131 let alpha_in_i =
@@ -138,14 +151,15 @@ impl<T: Config> Pallet<T> {
138151 TotalStake :: < T > :: mutate ( |total| {
139152 * total = total. saturating_add ( tao_in_i. into ( ) ) ;
140153 } ) ;
154+
155+ let difference_tao: U96F32 = * excess_tao. get ( netuid_i) . unwrap_or ( & asfloat ! ( 0 ) ) ;
141156 TotalIssuance :: < T > :: mutate ( |total| {
142157 * total = total. saturating_add ( tao_in_i. into ( ) ) ;
158+ * total = total. saturating_add ( tou64 ! ( difference_tao) . into ( ) ) ;
143159 } ) ;
144- // Adjust protocol liquidity based on new reserves
145- T :: SwapInterface :: adjust_protocol_liquidity ( * netuid_i, tao_in_i, alpha_in_i) ;
146160 }
147161
148- // --- 5 . Compute owner cuts and remove them from alpha_out remaining.
162+ // --- 6 . Compute owner cuts and remove them from alpha_out remaining.
149163 // Remove owner cuts here so that we can properly seperate root dividends in the next step.
150164 // Owner cuts are accumulated and then fed to the drain at the end of this func.
151165 let cut_percent: U96F32 = Self :: get_float_subnet_owner_cut ( ) ;
@@ -174,51 +188,55 @@ impl<T: Config> Pallet<T> {
174188 let tao_weight: U96F32 = root_tao. saturating_mul ( Self :: get_tao_weight ( ) ) ;
175189 log:: debug!( "tao_weight: {tao_weight:?}" ) ;
176190
177- // --- 6 . Seperate out root dividends in alpha and keep them.
191+ // --- 7 . Seperate out root dividends in alpha and keep them.
178192 // Then accumulate those dividends for later.
179193 for netuid_i in subnets_to_emit_to. iter ( ) {
180194 // Get remaining alpha out.
181195 let alpha_out_i: U96F32 = * alpha_out. get ( netuid_i) . unwrap_or ( & asfloat ! ( 0.0 ) ) ;
182196 log:: debug!( "alpha_out_i: {alpha_out_i:?}" ) ;
183- // Get total ALPHA on subnet.
184- let alpha_issuance: U96F32 = asfloat ! ( Self :: get_alpha_issuance( * netuid_i) ) ;
185- log:: debug!( "alpha_issuance: {alpha_issuance:?}" ) ;
186- // Get root proportional dividends.
187- let root_proportion: U96F32 = tao_weight
188- . checked_div ( tao_weight. saturating_add ( alpha_issuance) )
189- . unwrap_or ( asfloat ! ( 0.0 ) ) ;
190- log:: debug!( "root_proportion: {root_proportion:?}" ) ;
197+
191198 // Get root proportion of alpha_out dividends.
192- let root_alpha: U96F32 = root_proportion
193- . saturating_mul ( alpha_out_i) // Total alpha emission per block remaining.
194- . saturating_mul ( asfloat ! ( 0.5 ) ) ; // 50% to validators.
199+ let mut root_alpha: U96F32 = asfloat ! ( 0.0 ) ;
200+ if root_sell_flag {
201+ // Get ALPHA issuance.
202+ let alpha_issuance: U96F32 = asfloat ! ( Self :: get_alpha_issuance( * netuid_i) ) ;
203+ log:: debug!( "alpha_issuance: {alpha_issuance:?}" ) ;
204+
205+ // Get root proportional dividends.
206+ let root_proportion: U96F32 = tao_weight
207+ . checked_div ( tao_weight. saturating_add ( alpha_issuance) )
208+ . unwrap_or ( asfloat ! ( 0.0 ) ) ;
209+ log:: debug!( "root_proportion: {root_proportion:?}" ) ;
210+
211+ // Get root alpha from root prop.
212+ root_alpha = root_proportion
213+ . saturating_mul ( alpha_out_i) // Total alpha emission per block remaining.
214+ . saturating_mul ( asfloat ! ( 0.5 ) ) ; // 50% to validators.
215+ PendingRootAlphaDivs :: < T > :: mutate ( * netuid_i, |total| {
216+ * total = total. saturating_add ( tou64 ! ( root_alpha) . into ( ) ) ;
217+ } ) ;
218+ }
195219 // Remove root alpha from alpha_out.
196220 log:: debug!( "root_alpha: {root_alpha:?}" ) ;
221+
197222 // Get pending alpha as original alpha_out - root_alpha.
198223 let pending_alpha: U96F32 = alpha_out_i. saturating_sub ( root_alpha) ;
199224 log:: debug!( "pending_alpha: {pending_alpha:?}" ) ;
200225
201- let subsidized: bool = * is_subsidized. get ( netuid_i) . unwrap_or ( & false ) ;
202- if !subsidized {
203- PendingRootAlphaDivs :: < T > :: mutate ( * netuid_i, |total| {
204- * total = total. saturating_add ( tou64 ! ( root_alpha) . into ( ) ) ;
205- } ) ;
206- }
207-
208226 // Accumulate alpha emission in pending.
209227 PendingEmission :: < T > :: mutate ( * netuid_i, |total| {
210228 * total = total. saturating_add ( tou64 ! ( pending_alpha) . into ( ) ) ;
211229 } ) ;
212230 }
213231
214- // --- 7 . Update moving prices after using them in the emission calculation.
232+ // --- 8 . Update moving prices after using them in the emission calculation.
215233 // Only update price EMA for subnets that we emit to.
216234 for netuid_i in subnets_to_emit_to. iter ( ) {
217235 // Update moving prices after using them above.
218236 Self :: update_moving_price ( * netuid_i) ;
219237 }
220238
221- // --- 8 . Drain pending emission through the subnet based on tempo.
239+ // --- 9 . Drain pending emission through the subnet based on tempo.
222240 // Run the epoch for *all* subnets, even if we don't emit anything.
223241 for & netuid in subnets. iter ( ) {
224242 // Reveal matured weights.
@@ -245,15 +263,26 @@ impl<T: Config> Pallet<T> {
245263 let owner_cut = PendingOwnerCut :: < T > :: get ( netuid) ;
246264 PendingOwnerCut :: < T > :: insert ( netuid, AlphaCurrency :: ZERO ) ;
247265
248- // Drain pending root alpha divs, alpha emission, and owner cut .
249- Self :: drain_pending_emission ( netuid, pending_alpha, pending_root_alpha, owner_cut) ;
266+ // Distribute the emission.
267+ Self :: distribute_emission ( netuid, pending_alpha, pending_root_alpha, owner_cut) ;
250268 } else {
251269 // Increment
252270 BlocksSinceLastStep :: < T > :: mutate ( netuid, |total| * total = total. saturating_add ( 1 ) ) ;
253271 }
254272 }
255273 }
256274
275+ pub fn get_network_root_sell_flag ( subnets_to_emit_to : & [ NetUid ] ) -> bool {
276+ let total_ema_price: U96F32 = subnets_to_emit_to
277+ . iter ( )
278+ . map ( |netuid| Self :: get_moving_alpha_price ( * netuid) )
279+ . sum ( ) ;
280+
281+ // If the total EMA price is less than or equal to 1
282+ // then we WILL NOT root sell.
283+ total_ema_price > U96F32 :: saturating_from_num ( 1 )
284+ }
285+
257286 pub fn calculate_dividends_and_incentives (
258287 netuid : NetUid ,
259288 hotkey_emission : Vec < ( T :: AccountId , AlphaCurrency , AlphaCurrency ) > ,
@@ -482,6 +511,7 @@ impl<T: Config> Pallet<T> {
482511 let destination = maybe_dest. clone ( ) . unwrap_or ( hotkey. clone ( ) ) ;
483512
484513 if let Some ( dest) = maybe_dest {
514+ log:: debug!( "incentives: auto staking {incentive:?} to {dest:?}" ) ;
485515 Self :: deposit_event ( Event :: < T > :: AutoStakeAdded {
486516 netuid,
487517 destination : dest,
@@ -490,6 +520,7 @@ impl<T: Config> Pallet<T> {
490520 incentive,
491521 } ) ;
492522 }
523+
493524 Self :: increase_stake_for_hotkey_and_coldkey_on_subnet (
494525 & destination,
495526 & owner,
@@ -600,7 +631,7 @@ impl<T: Config> Pallet<T> {
600631 ( incentives, ( alpha_dividends, root_alpha_dividends) )
601632 }
602633
603- pub fn drain_pending_emission (
634+ pub fn distribute_emission (
604635 netuid : NetUid ,
605636 pending_alpha : AlphaCurrency ,
606637 pending_root_alpha : AlphaCurrency ,
@@ -611,10 +642,11 @@ impl<T: Config> Pallet<T> {
611642 ) ;
612643
613644 let tao_weight = Self :: get_tao_weight ( ) ;
645+ let total_alpha = pending_alpha. saturating_add ( pending_root_alpha) ;
614646
615647 // Run the epoch.
616648 let hotkey_emission: Vec < ( T :: AccountId , AlphaCurrency , AlphaCurrency ) > =
617- Self :: epoch_with_mechanisms ( netuid, pending_alpha . saturating_add ( pending_root_alpha ) ) ;
649+ Self :: epoch_with_mechanisms ( netuid, total_alpha ) ;
618650 log:: debug!( "hotkey_emission: {hotkey_emission:?}" ) ;
619651
620652 // Compute the pending validator alpha.
@@ -630,8 +662,7 @@ impl<T: Config> Pallet<T> {
630662 log:: debug!( "incentive_sum: {incentive_sum:?}" ) ;
631663
632664 let pending_validator_alpha = if !incentive_sum. is_zero ( ) {
633- pending_alpha
634- . saturating_add ( pending_root_alpha)
665+ total_alpha
635666 . saturating_div ( 2 . into ( ) )
636667 . saturating_sub ( pending_root_alpha)
637668 } else {
0 commit comments