diff --git a/vesting/src/lib.rs b/vesting/src/lib.rs index 422b88b1b..96dab8fb6 100644 --- a/vesting/src/lib.rs +++ b/vesting/src/lib.rs @@ -264,6 +264,14 @@ pub mod module { ) -> DispatchResult { let from = T::VestedTransferOrigin::ensure_origin(origin)?; let to = T::Lookup::lookup(dest)?; + + if to == from { + ensure!( + T::Currency::free_balance(&from) >= schedule.total_amount().ok_or(ArithmeticError::Overflow)?, + Error::::InsufficientBalanceToLock, + ); + } + Self::do_vested_transfer(&from, &to, schedule.clone())?; Self::deposit_event(Event::VestingScheduleAdded { diff --git a/vesting/src/mock.rs b/vesting/src/mock.rs index 75024a63f..9a2a871fa 100644 --- a/vesting/src/mock.rs +++ b/vesting/src/mock.rs @@ -116,6 +116,9 @@ pub const ALICE: AccountId = 1; pub const BOB: AccountId = 2; pub const CHARLIE: AccountId = 3; +pub const ALICE_BALANCE: u64 = 100; +pub const CHARLIE_BALANCE: u64 = 50; + #[derive(Default)] pub struct ExtBuilder; @@ -126,7 +129,7 @@ impl ExtBuilder { .unwrap(); pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, 100), (CHARLIE, 50)], + balances: vec![(ALICE, ALICE_BALANCE), (CHARLIE, CHARLIE_BALANCE)], } .assimilate_storage(&mut t) .unwrap(); diff --git a/vesting/src/tests.rs b/vesting/src/tests.rs index 97371ffac..2419d6680 100644 --- a/vesting/src/tests.rs +++ b/vesting/src/tests.rs @@ -87,6 +87,45 @@ fn vested_transfer_works() { }); } +#[test] +fn self_vesting() { + ExtBuilder::build().execute_with(|| { + System::set_block_number(1); + + let schedule = VestingSchedule { + start: 0u64, + period: 10u64, + period_count: 1u32, + per_period: ALICE_BALANCE, + }; + + let bad_schedule = VestingSchedule { + start: 0u64, + period: 10u64, + period_count: 1u32, + per_period: 10 * ALICE_BALANCE, + }; + + assert_noop!( + Vesting::vested_transfer(RuntimeOrigin::signed(ALICE), ALICE, bad_schedule), + crate::Error::::InsufficientBalanceToLock + ); + + assert_ok!(Vesting::vested_transfer( + RuntimeOrigin::signed(ALICE), + ALICE, + schedule.clone() + )); + + assert_eq!(Vesting::vesting_schedules(&ALICE), vec![schedule.clone()]); + System::assert_last_event(RuntimeEvent::Vesting(crate::Event::VestingScheduleAdded { + from: ALICE, + to: ALICE, + vesting_schedule: schedule, + })); + }); +} + #[test] fn add_new_vesting_schedule_merges_with_current_locked_balance_and_until() { ExtBuilder::build().execute_with(|| {