Skip to content

Commit

Permalink
Merge pull request #347 from liberland/BLOCKCHAIN-364/monthly-llm-vau…
Browse files Browse the repository at this point in the history
…lt-ming

BLOCKCHAIN-364 - LLM monthly vault mint instead of yearly
  • Loading branch information
DorianSternVukotic authored Feb 28, 2024
2 parents f34f1a3 + 920f59c commit 54c2ca2
Showing 11 changed files with 181 additions and 52 deletions.
11 changes: 5 additions & 6 deletions substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1424,7 +1424,8 @@ parameter_types! {
pub const CitizenshipMinimum: Balance = 5_000u128 * GRAINS_IN_LLM;
pub const UnlockFactor: Permill = Permill::from_parts(8742);
pub const AssetId: u32 = 1;
pub const InflationEventInterval: BlockNumber = 365 * DAYS;
pub const InflationEventInterval: BlockNumber = 30 * DAYS;
pub const InflationEventReleaseFactor: Perbill = Perbill::from_parts(8741611);
}

impl pallet_liberland_initializer::Config for Runtime {}
@@ -1440,6 +1441,7 @@ impl pallet_llm::Config for Runtime {
type AssetName = AssetName;
type AssetSymbol = AssetSymbol;
type InflationEventInterval = InflationEventInterval;
type InflationEventReleaseFactor = InflationEventReleaseFactor;
type SenateOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
EnsureSenateMajority
@@ -1954,14 +1956,11 @@ mod bounties_v4 {
// All migrations executed on runtime upgrade as a nested tuple of types implementing
// `OnRuntimeUpgrade`.
parameter_types! {
pub const PastPayouts: Vec<(AccountId, Balance)> = vec![];
pub const OldInflationEventInterval: BlockNumber = 365 * DAYS;
}
type Migrations = (
pallet_contracts::Migration<Runtime>,
pallet_llm::migrations::v3::Migration<Runtime>,
pallet_im_online::migration::v1::Migration<Runtime>,
migrations::society_to_v2::Migration<Runtime>,
migrations::add_pallets::Migration<Runtime>,
pallet_llm::migrations::v4::Migration<Runtime, OldInflationEventInterval>,
);

type EventRecord = frame_system::EventRecord<
3 changes: 3 additions & 0 deletions substrate/bin/node/runtime/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -84,6 +84,9 @@ pub mod society_to_v2 {
use pallet_society::migrations::VersionUncheckedMigrateToV2;
use frame_support::migrations::StoreCurrentStorageVersion;

parameter_types! {
pub const PastPayouts: Vec<(AccountId, Balance)> = vec![];
}
type SocietyMigration = VersionUncheckedMigrateToV2<Runtime, (), PastPayouts>;

pub struct Migration<T>(sp_std::marker::PhantomData<T>);
2 changes: 2 additions & 0 deletions substrate/frame/democracy/src/tests.rs
Original file line number Diff line number Diff line change
@@ -244,6 +244,7 @@ parameter_types! {
pub const AssetName: &'static str = "LiberTest Merit";
pub const AssetSymbol: &'static str = "LTM";
pub const InflationEventInterval: u64 = 1000;
pub const InflationEventReleaseFactor: Perbill = Perbill::from_parts(8741611);
}

impl pallet_liberland_initializer::Config for Test {}
@@ -259,6 +260,7 @@ impl pallet_llm::Config for Test {
type AssetName = AssetName;
type AssetSymbol = AssetSymbol;
type InflationEventInterval = InflationEventInterval;
type InflationEventReleaseFactor = InflationEventReleaseFactor;
type OnLLMPoliticsUnlock = ();
type SenateOrigin = EnsureRoot<u64>;
type WeightInfo = ();
2 changes: 2 additions & 0 deletions substrate/frame/elections-phragmen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1438,6 +1438,7 @@ mod tests {
pub const AssetName: &'static str = "LiberTest Merit";
pub const AssetSymbol: &'static str = "LTM";
pub const InflationEventInterval: u64 = 1000;
pub const InflationEventReleaseFactor: Perbill = Perbill::from_parts(8741611);
}

impl pallet_liberland_initializer::Config for Test {}
@@ -1453,6 +1454,7 @@ mod tests {
type AssetName = AssetName;
type AssetSymbol = AssetSymbol;
type InflationEventInterval = InflationEventInterval;
type InflationEventReleaseFactor = InflationEventReleaseFactor;
type OnLLMPoliticsUnlock = ();
type SenateOrigin = EnsureRoot<u64>;
type WeightInfo = ();
2 changes: 2 additions & 0 deletions substrate/frame/liberland-legislation/src/mock.rs
Original file line number Diff line number Diff line change
@@ -240,6 +240,7 @@ parameter_types! {
pub const AssetName: &'static str = "LiberTest Merit";
pub const AssetSymbol: &'static str = "LTM";
pub const InflationEventInterval: u64 = 1000;
pub const InflationEventReleaseFactor: Perbill = Perbill::from_parts(8741611);
}

impl pallet_llm::Config for Test {
@@ -253,6 +254,7 @@ impl pallet_llm::Config for Test {
type AssetName = AssetName;
type AssetSymbol = AssetSymbol;
type InflationEventInterval = InflationEventInterval;
type InflationEventReleaseFactor = InflationEventReleaseFactor;
type OnLLMPoliticsUnlock = ();
type SenateOrigin = EnsureRoot<u64>;
type WeightInfo = ();
2 changes: 1 addition & 1 deletion substrate/frame/llm/README.md
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ Accounts may freely transfer their not-locked LLM to other accounts.

## Internal Storage:

* `NextRelease`: block number for next LLM Release Event (transfer of 10% from **Vault** to **Treasury**)
* `LastRelease`: block number for last LLM Release Event (transfer from **Vault** to **Treasury**)
* `LLMPolitics`: amount of LLM each account has allocated into politics
* `Withdrawlock`: block number until which account can't do another `politics_unlock`
* `Electionlock`: block number until which account can't participate in politics directly
64 changes: 34 additions & 30 deletions substrate/frame/llm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
//! * creating LLM asset in `pallet-assets` on genesis
//! * LLM release from **Vault** to **Treasury**
//! * locking, a.k.a. politipooling the LLM for use in politics
//! * veryfing citizenship status
//! * verifying citizenship status
//!
//! ## LLM lifecycle
//!
@@ -19,9 +19,9 @@
//! * configured `TotalSupply` amount of LLM is created and transferred to **Vault**
//! * configured `PreReleasedAmount` is transferred from **Vault** to **Treasury**
//!
//! On yearly basis (see `fn try_release`):
//! Every `InflationEventInterval` (see `fn maybe_release`):
//!
//! * 90% of **Vault** balance is transferred to **Treasury**
//! * `InflationEventReleaseFactor` of **Vault** balance is transferred to **Treasury**
//!
//! Accounts are free to locks in politics, a.k.a. politipool any amount of LLM at any time.
//!
@@ -51,7 +51,7 @@
//!
//! ## Internal Storage:
//!
//! * `NextRelease`: block number for next LLM Release Event (transfer of 10% from **Vault** to
//! * `LastRelease`: block number for next LLM Release Event (transfer from **Vault** to
//! **Treasury**)
//! * `LLMPolitics`: amount of LLM each account has allocated into politics
//! * `Withdrawlock`: block number until which account can't do another `politics_unlock`
@@ -181,14 +181,14 @@ pub mod pallet {
use scale_info::prelude::vec;
use sp_runtime::{
traits::{AccountIdConversion, StaticLookup},
AccountId32, Permill,
AccountId32, Perbill, Permill,
};
use sp_std::vec::Vec;

/// block number for next LLM release event (transfer of 10% from **Vault** to **Treasury**)
/// block number of last LLM release event (transfer from **Vault** to **Treasury**)
#[pallet::storage]
#[pallet::getter(fn next_release)]
pub(super) type NextRelease<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>; // ValueQuery , OnEmpty = 0
#[pallet::getter(fn last_release)]
pub(super) type LastRelease<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>; // ValueQuery , OnEmpty = 0

/// amount of LLM each account has allocated into politics
#[pallet::storage]
@@ -296,8 +296,13 @@ pub mod pallet {
type AssetId: Get<<Self as pallet_assets::Config>::AssetId>;
type AssetName: Get<Vec<u8>>;
type AssetSymbol: Get<Vec<u8>>;

#[pallet::constant]
type InflationEventInterval: Get<BlockNumberFor<Self>>;

#[pallet::constant]
type InflationEventReleaseFactor: Get<Perbill>;

type OnLLMPoliticsUnlock: OnLLMPoliticsUnlock<Self::AccountId>;
type WeightInfo: WeightInfo;
}
@@ -324,7 +329,7 @@ pub mod pallet {
Locked,
}

const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(4);

#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
@@ -333,7 +338,9 @@ pub mod pallet {
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(b: BlockNumberFor<T>) -> Weight {
Self::maybe_release(b);
if let Err(e) = Self::maybe_release(b) {
log::error!("LLM maybe_release failure: {e:?}");
};
Weight::zero()
}
}
@@ -524,7 +531,6 @@ pub mod pallet {

fn get_unlock_amount(balance: T::Balance) -> Result<T::Balance, Error<T>> {
let factor = T::UnlockFactor::get();
let balance: u64 = balance.try_into().map_err(|_| Error::<T>::InvalidAmount)?;
let amount = factor.mul_floor(balance);
amount.try_into().map_err(|_| Error::<T>::InvalidAmount)
}
@@ -607,9 +613,7 @@ pub mod pallet {
let vaultac: T::AccountId = Self::get_llm_vault_account();
let supply = T::TotalSupply::get().try_into().map_err(|_| Error::<T>::InvalidAmount)?;
Assets::<T>::mint_into(asset_id, &vaultac, supply)?;

let nextblock = Self::get_future_block();
NextRelease::<T>::put(nextblock);
LastRelease::<T>::put(frame_system::Pallet::<T>::block_number());

// Release a.k.a. transfer to treasury
let prereleased =
@@ -642,30 +646,30 @@ pub mod pallet {
PalletId(*b"polilock").into_account_truncating()
}

fn get_future_block() -> BlockNumberFor<T> {
let current_block_number = frame_system::Pallet::<T>::block_number();
current_block_number + T::InflationEventInterval::get()
}

// each time we release (should be each year), release 10% from vault
fn get_release_amount() -> T::Balance {
fn get_release_amount() -> Result<T::Balance, Error<T>> {
let asset_id = Self::llm_id().into();
let vault_account = Self::get_llm_vault_account();
let unreleased_amount = Assets::<T>::balance(asset_id, vault_account);
let release_amount = unreleased_amount / 10u8.into();
release_amount

let factor = T::InflationEventReleaseFactor::get();
let release_amount = factor.mul_floor(unreleased_amount);
release_amount.try_into().map_err(|_| Error::<T>::InvalidAmount)
}

fn maybe_release(block: BlockNumberFor<T>) -> bool {
if block < NextRelease::<T>::get() {
return false;
fn maybe_release(block: BlockNumberFor<T>) -> DispatchResult {
let next_release = LastRelease::<T>::get() + T::InflationEventInterval::get();
if block < next_release {
return Ok(());
}
NextRelease::<T>::put(Self::get_future_block());

let release_amount = Self::get_release_amount();
Self::release_tokens_from_vault(release_amount).unwrap();
LastRelease::<T>::put(next_release);
let release_amount = Self::get_release_amount()?;
if release_amount > 0u8.into() {
log::info!("LLM - releasing {release_amount:?} from vault");
Self::release_tokens_from_vault(release_amount)?;
}

true
Ok(())
}

/// Release tokens to the treasury account. Sends tokens from the llm/vault to the treasury
51 changes: 50 additions & 1 deletion substrate/frame/llm/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ use frame_support::{pallet_prelude::*, storage_alias, traits::OnRuntimeUpgrade};
use liberland_traits::CitizenshipChecker;
use pallet_identity::Registration;
use sp_std::vec::Vec;
use frame_system::pallet_prelude::BlockNumberFor;

#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;
@@ -235,7 +236,6 @@ pub mod v2 {

pub mod v3 {
use super::*;
use frame_system::pallet_prelude::BlockNumberFor;

const TARGET: &'static str = "runtime::llm::migration::v3";

@@ -277,3 +277,52 @@ pub mod v3 {
}
}
}

pub mod v4 {
use super::*;

const TARGET: &'static str = "runtime::llm::migration::v4";

pub struct Migration<T, OldInterval>(sp_std::marker::PhantomData<(T, OldInterval)>);

#[storage_alias]
type NextRelease<T: Config> = StorageValue<
Pallet<T>,
BlockNumberFor<T>,
ValueQuery
>;

impl<T: Config, OldInterval: Get<BlockNumberFor<T>>> OnRuntimeUpgrade for Migration<T, OldInterval> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
assert!(StorageVersion::get::<Pallet<T>>() == 3, "can only upgrade from version 3");

Ok(().encode())
}

fn on_runtime_upgrade() -> Weight {
let weight = T::DbWeight::get().reads(1);
if StorageVersion::get::<Pallet<T>>() != 3 {
log::warn!(
target: TARGET,
"skipping on_runtime_upgrade: executed on wrong storage version.\
Expected version 3"
);
return weight;
}

LastRelease::<T>::put(
NextRelease::<T>::get() - OldInterval::get()
);

StorageVersion::new(4).put::<Pallet<T>>();
weight.saturating_add(T::DbWeight::get().reads_writes(1, 1))
}

#[cfg(feature = "try-runtime")]
fn post_upgrade(_state: Vec<u8>) -> Result<(), TryRuntimeError> {
assert_eq!(StorageVersion::get::<Pallet<T>>(), 4, "must upgrade");
Ok(())
}
}
}
6 changes: 4 additions & 2 deletions substrate/frame/llm/src/mock.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ use sp_core::{ConstU16, H256};
use sp_runtime::{
BuildStorage,
traits::{BlakeTwo256, Hash, IdentityLookup},
Permill,
Perbill, Permill,
};

type Block = frame_system::mocking::MockBlock<Test>;
@@ -106,7 +106,8 @@ parameter_types! {
pub const AssetId: u32 = 1;
pub const AssetName: &'static str = "LiberTest Merit";
pub const AssetSymbol: &'static str = "LTM";
pub const InflationEventInterval: u64 = 1000;
pub const InflationEventInterval: u64 = 30*24*3600/6;
pub const InflationEventReleaseFactor: Perbill = Perbill::from_parts(8741611);
}

impl pallet_llm::Config for Test {
@@ -120,6 +121,7 @@ impl pallet_llm::Config for Test {
type AssetName = AssetName;
type AssetSymbol = AssetSymbol;
type InflationEventInterval = InflationEventInterval;
type InflationEventReleaseFactor = InflationEventReleaseFactor;
type OnLLMPoliticsUnlock = ();
type SenateOrigin = EnsureRoot<u64>;
type WeightInfo = ();
Loading

0 comments on commit 54c2ca2

Please sign in to comment.