mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 02:11:07 +00:00
Introduce vesting offsets (#3094)
* Introduce vesting offsets Closes #3090 * Fix logic * Bump impl verfsion * Initial rewrite of vesting * Test for liquidity with delayed vesting * Bump Spec, Fix line width * More line width fix * Small nit to documentation
This commit is contained in:
@@ -111,31 +111,37 @@ fn lock_value_extension_should_work() {
|
||||
|
||||
#[test]
|
||||
fn lock_reasons_should_work() {
|
||||
with_externalities(&mut ExtBuilder::default().existential_deposit(1).monied(true).transaction_fees(0, 1).build(), || {
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into());
|
||||
assert_noop!(
|
||||
<Balances as Currency<_>>::transfer(&1, &2, 1),
|
||||
"account liquidity restrictions prevent withdrawal"
|
||||
);
|
||||
assert_ok!(<Balances as ReservableCurrency<_>>::reserve(&1, 1));
|
||||
assert_ok!(<Balances as MakePayment<_>>::make_payment(&1, 1));
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(1)
|
||||
.monied(true).transaction_fees(0, 1)
|
||||
.build(),
|
||||
|| {
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Transfer.into());
|
||||
assert_noop!(
|
||||
<Balances as Currency<_>>::transfer(&1, &2, 1),
|
||||
"account liquidity restrictions prevent withdrawal"
|
||||
);
|
||||
assert_ok!(<Balances as ReservableCurrency<_>>::reserve(&1, 1));
|
||||
assert_ok!(<Balances as MakePayment<_>>::make_payment(&1, 1));
|
||||
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Reserve.into());
|
||||
assert_ok!(<Balances as Currency<_>>::transfer(&1, &2, 1));
|
||||
assert_noop!(
|
||||
<Balances as ReservableCurrency<_>>::reserve(&1, 1),
|
||||
"account liquidity restrictions prevent withdrawal"
|
||||
);
|
||||
assert_ok!(<Balances as MakePayment<_>>::make_payment(&1, 1));
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::Reserve.into());
|
||||
assert_ok!(<Balances as Currency<_>>::transfer(&1, &2, 1));
|
||||
assert_noop!(
|
||||
<Balances as ReservableCurrency<_>>::reserve(&1, 1),
|
||||
"account liquidity restrictions prevent withdrawal"
|
||||
);
|
||||
assert_ok!(<Balances as MakePayment<_>>::make_payment(&1, 1));
|
||||
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::TransactionPayment.into());
|
||||
assert_ok!(<Balances as Currency<_>>::transfer(&1, &2, 1));
|
||||
assert_ok!(<Balances as ReservableCurrency<_>>::reserve(&1, 1));
|
||||
assert_noop!(
|
||||
<Balances as MakePayment<_>>::make_payment(&1, 1),
|
||||
"account liquidity restrictions prevent withdrawal"
|
||||
);
|
||||
});
|
||||
Balances::set_lock(ID_1, &1, 10, u64::max_value(), WithdrawReason::TransactionPayment.into());
|
||||
assert_ok!(<Balances as Currency<_>>::transfer(&1, &2, 1));
|
||||
assert_ok!(<Balances as ReservableCurrency<_>>::reserve(&1, 1));
|
||||
assert_noop!(
|
||||
<Balances as MakePayment<_>>::make_payment(&1, 1),
|
||||
"account liquidity restrictions prevent withdrawal"
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -204,8 +210,9 @@ fn default_indexing_on_new_accounts_should_not_work2() {
|
||||
.monied(true)
|
||||
.build(),
|
||||
|| {
|
||||
|
||||
assert_eq!(Balances::is_dead_account(&5), true); // account 5 should not exist
|
||||
// account 1 has 256 * 10 = 2560, account 5 is not exist, ext_deposit is 10, value is 9, not satisfies for ext_deposit
|
||||
// ext_deposit is 10, value is 9, not satisfies for ext_deposit
|
||||
assert_noop!(
|
||||
Balances::transfer(Some(1).into(), 5, 9),
|
||||
"value too low to create account"
|
||||
@@ -235,16 +242,19 @@ fn reserved_balance_should_prevent_reclaim_count() {
|
||||
assert_eq!(Balances::is_dead_account(&2), false);
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); // account 4 tries to take index 1 for account 5.
|
||||
// account 4 tries to take index 1 for account 5.
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69));
|
||||
assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::is_dead_account(&5), false);
|
||||
|
||||
assert!(Balances::slash(&2, 256 * 18 + 2).1.is_zero()); // account 2 gets slashed
|
||||
assert_eq!(Balances::total_balance(&2), 0); // "reserve" account reduced to 255 (below ED) so account deleted
|
||||
// "reserve" account reduced to 255 (below ED) so account deleted
|
||||
assert_eq!(Balances::total_balance(&2), 0);
|
||||
assert_eq!(System::account_nonce(&2), 0); // nonce zero
|
||||
assert_eq!(Balances::is_dead_account(&2), true);
|
||||
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69)); // account 4 tries to take index 1 again for account 6.
|
||||
// account 4 tries to take index 1 again for account 6.
|
||||
assert_ok!(Balances::transfer(Some(4).into(), 6, 256 * 1 + 0x69));
|
||||
assert_eq!(Balances::total_balance(&6), 256 * 1 + 0x69);
|
||||
assert_eq!(Balances::is_dead_account(&6), false);
|
||||
},
|
||||
@@ -258,7 +268,7 @@ fn reward_should_work() {
|
||||
assert_eq!(Balances::total_balance(&1), 10);
|
||||
assert_ok!(Balances::deposit_into_existing(&1, 10).map(drop));
|
||||
assert_eq!(Balances::total_balance(&1), 20);
|
||||
assert_eq!(<TotalIssuance<Runtime>>::get(), 110);
|
||||
assert_eq!(<TotalIssuance<Runtime>>::get(), 120);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -294,7 +304,8 @@ fn dust_account_removal_should_work2() {
|
||||
System::inc_account_nonce(&2);
|
||||
assert_eq!(System::account_nonce(&2), 1);
|
||||
assert_eq!(Balances::total_balance(&2), 2000);
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5, 1851)); // index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit)
|
||||
// index 1 (account 2) becomes zombie for 256*10 + 50(fee) < 256 * 10 (ext_deposit)
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 5, 1851));
|
||||
assert_eq!(Balances::total_balance(&2), 0);
|
||||
assert_eq!(Balances::total_balance(&5), 1851);
|
||||
assert_eq!(System::account_nonce(&2), 0);
|
||||
@@ -571,32 +582,52 @@ fn check_vesting_status() {
|
||||
assert_eq!(System::block_number(), 1);
|
||||
let user1_free_balance = Balances::free_balance(&1);
|
||||
let user2_free_balance = Balances::free_balance(&2);
|
||||
let user12_free_balance = Balances::free_balance(&12);
|
||||
assert_eq!(user1_free_balance, 256 * 10); // Account 1 has free balance
|
||||
assert_eq!(user2_free_balance, 256 * 20); // Account 2 has free balance
|
||||
assert_eq!(user12_free_balance, 256 * 10); // Account 12 has free balance
|
||||
let user1_vesting_schedule = VestingSchedule {
|
||||
offset: 256 * 10,
|
||||
per_block: 256,
|
||||
locked: 256 * 5,
|
||||
per_block: 128, // Vesting over 10 blocks
|
||||
starting_block: 0,
|
||||
};
|
||||
let user2_vesting_schedule = VestingSchedule {
|
||||
offset: 256 * 30,
|
||||
per_block: 256,
|
||||
locked: 256 * 20,
|
||||
per_block: 256, // Vesting over 20 blocks
|
||||
starting_block: 10,
|
||||
};
|
||||
let user12_vesting_schedule = VestingSchedule {
|
||||
locked: 256 * 5,
|
||||
per_block: 64, // Vesting over 20 blocks
|
||||
starting_block: 10,
|
||||
};
|
||||
assert_eq!(Balances::vesting(&1), Some(user1_vesting_schedule)); // Account 1 has a vesting schedule
|
||||
assert_eq!(Balances::vesting(&2), Some(user2_vesting_schedule)); // Account 2 has a vesting schedule
|
||||
assert_eq!(Balances::vesting(&12), Some(user12_vesting_schedule)); // Account 12 has a vesting schedule
|
||||
|
||||
assert_eq!(Balances::vesting_balance(&1), user1_free_balance - 256); // Account 1 has only 256 units vested at block 1
|
||||
// Account 1 has only 128 units vested from their illiquid 256 * 5 units at block 1
|
||||
assert_eq!(Balances::vesting_balance(&1), 128 * 9);
|
||||
// Account 2 has their full balance locked
|
||||
assert_eq!(Balances::vesting_balance(&2), user2_free_balance);
|
||||
// Account 12 has only their illiquid funds locked
|
||||
assert_eq!(Balances::vesting_balance(&12), user12_free_balance - 256 * 5);
|
||||
|
||||
System::set_block_number(10);
|
||||
assert_eq!(System::block_number(), 10);
|
||||
|
||||
assert_eq!(Balances::vesting_balance(&1), 0); // Account 1 has fully vested by block 10
|
||||
assert_eq!(Balances::vesting_balance(&2), user2_free_balance); // Account 2 has started vesting by block 10
|
||||
// Account 1 has fully vested by block 10
|
||||
assert_eq!(Balances::vesting_balance(&1), 0);
|
||||
// Account 2 has started vesting by block 10
|
||||
assert_eq!(Balances::vesting_balance(&2), user2_free_balance);
|
||||
// Account 12 has started vesting by block 10
|
||||
assert_eq!(Balances::vesting_balance(&12), user12_free_balance - 256 * 5);
|
||||
|
||||
System::set_block_number(30);
|
||||
assert_eq!(System::block_number(), 30);
|
||||
|
||||
assert_eq!(Balances::vesting_balance(&1), 0); // Account 1 is still fully vested, and not negative
|
||||
assert_eq!(Balances::vesting_balance(&2), 0); // Account 2 has fully vested by block 30
|
||||
assert_eq!(Balances::vesting_balance(&12), 0); // Account 2 has fully vested by block 30
|
||||
|
||||
}
|
||||
);
|
||||
@@ -614,9 +645,10 @@ fn unvested_balance_should_not_transfer() {
|
||||
assert_eq!(System::block_number(), 1);
|
||||
let user1_free_balance = Balances::free_balance(&1);
|
||||
assert_eq!(user1_free_balance, 100); // Account 1 has free balance
|
||||
assert_eq!(Balances::vesting_balance(&1), 90); // Account 1 has only 10 units vested at block 1
|
||||
// Account 1 has only 5 units vested at block 1 (plus 50 unvested)
|
||||
assert_eq!(Balances::vesting_balance(&1), 45);
|
||||
assert_noop!(
|
||||
Balances::transfer(Some(1).into(), 2, 11),
|
||||
Balances::transfer(Some(1).into(), 2, 56),
|
||||
"vesting balance too high to send value"
|
||||
); // Account 1 cannot send more than vested amount
|
||||
}
|
||||
@@ -635,8 +667,9 @@ fn vested_balance_should_transfer() {
|
||||
assert_eq!(System::block_number(), 1);
|
||||
let user1_free_balance = Balances::free_balance(&1);
|
||||
assert_eq!(user1_free_balance, 100); // Account 1 has free balance
|
||||
assert_eq!(Balances::vesting_balance(&1), 90); // Account 1 has only 10 units vested at block 1
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2, 10));
|
||||
// Account 1 has only 5 units vested at block 1 (plus 50 unvested)
|
||||
assert_eq!(Balances::vesting_balance(&1), 45);
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2, 55));
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -652,11 +685,51 @@ fn extra_balance_should_transfer() {
|
||||
|| {
|
||||
assert_eq!(System::block_number(), 1);
|
||||
assert_ok!(Balances::transfer(Some(3).into(), 1, 100));
|
||||
assert_ok!(Balances::transfer(Some(3).into(), 2, 100));
|
||||
|
||||
let user1_free_balance = Balances::free_balance(&1);
|
||||
assert_eq!(user1_free_balance, 200); // Account 1 has 100 more free balance than normal
|
||||
|
||||
assert_eq!(Balances::vesting_balance(&1), 90); // Account 1 has 90 units vested at block 1
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 2, 105)); // Account 1 can send extra units gained
|
||||
let user2_free_balance = Balances::free_balance(&2);
|
||||
assert_eq!(user2_free_balance, 300); // Account 2 has 100 more free balance than normal
|
||||
|
||||
// Account 1 has only 5 units vested at block 1 (plus 150 unvested)
|
||||
assert_eq!(Balances::vesting_balance(&1), 45);
|
||||
assert_ok!(Balances::transfer(Some(1).into(), 3, 155)); // Account 1 can send extra units gained
|
||||
|
||||
// Account 2 has no units vested at block 1, but gained 100
|
||||
assert_eq!(Balances::vesting_balance(&2), 200);
|
||||
assert_ok!(Balances::transfer(Some(2).into(), 3, 100)); // Account 2 can send extra units gained
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn liquid_funds_should_transfer_with_delayed_vesting() {
|
||||
with_externalities(
|
||||
&mut ExtBuilder::default()
|
||||
.existential_deposit(256)
|
||||
.monied(true)
|
||||
.vesting(true)
|
||||
.build(),
|
||||
|| {
|
||||
assert_eq!(System::block_number(), 1);
|
||||
let user12_free_balance = Balances::free_balance(&12);
|
||||
|
||||
assert_eq!(user12_free_balance, 2560); // Account 12 has free balance
|
||||
// Account 12 has liquid funds
|
||||
assert_eq!(Balances::vesting_balance(&12), user12_free_balance - 256 * 5);
|
||||
|
||||
// Account 12 has delayed vesting
|
||||
let user12_vesting_schedule = VestingSchedule {
|
||||
locked: 256 * 5,
|
||||
per_block: 64, // Vesting over 20 blocks
|
||||
starting_block: 10,
|
||||
};
|
||||
assert_eq!(Balances::vesting(&12), Some(user12_vesting_schedule));
|
||||
|
||||
// Account 12 can still send liquid funds
|
||||
assert_ok!(Balances::transfer(Some(12).into(), 3, 256 * 5));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user