#![cfg_attr(not(feature = "std"), no_std)]
use parity_scale_codec::{Decode, Encode, HasCompact, MaxEncodedLen};
use sp_runtime::{traits::AtLeast32Bit, RuntimeDebug};
use sp_std::cmp::{Eq, PartialEq};
use scale_info::TypeInfo;
#[derive(Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
pub struct ReleaseSchedule<BlockNumber, Balance: MaxEncodedLen + HasCompact> {
pub start: BlockNumber,
pub period: BlockNumber,
pub period_count: u32,
#[codec(compact)]
pub per_period: Balance,
}
impl<BlockNumber: AtLeast32Bit + Copy, Balance: AtLeast32Bit + MaxEncodedLen + Copy>
ReleaseSchedule<BlockNumber, Balance>
{
pub fn end(&self) -> Option<BlockNumber> {
self.period.checked_mul(&self.period_count.into())?.checked_add(&self.start)
}
pub fn total_amount(&self) -> Option<Balance> {
self.per_period.checked_mul(&self.period_count.into())
}
#[allow(clippy::expect_used)]
pub fn frozen_amount(&self, time: BlockNumber) -> Balance {
let full = time
.saturating_sub(self.start)
.checked_div(&self.period)
.expect("ensured non-zero period; qed");
let unrealized = self.period_count.saturating_sub(full.unique_saturated_into());
self.per_period
.checked_mul(&unrealized.into())
.expect("ensured non-overflow total amount; qed")
}
}