Newer
Older
//! Unit tests for the vesting module.
#![cfg(test)]
use super::*;
use frame_support::{assert_err, assert_ok, traits::WithdrawReason};
use mock::{ExtBuilder, Origin, PalletBalances, Runtime, System, TestEvent, Vesting, ALICE, BOB, CHARLIE};
use pallet_balances::{BalanceLock, Reasons};
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#[test]
fn vesting_from_chain_spec_works() {
ExtBuilder::build().execute_with(|| {
assert_ok!(PalletBalances::ensure_can_withdraw(
&CHARLIE,
10,
WithdrawReason::Transfer.into(),
20
));
assert!(PalletBalances::ensure_can_withdraw(&CHARLIE, 11, WithdrawReason::Transfer.into(), 19).is_err());
assert_eq!(
Vesting::vesting_schedules(&CHARLIE),
vec![VestingSchedule {
start: 2u64,
period: 3u64,
period_count: 4u32,
per_period: 5u64,
}]
);
System::set_block_number(13);
assert_ok!(Vesting::claim(Origin::signed(CHARLIE)));
assert_ok!(PalletBalances::ensure_can_withdraw(
&CHARLIE,
25,
WithdrawReason::Transfer.into(),
5
));
assert!(PalletBalances::ensure_can_withdraw(&CHARLIE, 26, WithdrawReason::Transfer.into(), 4).is_err());
System::set_block_number(14);
assert_ok!(Vesting::claim(Origin::signed(CHARLIE)));
assert_ok!(PalletBalances::ensure_can_withdraw(
&CHARLIE,
30,
WithdrawReason::Transfer.into(),
0
));
});
}
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 0u64,
period: 10u64,
period_count: 1u32,
per_period: 100u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule.clone()]);
let vested_event = TestEvent::vesting(RawEvent::VestingScheduleAdded(ALICE, BOB, schedule));
assert!(System::events().iter().any(|record| record.event == vested_event));
});
}
#[test]
fn add_new_vesting_schedule_merges_with_current_locked_balance_and_until() {
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 0u64,
period: 10u64,
period_count: 2u32,
per_period: 10u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule));
System::set_block_number(12);
let another_schedule = VestingSchedule {
start: 10u64,
period: 13u64,
period_count: 1u32,
per_period: 7u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, another_schedule));
assert_eq!(
PalletBalances::locks(&BOB).pop(),
Some(BalanceLock {
id: VESTING_LOCK_ID,
amount: 17u64,
reasons: Reasons::All,
})
);
});
}
#[test]
fn cannot_use_fund_if_not_claimed() {
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 10u64,
period: 10u64,
period_count: 1u32,
per_period: 50u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
assert!(PalletBalances::ensure_can_withdraw(&BOB, 1, WithdrawReason::Transfer.into(), 49).is_err());
});
}
#[test]
fn vested_transfer_fails_if_zero_period_or_count() {
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 1u64,
period: 0u64,
period_count: 1u32,
per_period: 100u64,
};
assert_err!(
Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()),
Error::<Runtime>::ZeroVestingPeriod
);
let schedule = VestingSchedule {
start: 1u64,
period: 1u64,
period_count: 0u32,
per_period: 100u64,
};
assert_err!(
Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()),
Error::<Runtime>::ZeroVestingPeriodCount
);
});
}
#[test]
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 1u64,
period: 1u64,
period_count: 1u32,
per_period: 100u64,
};
assert_err!(
Vesting::vested_transfer(Origin::signed(BOB), ALICE, schedule.clone()),
pallet_balances::Error::<Runtime, _>::InsufficientBalance,
);
});
}
#[test]
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 1u64,
period: 1u64,
period_count: 2u32,
per_period: u64::max_value(),
};
assert_err!(
Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule),
Error::<Runtime>::NumOverflow
);
let another_schedule = VestingSchedule {
start: u64::max_value(),
period: 1u64,
period_count: 2u32,
per_period: 1u64,
};
assert_err!(
Vesting::vested_transfer(Origin::signed(ALICE), BOB, another_schedule),
Error::<Runtime>::NumOverflow
);
});
}
#[test]
fn claim_works() {
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 0u64,
period: 10u64,
period_count: 2u32,
per_period: 10u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
System::set_block_number(11);
// remain locked if not claimed
assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10).is_err());
// unlocked after claiming
assert_ok!(Vesting::claim(Origin::signed(BOB)));
assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));
// more are still locked
assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 1).is_err());
System::set_block_number(21);
// claim more
assert_ok!(Vesting::claim(Origin::signed(BOB)));
assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));
// all used up
assert_eq!(PalletBalances::free_balance(BOB), 0);
// no locks anymore
assert_eq!(PalletBalances::locks(&BOB), vec![]);
});
}
#[test]
fn update_vesting_schedules_works() {
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 0u64,
period: 10u64,
period_count: 2u32,
per_period: 10u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
let updated_schedule = VestingSchedule {
start: 0u64,
period: 20u64,
period_count: 2u32,
per_period: 10u64,
};
assert_ok!(Vesting::update_vesting_schedules(
BOB,
vec![updated_schedule]
));
System::set_block_number(11);
assert_ok!(Vesting::claim(Origin::signed(BOB)));
assert!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 1).is_err());
System::set_block_number(21);
assert_ok!(Vesting::claim(Origin::signed(BOB)));
assert_ok!(PalletBalances::transfer(Origin::signed(BOB), ALICE, 10));
});
}
#[test]
fn update_vesting_schedules_fails_if_unexpected_existing_locks() {
ExtBuilder::build().execute_with(|| {
assert_ok!(PalletBalances::transfer(Origin::signed(ALICE), BOB, 1));
PalletBalances::set_lock(*b"prelocks", &BOB, 0u64, WithdrawReasons::all());
#[test]
fn vested_transfer_check_for_min() {
ExtBuilder::build().execute_with(|| {
let schedule = VestingSchedule {
start: 1u64,
period: 1u64,
period_count: 1u32,
per_period: 3u64,
};
assert_err!(
Vesting::vested_transfer(Origin::signed(BOB), ALICE, schedule.clone()),
Error::<Runtime>::AmountLow
);
});
}
#[test]
fn multiple_vesting_schedule_claim_works() {
ExtBuilder::build().execute_with(|| {
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
let schedule = VestingSchedule {
start: 0u64,
period: 10u64,
period_count: 2u32,
per_period: 10u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule.clone()));
let schedule2 = VestingSchedule {
start: 0u64,
period: 10u64,
period_count: 3u32,
per_period: 10u64,
};
assert_ok!(Vesting::vested_transfer(Origin::signed(ALICE), BOB, schedule2.clone()));
assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule, schedule2.clone()]);
System::set_block_number(21);
assert_ok!(Vesting::claim(Origin::signed(BOB)));
assert_eq!(Vesting::vesting_schedules(&BOB), vec![schedule2]);
System::set_block_number(31);
assert_ok!(Vesting::claim(Origin::signed(BOB)));
assert_eq!(VestingSchedules::<Runtime>::contains_key(&BOB), false);
assert_eq!(PalletBalances::locks(&BOB), vec![]);
});
}