mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-22 15:01:04 +00:00
bc53b9a03a
* Change copyright year to 2023 from 2022 * Fix incorrect update of copyright year * Remove years from copy right header * Fix remaining files * Fix typo in a header and remove update-copyright.sh
115 lines
3.8 KiB
Rust
115 lines
3.8 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! Module to enforce private fields on `VestingInfo`.
|
|
|
|
use super::*;
|
|
|
|
/// Struct to encode the vesting schedule of an individual account.
|
|
#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, MaxEncodedLen, TypeInfo)]
|
|
pub struct VestingInfo<Balance, BlockNumber> {
|
|
/// Locked amount at genesis.
|
|
locked: Balance,
|
|
/// Amount that gets unlocked every block after `starting_block`.
|
|
per_block: Balance,
|
|
/// Starting block for unlocking(vesting).
|
|
starting_block: BlockNumber,
|
|
}
|
|
|
|
impl<Balance, BlockNumber> VestingInfo<Balance, BlockNumber>
|
|
where
|
|
Balance: AtLeast32BitUnsigned + Copy,
|
|
BlockNumber: AtLeast32BitUnsigned + Copy + Bounded,
|
|
{
|
|
/// Instantiate a new `VestingInfo`.
|
|
pub fn new(
|
|
locked: Balance,
|
|
per_block: Balance,
|
|
starting_block: BlockNumber,
|
|
) -> VestingInfo<Balance, BlockNumber> {
|
|
VestingInfo { locked, per_block, starting_block }
|
|
}
|
|
|
|
/// Validate parameters for `VestingInfo`. Note that this does not check
|
|
/// against `MinVestedTransfer`.
|
|
pub fn is_valid(&self) -> bool {
|
|
!self.locked.is_zero() && !self.raw_per_block().is_zero()
|
|
}
|
|
|
|
/// Locked amount at schedule creation.
|
|
pub fn locked(&self) -> Balance {
|
|
self.locked
|
|
}
|
|
|
|
/// Amount that gets unlocked every block after `starting_block`. Corrects for `per_block` of 0.
|
|
/// We don't let `per_block` be less than 1, or else the vesting will never end.
|
|
/// This should be used whenever accessing `per_block` unless explicitly checking for 0 values.
|
|
pub fn per_block(&self) -> Balance {
|
|
self.per_block.max(One::one())
|
|
}
|
|
|
|
/// Get the unmodified `per_block`. Generally should not be used, but is useful for
|
|
/// validating `per_block`.
|
|
pub(crate) fn raw_per_block(&self) -> Balance {
|
|
self.per_block
|
|
}
|
|
|
|
/// Starting block for unlocking(vesting).
|
|
pub fn starting_block(&self) -> BlockNumber {
|
|
self.starting_block
|
|
}
|
|
|
|
/// Amount locked at block `n`.
|
|
pub fn locked_at<BlockNumberToBalance: Convert<BlockNumber, Balance>>(
|
|
&self,
|
|
n: BlockNumber,
|
|
) -> Balance {
|
|
// Number of blocks that count toward vesting;
|
|
// saturating to 0 when n < starting_block.
|
|
let vested_block_count = n.saturating_sub(self.starting_block);
|
|
let vested_block_count = BlockNumberToBalance::convert(vested_block_count);
|
|
// Return amount that is still locked in vesting.
|
|
vested_block_count
|
|
.checked_mul(&self.per_block()) // `per_block` accessor guarantees at least 1.
|
|
.map(|to_unlock| self.locked.saturating_sub(to_unlock))
|
|
.unwrap_or(Zero::zero())
|
|
}
|
|
|
|
/// Block number at which the schedule ends (as type `Balance`).
|
|
pub fn ending_block_as_balance<BlockNumberToBalance: Convert<BlockNumber, Balance>>(
|
|
&self,
|
|
) -> Balance {
|
|
let starting_block = BlockNumberToBalance::convert(self.starting_block);
|
|
let duration = if self.per_block() >= self.locked {
|
|
// If `per_block` is bigger than `locked`, the schedule will end
|
|
// the block after starting.
|
|
One::one()
|
|
} else {
|
|
self.locked / self.per_block() +
|
|
if (self.locked % self.per_block()).is_zero() {
|
|
Zero::zero()
|
|
} else {
|
|
// `per_block` does not perfectly divide `locked`, so we need an extra block to
|
|
// unlock some amount less than `per_block`.
|
|
One::one()
|
|
}
|
|
};
|
|
|
|
starting_block.saturating_add(duration)
|
|
}
|
|
}
|