Skip to content

Commit

Permalink
fix: time-release pallet updated with fungible traits; test working
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Orris committed Nov 17, 2023
1 parent e0eb02b commit 97d61f3
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 59 deletions.
54 changes: 34 additions & 20 deletions pallets/time-release/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ use frame_support::{
ensure,
pallet_prelude::*,
traits::{
BuildGenesisConfig, Currency, EnsureOrigin, ExistenceRequirement, Get, LockIdentifier,
LockableCurrency, WithdrawReasons,
tokens::{
fungible::{Inspect as InspectFungible, Mutate, MutateFreeze},
Balance, Preservation,
},
BuildGenesisConfig, EnsureOrigin, Get,
},
BoundedVec,
};
Expand All @@ -68,15 +71,13 @@ mod benchmarking;

pub use module::*;

/// The lock identifier for timed released transfers.
pub const RELEASE_LOCK_ID: LockIdentifier = *b"timeRels";

#[frame_support::pallet]
pub mod module {
use super::*;

pub(crate) type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
pub(crate) type BalanceOf<T> = <<T as Config>::Currency as InspectFungible<
<T as frame_system::Config>::AccountId,
>>::Balance;
pub(crate) type ReleaseScheduleOf<T> = ReleaseSchedule<BlockNumberFor<T>, BalanceOf<T>>;

/// Scheduled item used for configuring genesis.
Expand All @@ -88,13 +89,30 @@ pub mod module {
BalanceOf<T>,
);

/// A reason for freezing funds.
#[pallet::composite_enum]
pub enum FreezeReason {
/// The account is staked.
#[codec(index = 0)]
Staked,
/// An account with time released assets.
TimeReleased,
}
#[pallet::config]
pub trait Config: frame_system::Config {
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

/// The overarching freeze reason.
type RuntimeFreezeReason: From<FreezeReason>;

/// We need MaybeSerializeDeserialize because of the genesis config.
type Balance: Balance + MaybeSerializeDeserialize;

/// The currency trait used to set a lock on a balance.
type Currency: LockableCurrency<Self::AccountId, Moment = BlockNumberFor<Self>>;
type Currency: MutateFreeze<Self::AccountId, Id = Self::RuntimeFreezeReason>
+ InspectFungible<Self::AccountId, Balance = Self::Balance>
+ Mutate<Self::AccountId>;

#[pallet::constant]
/// The minimum amount transferred to call `transfer`.
Expand Down Expand Up @@ -207,15 +225,14 @@ pub mod module {
.expect("Invalid release schedule");

assert!(
T::Currency::free_balance(who) >= total_amount,
T::Currency::balance(who) >= total_amount,
"Account do not have enough balance"
);

T::Currency::set_lock(
RELEASE_LOCK_ID,
let _ = T::Currency::set_freeze(
&FreezeReason::TimeReleased.into(),
who,
total_amount,
WithdrawReasons::all(),
);
ReleaseSchedules::<T>::insert(who, bounded_schedules);
});
Expand Down Expand Up @@ -268,7 +285,7 @@ pub mod module {

if to == from {
ensure!(
T::Currency::free_balance(&from) >=
T::Currency::balance(&from) >=
schedule.total_amount().ok_or(ArithmeticError::Overflow)?,
Error::<T>::InsufficientBalanceToLock,
);
Expand Down Expand Up @@ -385,7 +402,7 @@ impl<T: Config> Pallet<T> {
.checked_add(&schedule_amount)
.ok_or(ArithmeticError::Overflow)?;

T::Currency::transfer(from, to, schedule_amount, ExistenceRequirement::AllowDeath)?;
T::Currency::transfer(from, to, schedule_amount, Preservation::Expendable)?;

Self::update_lock(&to, total_amount);

Expand Down Expand Up @@ -418,10 +435,7 @@ impl<T: Config> Pallet<T> {
},
)?;

ensure!(
T::Currency::free_balance(who) >= total_amount,
Error::<T>::InsufficientBalanceToLock,
);
ensure!(T::Currency::balance(who) >= total_amount, Error::<T>::InsufficientBalanceToLock,);

Self::update_lock(&who, total_amount);
Self::set_schedules_for(who, bounded_schedules);
Expand All @@ -430,11 +444,11 @@ impl<T: Config> Pallet<T> {
}

fn update_lock(who: &T::AccountId, locked: BalanceOf<T>) {
T::Currency::set_lock(RELEASE_LOCK_ID, who, locked, WithdrawReasons::all());
let _ = T::Currency::set_freeze(&FreezeReason::TimeReleased.into(), who, locked);
}

fn delete_lock(who: &T::AccountId) {
T::Currency::remove_lock(RELEASE_LOCK_ID, who);
let _ = T::Currency::thaw(&FreezeReason::TimeReleased.into(), who);
}

fn set_schedules_for(
Expand Down
10 changes: 6 additions & 4 deletions pallets/time-release/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ impl pallet_balances::Config for Test {
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type WeightInfo = ();
type FreezeIdentifier = ();
type MaxHolds = ConstU32<0>;
type MaxFreezes = ConstU32<0>;
type FreezeIdentifier = RuntimeFreezeReason;
type MaxFreezes = ConstU32<1>;
type RuntimeHoldReason = ();
type MaxHolds = ConstU32<0>;
}

pub struct EnsureAliceOrBob;
Expand Down Expand Up @@ -99,6 +99,8 @@ impl Config for Test {
type WeightInfo = ();
type MaxReleaseSchedules = ConstU32<50>;
type BlockNumberProvider = MockBlockNumberProvider;
type RuntimeFreezeReason = RuntimeFreezeReason;
type Balance = Balance;
}

type Block = frame_system::mocking::MockBlockU32<Test>;
Expand All @@ -107,7 +109,7 @@ construct_runtime!(
pub enum Test
{
System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>},
TimeRelease: pallet_time_release::{Pallet, Storage, Call, Event<T>, Config<T>},
TimeRelease: pallet_time_release::{Pallet, Storage, Call, Event<T>, Config<T>, FreezeReason},
PalletBalances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
}
);
Expand Down
Loading

0 comments on commit 97d61f3

Please sign in to comment.