Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hansieodendaal committed Sep 20, 2024
1 parent 211969c commit ef4acf4
Showing 1 changed file with 152 additions and 45 deletions.
197 changes: 152 additions & 45 deletions base_layer/core/src/blocks/pre_mine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use std::{
convert::{TryFrom, TryInto},
iter::once,
};
use std::str::FromStr;
use rand::{prelude::SliceRandom, rngs::OsRng, thread_rng};
use tari_common::configuration::Network;
use tari_common_types::{
Expand Down Expand Up @@ -108,17 +107,22 @@ pub struct ReleaseCadence {
}

/// The upfront release of tokens
#[derive(Clone, Debug, Default, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ReleaseStrategy {
/// Proportional upfront release
#[default]
Proportional(ProportionalRelease),
/// Custom upfront release
Custom(Vec<CustomRelease>),
/// Cadence upfront release
Cadence(Vec<CadenceRelease>),
}

impl Default for ReleaseStrategy {
fn default() -> Self {
Self::Proportional(ProportionalRelease::default())
}
}

/// The upfront tokens to be released on a proportional basis
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct ProportionalRelease {
Expand Down Expand Up @@ -231,6 +235,70 @@ pub fn get_tokenomics_pre_mine_unlock_schedule(network: Network) -> UnlockSchedu
CadenceRelease{ value: 809_645.into(), taken_from_period: 12, maturity: 0 },
]
}),
ReleaseStrategy::Cadence( {
vec![
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 0, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 1, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 2, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 3, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 4, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 5, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 6, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 7, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 8, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 9, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 10, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 11, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 12, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 13, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 14, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 15, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 16, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 17, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 18, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 19, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 20, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 21, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 22, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 23, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 24, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 25, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 26, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 27, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 28, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 29, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 30, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 31, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 32, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 33, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 34, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 35, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 36, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 37, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 38, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 39, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 40, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 41, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 42, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 43, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 44, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 45, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 46, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 47, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 48, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 49, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 50, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 51, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 52, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 53, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 54, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 55, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 56, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 57, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 58, maturity: 0 },
CadenceRelease{ value: 6_300_000.into(), taken_from_period: 59, maturity: 0 },
]
}),
],
expected_payout_period_blocks: get_expected_payout_period_blocks(network),
}),
Expand Down Expand Up @@ -265,6 +333,11 @@ pub fn get_pre_mine_value(network: Network) -> Result<MicroMinotari, String> {
Ok(pre_mine_items.iter().map(|item| item.value).sum::<MicroMinotari>())
}

struct CadenceItem {
taken_from_period: usize,
value: Minotari,
}

/// Create a list of (token value, maturity in blocks) according to the amounts in the unlock schedule, based on the
/// apportionment and release cadence where 1 day equals 24 * 60 / 2 blocks.
pub fn create_pre_mine_output_values(schedule: UnlockSchedule) -> Result<Vec<PreMineItem>, String> {
Expand All @@ -280,52 +353,86 @@ pub fn create_pre_mine_output_values(schedule: UnlockSchedule) -> Result<Vec<Pre
&schedule.participants,
] {
if let Some(schedule) = apportionment.schedule.as_ref() {
let upfront_release = schedule.upfront_release.clone().unwrap_or_default();
if upfront_release.percentage > 100 {
return Err(format!(
"Upfront percentage must be less than or equal to 100 in {:?}",
apportionment
));
}
if apportionment
.tokens_amount.uT().as_u64()
.checked_mul(upfront_release.percentage)
.is_none()
{
return Err(format!("Minotari calculation overflow in {:?}", apportionment));
}
let mut tokens_value = apportionment.tokens_amount.uT().as_u64();
if upfront_release.percentage > 0 {
let upfront_tokens = tokens_value * upfront_release.percentage / 100;
tokens_value -= upfront_tokens;
let value_per_round = upfront_tokens / upfront_release.number_of_tokens;
let mut assigned_tokens = 0;
for _ in 0..upfront_release.number_of_tokens - 1 {
values_with_maturity.push(PreMineItem {
value: MicroMinotari::from(value_per_round),
maturity: 0,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
assigned_tokens += value_per_round;
let mut early_payout = Vec::new();
for item in &schedule.upfront_release {
match item {
ReleaseStrategy::Proportional(upfront_release) => {
if upfront_release.percentage > 100 {
return Err(format!(
"Upfront percentage must be less than or equal to 100 in {:?}",
apportionment
));
}
if apportionment
.tokens_amount.uT().as_u64()
.checked_mul(upfront_release.percentage)
.is_none()
{
return Err(format!("Minotari calculation overflow in {:?}", apportionment));
}
if upfront_release.percentage > 0 {
let upfront_tokens = tokens_value * upfront_release.percentage / 100;
tokens_value -= upfront_tokens;
let value_per_round = upfront_tokens / upfront_release.number_of_tokens;
let mut assigned_tokens = 0;
for _ in 0..upfront_release.number_of_tokens - 1 {
values_with_maturity.push(PreMineItem {
value: MicroMinotari::from(value_per_round),
maturity: 0,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
assigned_tokens += value_per_round;
}
values_with_maturity.push(PreMineItem {
value: MicroMinotari::from(upfront_tokens - assigned_tokens),
maturity: 0,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
}
}
ReleaseStrategy::Custom(upfront_release) => {
for release in upfront_release {
tokens_value -= release.value.uT().as_u64();
values_with_maturity.push(PreMineItem {
value: release.value.uT(),
maturity: release.maturity,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
}
}
ReleaseStrategy::Cadence(upfront_release) => {
for release in upfront_release {
early_payout.push(CadenceItem{taken_from_period: release.taken_from_period, value: release.value});
values_with_maturity.push(PreMineItem {
value: release.value.uT(),
maturity: release.maturity,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
}
}
}
values_with_maturity.push(PreMineItem {
value: MicroMinotari::from(upfront_tokens - assigned_tokens),
maturity: 0,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
}
for (value, maturity) in upfront_release.custom_upfront_tokens {
let utxo_value = value.uT().as_u64();
tokens_value -= utxo_value;
values_with_maturity.push(PreMineItem {
value: MicroMinotari::from(utxo_value),
maturity,
fail_safe_height: schedule.expected_payout_period_blocks,
beneficiary: apportionment.beneficiary.clone(),
});
// Sort 'early_payout' by 'taken_from_period' in ascending order, then add all the values for the same
// period and create a new vector 'early_payout' with the summed values, one value for each period
early_payout.sort_by_key(|x| x.taken_from_period);
let mut early_payout_sum = Vec::new();
let mut current_period = 0;
let mut current_value = 0;
for item in early_payout {
if item.taken_from_period == current_period {
current_value += item.value.uT().as_u64();
} else {
early_payout_sum.push(CadenceItem{taken_from_period: current_period, value: current_value.into()});
current_period = item.taken_from_period;
current_value = item.value.uT().as_u64();
}
}

let monthly_tokens = tokens_value / schedule.monthly_fraction_denominator;
let mut total_tokens = 0;
let mut maturity = 0;
Expand Down

0 comments on commit ef4acf4

Please sign in to comment.