Skip to content

Commit

Permalink
make token amounts in RewardsController of Uint type
Browse files Browse the repository at this point in the history
  • Loading branch information
brentstone committed Oct 18, 2023
1 parent ce20a15 commit ab20766
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 92 deletions.
13 changes: 8 additions & 5 deletions apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,7 @@ where
.read_storage_key(&params_storage::get_pos_inflation_amount_key())
.expect("PoS inflation amount should exist in storage");
// Read from PoS storage
let total_tokens = self
let total_tokens: token::Amount = self
.read_storage_key(&token::minted_balance_key(
&staking_token_address(&self.wl_storage),
))
Expand All @@ -653,13 +653,13 @@ where

// Run rewards PD controller
let pos_controller = inflation::RewardsController {
locked_tokens: pos_locked_supply,
total_tokens,
total_native_tokens: total_tokens,
locked_tokens: pos_locked_supply.raw_amount(),
total_tokens: total_tokens.raw_amount(),
total_native_tokens: total_tokens.raw_amount(),
locked_ratio_target: pos_locked_ratio_target,
locked_ratio_last: pos_last_staked_ratio,
max_reward_rate: pos_max_inflation_rate,
last_inflation_amount: pos_last_inflation_amount,
last_inflation_amount: pos_last_inflation_amount.raw_amount(),
p_gain_nom: pos_p_gain_nom,
d_gain_nom: pos_d_gain_nom,
epochs_per_year,
Expand Down Expand Up @@ -689,6 +689,9 @@ where
// for the previous epoch
//
// TODO: think about changing the reward to Decimal
let inflation = token::Amount::from_uint(inflation, 0)
.expect("Should not fail Uint -> Amount conversion");

let mut reward_tokens_remaining = inflation;
let mut new_rewards_products: HashMap<Address, (Dec, Dec)> =
HashMap::new();
Expand Down
122 changes: 41 additions & 81 deletions core/src/ledger/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! funding.
use crate::types::dec::Dec;
use crate::types::token;
use crate::types::uint::Uint;

/// The domains of inflation
pub enum RewardsType {
Expand All @@ -19,26 +19,26 @@ pub enum RewardsType {
#[allow(missing_docs)]
pub struct ValsToUpdate {
pub locked_ratio: Dec,
pub inflation: token::Amount,
pub inflation: Uint,
}

/// PD controller used to dynamically adjust the rewards rates
#[derive(Debug, Clone)]
pub struct RewardsController {
/// Locked token amount in the relevant system
pub locked_tokens: token::Amount,
pub locked_tokens: Uint,
/// Total token supply
pub total_tokens: token::Amount,
pub total_tokens: Uint,
/// Total native token supply
pub total_native_tokens: token::Amount,
pub total_native_tokens: Uint,
/// PD target locked ratio
pub locked_ratio_target: Dec,
/// PD last locked ratio
pub locked_ratio_last: Dec,
/// Maximum reward rate
pub max_reward_rate: Dec,
/// Last inflation amount
pub last_inflation_amount: token::Amount,
pub last_inflation_amount: Uint,
/// Nominal proportional gain
pub p_gain_nom: Dec,
/// Nominal derivative gain
Expand All @@ -65,12 +65,12 @@ impl RewardsController {

// Token amounts must be expressed in terms of the raw amount (namnam)
// to properly run the PD controller
let locked = Dec::try_from(locked_tokens.raw_amount())
.expect("Should not fail to convert token Amount to Dec");
let total = Dec::try_from(total_tokens.raw_amount())
.expect("Should not fail to convert token Amount to Dec");
let total_native = Dec::try_from(total_native_tokens.raw_amount())
.expect("Should not fail to convert token Amount to Dec");
let locked = Dec::try_from(locked_tokens)
.expect("Should not fail to convert Uint to Dec");
let total = Dec::try_from(total_tokens)
.expect("Should not fail to convert Uint to Dec");
let total_native = Dec::try_from(total_native_tokens)
.expect("Should not fail to convert Uint to Dec");
let epochs_py: Dec = epochs_per_year.into();

let locked_ratio = locked / total;
Expand All @@ -82,29 +82,20 @@ impl RewardsController {
let delta_error = locked_ratio_last - locked_ratio;
let control_val = p_gain * error - d_gain * delta_error;

let last_inflation_amount =
Dec::try_from(last_inflation_amount.raw_amount())
.expect("Should not fail to convert token Amount to Dec");
let last_inflation_amount = Dec::try_from(last_inflation_amount)
.expect("Should not fail to convert Uint to Dec");
let new_inflation_amount_raw = last_inflation_amount + control_val;
let new_inflation_amount = if new_inflation_amount_raw.is_negative() {
token::Amount::zero()
Uint::zero()
} else {
token::Amount::from_uint(
new_inflation_amount_raw
.to_uint()
.expect("Should not fail to convert Dec to Uint"),
0,
)
.expect("Should not fail to convert Uint to Amount")
new_inflation_amount_raw
.to_uint()
.expect("Should not fail to convert Dec to Uint")
};

let max_inflation = token::Amount::from_uint(
max_inflation
.to_uint()
.expect("Should not fail to convert Dec to Uint"),
0,
)
.expect("Should not fail to convert Uint to Amount");
let max_inflation = max_inflation
.to_uint()
.expect("Should not fail to convert Dec to Uint");

let inflation = std::cmp::min(new_inflation_amount, max_inflation);
ValsToUpdate {
Expand All @@ -119,30 +110,17 @@ mod test {
use std::str::FromStr;

use super::*;
use crate::types::token::NATIVE_MAX_DECIMAL_PLACES;

#[test]
fn test_inflation_calc_up() {
let mut controller = RewardsController {
locked_tokens: token::Amount::from_uint(
2_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
total_tokens: token::Amount::from_uint(
4_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
total_native_tokens: token::Amount::from_uint(
4_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
locked_tokens: Uint::from(2_000_000_000),
total_tokens: Uint::from(4_000_000_000_u64),
total_native_tokens: Uint::from(4_000_000_000_u64),
locked_ratio_target: Dec::from_str("0.66666666").unwrap(),
locked_ratio_last: Dec::from_str("0.5").unwrap(),
max_reward_rate: Dec::from_str("0.1").unwrap(),
last_inflation_amount: token::Amount::zero(),
last_inflation_amount: Uint::zero(),
p_gain_nom: Dec::from_str("0.1").unwrap(),
d_gain_nom: Dec::from_str("0.1").unwrap(),
epochs_per_year: 365,
Expand All @@ -154,11 +132,10 @@ mod test {
inflation: inflation_0,
} = controller.clone().run();
println!(
"Round 0: Locked ratio: {locked_ratio_0}, inflation: {}",
inflation_0.to_string_native()
"Round 0: Locked ratio: {locked_ratio_0}, inflation: {inflation_0}"
);
assert_eq!(locked_ratio_0, Dec::from_str("0.5").unwrap());
assert_eq!(inflation_0, token::Amount::from_uint(18_264, 0).unwrap());
assert_eq!(inflation_0, Uint::from(18_264));

controller.locked_ratio_last = locked_ratio_0;
controller.last_inflation_amount = inflation_0;
Expand All @@ -170,13 +147,12 @@ mod test {
inflation: inflation_1,
} = controller.clone().run();
println!(
"Round 1: Locked ratio: {locked_ratio_1}, inflation: {}",
inflation_1.to_string_native()
"Round 1: Locked ratio: {locked_ratio_1}, inflation: {inflation_1}"
);
assert!(locked_ratio_1 > locked_ratio_0);
assert!(locked_ratio_1 > Dec::from_str("0.5").unwrap());
assert!(locked_ratio_1 < Dec::from_str("0.51").unwrap());
assert_eq!(inflation_1, token::Amount::from_uint(36_528, 0).unwrap());
assert_eq!(inflation_1, Uint::from(36_528));

controller.locked_ratio_last = locked_ratio_1;
controller.last_inflation_amount = inflation_1;
Expand All @@ -188,37 +164,24 @@ mod test {
inflation: inflation_2,
} = controller.run();
println!(
"Round 2: Locked ratio: {locked_ratio_2}, inflation: {}",
inflation_2.to_string_native()
"Round 2: Locked ratio: {locked_ratio_2}, inflation: {inflation_2}",
);
assert!(locked_ratio_2 > locked_ratio_1);
assert!(locked_ratio_2 > Dec::from_str("0.5").unwrap());
assert!(locked_ratio_2 < Dec::from_str("0.51").unwrap());
assert_eq!(inflation_2, token::Amount::from_uint(54_792, 0).unwrap());
assert_eq!(inflation_2, Uint::from(54_792));
}

#[test]
fn test_inflation_calc_down() {
let mut controller = RewardsController {
locked_tokens: token::Amount::from_uint(
900,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
total_tokens: token::Amount::from_uint(
1_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
total_native_tokens: token::Amount::from_uint(
1_000,
NATIVE_MAX_DECIMAL_PLACES,
)
.unwrap(),
locked_tokens: Uint::from(900_000_000),
total_tokens: Uint::from(1_000_000_000),
total_native_tokens: Uint::from(1_000_000_000),
locked_ratio_target: Dec::from_str("0.66666666").unwrap(),
locked_ratio_last: Dec::from_str("0.9").unwrap(),
max_reward_rate: Dec::from_str("0.1").unwrap(),
last_inflation_amount: token::Amount::from_uint(10_000, 0).unwrap(),
last_inflation_amount: Uint::from(10_000),
p_gain_nom: Dec::from_str("0.1").unwrap(),
d_gain_nom: Dec::from_str("0.1").unwrap(),
epochs_per_year: 365,
Expand All @@ -230,11 +193,10 @@ mod test {
inflation: inflation_0,
} = controller.clone().run();
println!(
"Round 0: Locked ratio: {locked_ratio_0}, inflation: {}",
inflation_0.to_string_native()
"Round 0: Locked ratio: {locked_ratio_0}, inflation: {inflation_0}",
);
assert_eq!(locked_ratio_0, Dec::from_str("0.9").unwrap());
assert_eq!(inflation_0, token::Amount::from_uint(3_607, 0).unwrap());
assert_eq!(inflation_0, Uint::from(3_607));

controller.locked_ratio_last = locked_ratio_0;
controller.last_inflation_amount = inflation_0;
Expand All @@ -246,13 +208,12 @@ mod test {
inflation: inflation_1,
} = controller.clone().run();
println!(
"Round 1: Locked ratio: {locked_ratio_1}, inflation: {}",
inflation_1.to_string_native()
"Round 1: Locked ratio: {locked_ratio_1}, inflation: {inflation_1}",
);
assert!(locked_ratio_1 > locked_ratio_0);
assert!(locked_ratio_1 > Dec::from_str("0.9").unwrap());
assert!(locked_ratio_1 < Dec::from_str("0.91").unwrap());
assert_eq!(inflation_1, token::Amount::zero());
assert_eq!(inflation_1, Uint::zero());

controller.locked_ratio_last = locked_ratio_1;
controller.last_inflation_amount = inflation_1;
Expand All @@ -264,10 +225,9 @@ mod test {
inflation: inflation_2,
} = controller.run();
println!(
"Round 2: Locked ratio: {locked_ratio_2}, inflation: {}",
inflation_2.to_string_native()
"Round 2: Locked ratio: {locked_ratio_2}, inflation: {inflation_2}",
);
assert_eq!(locked_ratio_2, locked_ratio_1);
assert_eq!(inflation_2, token::Amount::zero());
assert_eq!(inflation_2, Uint::zero());
}
}
11 changes: 5 additions & 6 deletions core/src/ledger/storage/masp_conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ where

// Creating the PD controller for handing out tokens
let controller = RewardsController {
locked_tokens: total_token_in_masp,
total_tokens,
total_native_tokens,
locked_tokens: total_token_in_masp.raw_amount(),
total_tokens: total_tokens.raw_amount(),
total_native_tokens: total_native_tokens.raw_amount(),
locked_ratio_target: locked_target_ratio,
locked_ratio_last: last_locked_ratio,
max_reward_rate,
last_inflation_amount: last_inflation,
last_inflation_amount: last_inflation.raw_amount(),
p_gain_nom: kp_gain_nom,
d_gain_nom: kd_gain_nom,
epochs_per_year,
Expand All @@ -127,8 +127,7 @@ where
0u128
} else {
crate::types::uint::Uint::try_into(
(inflation.raw_amount()
* crate::types::uint::Uint::from(precision))
(inflation * crate::types::uint::Uint::from(precision))
/ total_token_in_masp.raw_amount(),
)
.unwrap()
Expand Down

0 comments on commit ab20766

Please sign in to comment.