-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
[package] | ||
name = "on-slash-vesting" | ||
authors.workspace = true | ||
documentation.workspace = true | ||
edition.workspace = true | ||
homepage.workspace = true | ||
license-file.workspace = true | ||
readme.workspace = true | ||
repository.workspace = true | ||
version.workspace = true | ||
|
||
[dependencies] | ||
pallet-vesting.workspace = true | ||
impl-trait-for-tuples.workspace = true | ||
frame-support.workspace = true | ||
frame-system.workspace = true | ||
pallet-balances.workspace = true | ||
log.workspace = true | ||
parity-scale-codec.workspace = true | ||
scale-info.workspace = true | ||
sp-runtime.workspace = true | ||
sp-io.workspace = true | ||
serde.workspace = true | ||
[lints] | ||
workspace = true | ||
|
||
|
||
[features] | ||
default = [ "std" ] | ||
|
||
std = [ | ||
"pallet-vesting/std", | ||
"frame-support/std", | ||
"frame-system/std", | ||
"pallet-balances/std", | ||
"log/std", | ||
"parity-scale-codec/std", | ||
"scale-info/std", | ||
"sp-runtime/std", | ||
"sp-io/std", | ||
"serde/std", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Ensure we're `no_std` when compiling for Wasm. | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
#[cfg(test)] | ||
mod mock; | ||
#[cfg(test)] | ||
mod test; | ||
|
||
extern crate alloc; | ||
use alloc::vec::Vec; | ||
use frame_support::{ | ||
sp_runtime::{traits::Convert, FixedPointNumber, FixedU128}, | ||
traits::{Currency, OriginTrait}, | ||
}; | ||
use pallet_vesting::Vesting; | ||
use sp_runtime::traits::BlockNumberProvider; | ||
|
||
pub trait OnSlash<AccountId, Balance: Clone> { | ||
fn on_slash(account: &AccountId, amount: Balance); | ||
} | ||
|
||
#[impl_trait_for_tuples::impl_for_tuples(30)] | ||
impl<AccountId, Balance: Clone> OnSlash<AccountId, Balance> for Tuple { | ||
fn on_slash(account: &AccountId, amount: Balance) { | ||
for_tuples!( #( Tuple::on_slash(account, amount.clone()); )* ); | ||
} | ||
} | ||
|
||
type AccountIdOf<T> = <T as frame_system::Config>::AccountId; | ||
impl<T> OnSlash<AccountIdOf<T>, u128> for pallet_vesting::Pallet<T> | ||
where | ||
T: pallet_vesting::Config, | ||
T::Currency: Currency<AccountIdOf<T>, Balance = u128>, | ||
{ | ||
fn on_slash(account: &AccountIdOf<T>, slashed_amount: u128) { | ||
let Some(vesting_schedules) = <Vesting<T>>::get(account) else { return }; | ||
let vesting_schedules = vesting_schedules.to_vec(); | ||
let mut new_vesting_schedules = Vec::new(); | ||
let now = T::BlockNumberProvider::current_block_number(); | ||
for schedule in vesting_schedules { | ||
dbg!(schedule); | ||
let total_locked = schedule.locked_at::<T::BlockNumberToBalance>(now).saturating_sub(slashed_amount); | ||
let start_block: u128 = T::BlockNumberToBalance::convert(now); | ||
let end_block: u128 = schedule.ending_block_as_balance::<T::BlockNumberToBalance>(); | ||
let duration = end_block.saturating_sub(start_block); | ||
let per_block = FixedU128::from_rational(total_locked, duration).saturating_mul_int(1u128); | ||
let new_schedule = pallet_vesting::VestingInfo::new(total_locked, per_block, now); | ||
if new_schedule.is_valid() { | ||
dbg!(new_schedule); | ||
new_vesting_schedules.push(new_schedule); | ||
} | ||
} | ||
let Ok(new_vesting_schedules) = new_vesting_schedules.try_into() else { | ||
log::error!("Failed to convert new vesting schedules into BoundedVec"); | ||
return | ||
}; | ||
<Vesting<T>>::set(account, Some(new_vesting_schedules)); | ||
let vest_result = <pallet_vesting::Pallet<T>>::vest(T::RuntimeOrigin::signed(account.clone())); | ||
debug_assert!(vest_result.is_ok()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use frame_support::{ | ||
__private::RuntimeDebug, | ||
derive_impl, parameter_types, | ||
sp_runtime::{traits::IdentityLookup, BuildStorage}, | ||
traits::{VariantCount, WithdrawReasons}, | ||
}; | ||
use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; | ||
use scale_info::TypeInfo; | ||
use serde::{Deserialize, Serialize}; | ||
use sp_runtime::traits::{ConvertInto, Identity}; | ||
|
||
frame_support::construct_runtime!( | ||
pub enum TestRuntime { | ||
System: frame_system = 0, | ||
Balances: pallet_balances = 1, | ||
Vesting: pallet_vesting = 2, | ||
} | ||
); | ||
type Block = frame_system::mocking::MockBlock<TestRuntime>; | ||
|
||
#[derive( | ||
Encode, | ||
Decode, | ||
Copy, | ||
Clone, | ||
PartialEq, | ||
Eq, | ||
RuntimeDebug, | ||
MaxEncodedLen, | ||
TypeInfo, | ||
Ord, | ||
PartialOrd, | ||
Serialize, | ||
Deserialize, | ||
)] | ||
pub enum MockRuntimeHoldReason { | ||
Reason, | ||
Reason2, | ||
} | ||
impl VariantCount for MockRuntimeHoldReason { | ||
const VARIANT_COUNT: u32 = 2; | ||
} | ||
|
||
#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] | ||
impl frame_system::Config for TestRuntime { | ||
type AccountData = pallet_balances::AccountData<u128>; | ||
type AccountId = u64; | ||
type Block = Block; | ||
type Lookup = IdentityLookup<Self::AccountId>; | ||
} | ||
|
||
parameter_types! { | ||
pub const MinVestedTransfer: u64 = 10; | ||
pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = | ||
WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); | ||
pub static ExistentialDeposit: u128 = 10u128.pow(7); | ||
} | ||
|
||
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)] | ||
impl pallet_balances::Config for TestRuntime { | ||
type AccountStore = System; | ||
type Balance = u128; | ||
type ExistentialDeposit = ExistentialDeposit; | ||
type RuntimeHoldReason = MockRuntimeHoldReason; | ||
} | ||
|
||
impl pallet_vesting::Config for TestRuntime { | ||
#[cfg(feature = "runtime-benchmarks")] | ||
type BenchmarkReason = BenchmarkReason; | ||
type BlockNumberProvider = System; | ||
type BlockNumberToBalance = ConvertInto; | ||
type Currency = Balances; | ||
type MinVestedTransfer = MinVestedTransfer; | ||
type RuntimeEvent = RuntimeEvent; | ||
type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; | ||
type WeightInfo = (); | ||
|
||
const MAX_VESTING_SCHEDULES: u32 = 6; | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct ExtBuilder { | ||
pub existential_deposit: u128, | ||
} | ||
|
||
impl ExtBuilder { | ||
pub fn existential_deposit(mut self, existential_deposit: u128) -> Self { | ||
self.existential_deposit = existential_deposit; | ||
self | ||
} | ||
|
||
pub fn build(self) -> sp_io::TestExternalities { | ||
EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); | ||
let mut t = frame_system::GenesisConfig::<TestRuntime>::default().build_storage().unwrap(); | ||
pallet_balances::GenesisConfig::<TestRuntime> { | ||
balances: vec![ | ||
(1, self.existential_deposit), | ||
(2, self.existential_deposit), | ||
(3, self.existential_deposit), | ||
(4, self.existential_deposit), | ||
], | ||
} | ||
.assimilate_storage(&mut t) | ||
.unwrap(); | ||
|
||
sp_io::TestExternalities::new(t) | ||
} | ||
} |
Oops, something went wrong.