Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c686721
Define VestingSchedule trait
dmitrylavrenov Jul 20, 2022
7857a38
Implement locked_at
dmitrylavrenov Jul 20, 2022
5d14f88
Add docs to LinearWithCliff
dmitrylavrenov Jul 20, 2022
b95b1df
Implement end
dmitrylavrenov Jul 20, 2022
ccfeca8
Add little note
dmitrylavrenov Jul 20, 2022
c98e14d
Add validate logic
dmitrylavrenov Jul 21, 2022
4b5566c
Enable no_std mod
dmitrylavrenov Jul 25, 2022
8f3076f
Merge branch 'master' into vesting-schedule
dmitrylavrenov Jul 25, 2022
14ab8fa
Improve validate logic for LinearWithCliff
dmitrylavrenov Jul 26, 2022
3b015c4
Define vesting logic
dmitrylavrenov Jul 22, 2022
0f811bc
Rename to avoid multiple versions
dmitrylavrenov Jul 22, 2022
458d760
Enable no_std mod
dmitrylavrenov Jul 25, 2022
5fa5587
Define Config trait
dmitrylavrenov Jul 26, 2022
bc54328
Add Vesting storage as information regarding the vesting of a given a…
dmitrylavrenov Jul 26, 2022
ece65a8
Avoid complex type
dmitrylavrenov Jul 26, 2022
bb4b15c
Add GenesisBuild
dmitrylavrenov Jul 26, 2022
c7f16fc
Fix typo
dmitrylavrenov Jul 27, 2022
7d4decf
Move vesting-schedule tp pallet-vestig as mod
dmitrylavrenov Jul 28, 2022
39d5e4e
Delete vesting-logic
dmitrylavrenov Jul 28, 2022
5b3f21f
Introduce moment logic
dmitrylavrenov Jul 28, 2022
1c5a75a
Define vesting driver logic
dmitrylavrenov Jul 28, 2022
de85df1
Implement vesting-driver for timestamp
dmitrylavrenov Jul 28, 2022
f338475
Remove unused mod
dmitrylavrenov Jul 28, 2022
308c841
Initial pallet
dmitrylavrenov Jul 28, 2022
6f4fbca
Sum locked
dmitrylavrenov Jul 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/humanode-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pallet-ethereum-chain-id = { version = "0.1", path = "../pallet-ethereum-chain-i
pallet-evm-accounts-mapping = { version = "0.1", path = "../pallet-evm-accounts-mapping", default-features = false }
pallet-humanode-session = { version = "0.1", path = "../pallet-humanode-session", default-features = false }
pallet-pot = { version = "0.1", path = "../pallet-pot", default-features = false }
pallet-vesting = { version = "0.1", path = "../pallet-vesting", default-features = false }
precompile-bioauth = { version = "0.1", path = "../precompile-bioauth", default-features = false }
precompile-evm-accounts-mapping = { version = "0.1", path = "../precompile-evm-accounts-mapping", default-features = false }
primitives-auth-ticket = { version = "0.1", path = "../primitives-auth-ticket", default-features = false }
Expand Down Expand Up @@ -134,6 +135,7 @@ std = [
"pallet-timestamp/std",
"pallet-transaction-payment/std",
"pallet-transaction-payment-rpc-runtime-api/std",
"pallet-vesting/std",
"robonode-crypto/std",
"sp-application-crypto/std",
"sp-api/std",
Expand Down Expand Up @@ -171,4 +173,5 @@ try-runtime = [
"pallet-sudo/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-vesting/try-runtime",
]
31 changes: 31 additions & 0 deletions crates/pallet-vesting/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "pallet-vesting"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" }
frame-system = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" }
pallet-timestamp = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
serde = { version = "1", features = ["derive"], optional = true }
sp-arithmetic = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" }
sp-runtime = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" }
sp-std = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "master" }

[features]
default = ["std"]
std = [
"codec/std",
"frame-support/std",
"frame-system/std",
"pallet-timestamp/std",
"scale-info/std",
"serde",
"sp-arithmetic/std",
"sp-runtime/std",
"sp-std/std",
]
try-runtime = ["frame-support/try-runtime"]
74 changes: 74 additions & 0 deletions crates/pallet-vesting/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! The vesting pallet.

#![cfg_attr(not(feature = "std"), no_std)]

mod moment;
mod vesting_driver;
mod vesting_driver_timestamp;
mod vesting_schedule;

use codec::MaxEncodedLen;
use frame_support::{
pallet_prelude::*,
storage::bounded_vec::BoundedVec,
traits::{Currency, LockIdentifier, LockableCurrency, StorageVersion, WithdrawReasons},
};
pub use pallet::*;
use sp_runtime::traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize, Zero};
use vesting_schedule::VestingSchedule;

/// Balance type alias.
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);

/// Provides the capability to get current moment.
pub trait CurrentMoment<Moment> {
/// Return current moment.
fn now() -> Moment;
}

// We have to temporarily allow some clippy lints. Later on we'll send patches to substrate to
// fix them at their end.
#[allow(clippy::missing_docs_in_private_items)]
#[frame_support::pallet]
pub mod pallet {
use super::*;

/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
pub trait Config: frame_system::Config {
/// The currency to operate with.
type Currency: LockableCurrency<Self::AccountId>;

/// Type used for expressing moment.
type Moment: Parameter
+ Default
+ AtLeast32BitUnsigned
+ Copy
+ MaybeSerializeDeserialize
+ MaxEncodedLen;

/// The vesting schedule type to operate with.
type VestingSchedule: VestingSchedule<
Self::AccountId,
Moment = Self::Moment,
Currency = Self::Currency,
>;

/// The vesting schedule value itself.
type VestinScheduleValue: Get<Self::VestingSchedule>;

/// Maximum number of vesting schedules an account may have at a given moment.
type MaxVestingSchedules: Get<u32>;

/// An lock identifier for a lockable currency to be used in vesting.
type VestingLockId: Get<LockIdentifier>;
}

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);
}
33 changes: 33 additions & 0 deletions crates/pallet-vesting/src/moment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! The current moment logic.

use sp_std::marker::PhantomData;

pub trait CurrentMoment<Moment> {
fn now() -> Moment;
}

pub type UnixMilliseconds = u64;

pub struct TimestampMoment<R>(PhantomData<R>);

impl<R> CurrentMoment<UnixMilliseconds> for TimestampMoment<R>
where
R: pallet_timestamp::Config<Moment = UnixMilliseconds>,
{
fn now() -> UnixMilliseconds {
pallet_timestamp::Pallet::<R>::now()
}
}

pub type BlockNumber = u32;

pub struct BlockNumberMoment<R>(PhantomData<R>);

impl<R> CurrentMoment<BlockNumber> for BlockNumberMoment<R>
where
R: frame_system::Config<BlockNumber = BlockNumber>,
{
fn now() -> BlockNumber {
frame_system::Pallet::<R>::block_number()
}
}
27 changes: 27 additions & 0 deletions crates/pallet-vesting/src/vesting_driver.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Vesting driver logic.

use frame_support::traits::Currency as CurrencyT;

use super::*;
use crate::{moment::CurrentMoment, vesting_schedule::VestingSchedule as VestingScheduleT};

/// [`VestingDriver`] logic.
pub trait VestingDriver<AccountId, VestingInfo, VestingSchedule: VestingScheduleT<AccountId>> {
type CurrentMoment: CurrentMoment<<VestingSchedule as VestingScheduleT<AccountId>>::Moment>;
/// Get the amount that is currently being vested and cannot be transferred out of this account.
fn vesting(
who: &AccountId,
vesting_info: &VestingInfo,
) -> <<VestingSchedule as VestingScheduleT<AccountId>>::Currency as CurrencyT<AccountId>>::Balance;
}

pub struct VestingInfo<AccountId, VestingSchedule: VestingScheduleT<AccountId>, MaxSchedules> {
/// Locked amount at genesis.
pub locked: <<VestingSchedule as VestingScheduleT<AccountId>>::Currency as CurrencyT<
AccountId,
>>::Balance,
/// Starting moment for unlocking(vesting).
pub start: <VestingSchedule as VestingScheduleT<AccountId>>::Moment,
/// Vesting schedules.
pub schedules: BoundedVec<VestingSchedule, MaxSchedules>,
}
41 changes: 41 additions & 0 deletions crates/pallet-vesting/src/vesting_driver_timestamp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use frame_support::traits::Currency as CurrencyT;
use sp_runtime::traits::Saturating;
use sp_std::marker::PhantomData;

use super::*;
use crate::{
moment::{CurrentMoment, TimestampMoment, UnixMilliseconds},
vesting_driver::{VestingDriver, VestingInfo},
vesting_schedule::VestingSchedule as VestingScheduleT,
};

pub struct Driver<R>(PhantomData<R>);

impl<AccountId, VestingSchedule, MaxSchedules, R>
VestingDriver<AccountId, VestingInfo<AccountId, VestingSchedule, MaxSchedules>, VestingSchedule>
for Driver<R>
where
R: pallet_timestamp::Config<Moment = UnixMilliseconds>,
VestingSchedule: VestingScheduleT<AccountId, Moment = UnixMilliseconds>,
{
type CurrentMoment = TimestampMoment<R>;

fn vesting(
who: &AccountId,
vesting_info: &VestingInfo<AccountId, VestingSchedule, MaxSchedules>,
) -> <<VestingSchedule as VestingScheduleT<AccountId>>::Currency as CurrencyT<AccountId>>::Balance
{
let now = TimestampMoment::<R>::now();
let total_locked_now =
vesting_info
.schedules
.iter()
.fold(Zero::zero(), |total, schedule| {
schedule
.locked_at(vesting_info.locked, vesting_info.start, now)
.saturating_add(total)
});
<VestingSchedule as VestingScheduleT<AccountId>>::Currency::free_balance(who)
.min(total_locked_now)
}
}
Loading