@@ -10,25 +10,19 @@ use masp_primitives::sapling::Node;
1010
1111use crate :: ledger:: inflation:: { RewardsController , ValsToUpdate } ;
1212use crate :: ledger:: parameters;
13+ use crate :: ledger:: storage_api:: token:: read_denom;
1314use crate :: ledger:: storage_api:: { StorageRead , StorageWrite } ;
1415use crate :: types:: address:: Address ;
1516use crate :: types:: dec:: Dec ;
1617use crate :: types:: storage:: Epoch ;
1718use crate :: types:: token:: MaspDenom ;
1819use crate :: types:: { address, token} ;
1920
20- /// Inflation is implicitly denominated by this value. The lower this figure,
21- /// the less precise inflation computations are. The higher this figure, the
22- /// larger the fixed-width types that are required to carry out inflation
23- /// computations. This value should be fixed constant for each asset type - here
24- /// we have simplified it and made it constant across asset types.
25- const PRECISION : u64 = 100 ;
26-
2721/// A representation of the conversion state
2822#[ derive( Debug , Default , BorshSerialize , BorshDeserialize ) ]
2923pub struct ConversionState {
3024 /// The last amount of the native token distributed
31- pub normed_inflation : Option < u32 > ,
25+ pub normed_inflation : Option < u128 > ,
3226 /// The tree currently containing all the conversions
3327 pub tree : FrozenCommitmentTree < Node > ,
3428 /// Map assets to their latest conversion and position in Merkle tree
@@ -44,11 +38,20 @@ pub struct ConversionState {
4438pub fn calculate_masp_rewards < D , H > (
4539 wl_storage : & mut super :: WlStorage < D , H > ,
4640 addr : & Address ,
47- ) -> crate :: ledger:: storage_api:: Result < ( u32 , u32 ) >
41+ ) -> crate :: ledger:: storage_api:: Result < ( u128 , u128 ) >
4842where
4943 D : ' static + super :: DB + for < ' iter > super :: DBIter < ' iter > ,
5044 H : ' static + super :: StorageHasher ,
5145{
46+ let denomination = read_denom ( wl_storage, addr) . unwrap ( ) . unwrap ( ) ;
47+ // Inflation is implicitly denominated by this value. The lower this
48+ // figure, the less precise inflation computations are. This is especially
49+ // problematic when inflation is coming from a token with much higher
50+ // denomination than the native token. The higher this figure, the higher
51+ // the threshold of holdings required in order to receive non-zero rewards.
52+ // This value should be fixed constant for each asset type.
53+ let precision = 10u128 . pow ( std:: cmp:: max ( u32:: from ( denomination. 0 ) , 3 ) - 3 ) ;
54+
5255 let masp_addr = address:: masp ( ) ;
5356 // Query the storage for information
5457
@@ -69,38 +72,33 @@ where
6972
7073 let epochs_per_year: u64 = wl_storage
7174 . read ( & parameters:: storage:: get_epochs_per_year_key ( ) ) ?
72- . expect ( "" ) ;
75+ . expect ( "epochs per year should properly decode " ) ;
7376
7477 //// Values from the last epoch
7578 let last_inflation: token:: Amount = wl_storage
76- . read ( & token:: masp_last_inflation ( addr) )
77- . expect ( "failure to read last inflation" )
78- . expect ( "" ) ;
79+ . read ( & token:: masp_last_inflation_key ( addr) ) ?
80+ . expect ( "failure to read last inflation" ) ;
7981
8082 let last_locked_ratio: Dec = wl_storage
81- . read ( & token:: masp_last_locked_ratio ( addr) )
82- . expect ( "failure to read last inflation" )
83- . expect ( "" ) ;
83+ . read ( & token:: masp_last_locked_ratio_key ( addr) ) ?
84+ . expect ( "failure to read last inflation" ) ;
8485
8586 //// Parameters for each token
8687 let max_reward_rate: Dec = wl_storage
87- . read ( & token:: masp_max_reward_rate ( addr) )
88- . expect ( "max reward should properly decode" )
89- . expect ( "" ) ;
88+ . read ( & token:: masp_max_reward_rate_key ( addr) ) ?
89+ . expect ( "max reward should properly decode" ) ;
9090
9191 let kp_gain_nom: Dec = wl_storage
92- . read ( & token:: masp_kp_gain ( addr) )
93- . expect ( "kp_gain_nom reward should properly decode" )
94- . expect ( "" ) ;
92+ . read ( & token:: masp_kp_gain_key ( addr) ) ?
93+ . expect ( "kp_gain_nom reward should properly decode" ) ;
9594
9695 let kd_gain_nom: Dec = wl_storage
97- . read ( & token:: masp_kd_gain ( addr) )
98- . expect ( "kd_gain_nom reward should properly decode" )
99- . expect ( "" ) ;
96+ . read ( & token:: masp_kd_gain_key ( addr) ) ?
97+ . expect ( "kd_gain_nom reward should properly decode" ) ;
10098
10199 let locked_target_ratio: Dec = wl_storage
102- . read ( & token:: masp_locked_ratio_target ( addr) ) ?
103- . expect ( "" ) ;
100+ . read ( & token:: masp_locked_ratio_target_key ( addr) ) ?
101+ . expect ( "locked ratio target should properly decode " ) ;
104102
105103 // Creating the PD controller for handing out tokens
106104 let controller = RewardsController {
@@ -126,10 +124,11 @@ where
126124 // Since we must put the notes in a compatible format with the
127125 // note format, we must make the inflation amount discrete.
128126 let noterized_inflation = if total_token_in_masp. is_zero ( ) {
129- 0u32
127+ 0u128
130128 } else {
131129 crate :: types:: uint:: Uint :: try_into (
132- ( inflation. raw_amount ( ) * PRECISION )
130+ ( inflation. raw_amount ( )
131+ * crate :: types:: uint:: Uint :: from ( precision) )
133132 / total_token_in_masp. raw_amount ( ) ,
134133 )
135134 . unwrap ( )
@@ -163,24 +162,21 @@ where
163162 // otherwise we will have an inaccurate view of inflation
164163 wl_storage
165164 . write (
166- & token:: masp_last_inflation ( addr) ,
167- ( total_token_in_masp / PRECISION ) * u64:: from ( noterized_inflation) ,
165+ & token:: masp_last_inflation_key ( addr) ,
166+ token:: Amount :: from_uint (
167+ ( total_token_in_masp. raw_amount ( ) / precision)
168+ * crate :: types:: uint:: Uint :: from ( noterized_inflation) ,
169+ 0 ,
170+ )
171+ . unwrap ( ) ,
168172 )
169173 . expect ( "unable to encode new inflation rate (Decimal)" ) ;
170174
171175 wl_storage
172- . write ( & token:: masp_last_locked_ratio ( addr) , locked_ratio)
176+ . write ( & token:: masp_last_locked_ratio_key ( addr) , locked_ratio)
173177 . expect ( "unable to encode new locked ratio (Decimal)" ) ;
174178
175- // to make it conform with the expected output, we need to
176- // move it to a ratio of x/100 to match the masp_rewards
177- // function This may be unneeded, as we could describe it as a
178- // ratio of x/1
179-
180- Ok ( (
181- noterized_inflation,
182- PRECISION . try_into ( ) . expect ( "inflation precision too large" ) ,
183- ) )
179+ Ok ( ( noterized_inflation, precision) )
184180}
185181
186182// This is only enabled when "wasm-runtime" is on, because we're using rayon
@@ -196,7 +192,7 @@ where
196192 use std:: cmp:: Ordering ;
197193
198194 use masp_primitives:: ff:: PrimeField ;
199- use masp_primitives:: transaction:: components:: I32Sum as MaspAmount ;
195+ use masp_primitives:: transaction:: components:: I128Sum as MaspAmount ;
200196 use rayon:: iter:: {
201197 IndexedParallelIterator , IntoParallelIterator , ParallelIterator ,
202198 } ;
@@ -288,12 +284,12 @@ where
288284 ( addr. clone ( ) , denom) ,
289285 ( MaspAmount :: from_pair (
290286 old_asset,
291- -( * normed_inflation as i32 ) ,
287+ -( * normed_inflation as i128 ) ,
292288 )
293289 . unwrap ( )
294290 + MaspAmount :: from_pair (
295291 new_asset,
296- new_normed_inflation as i32 ,
292+ new_normed_inflation as i128 ,
297293 )
298294 . unwrap ( ) )
299295 . into ( ) ,
@@ -320,13 +316,13 @@ where
320316 // intermediate tokens cancel/ telescope out
321317 current_convs. insert (
322318 ( addr. clone ( ) , denom) ,
323- ( MaspAmount :: from_pair ( old_asset, -( reward. 1 as i32 ) )
319+ ( MaspAmount :: from_pair ( old_asset, -( reward. 1 as i128 ) )
324320 . unwrap ( )
325- + MaspAmount :: from_pair ( new_asset, reward. 1 as i32 )
321+ + MaspAmount :: from_pair ( new_asset, reward. 1 as i128 )
326322 . unwrap ( )
327323 + MaspAmount :: from_pair (
328324 reward_assets[ denom as usize ] ,
329- real_reward as i32 ,
325+ real_reward as i128 ,
330326 )
331327 . unwrap ( ) )
332328 . into ( ) ,
0 commit comments