Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fortify mosaic & vesting pallets #779

Merged
merged 3 commits into from
Mar 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions frame/bonded-finance/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{AssetIdOf, BalanceOf, BlockNumberOf, BondOfferOf, Call, Config, Pall
use codec::Decode;
use composable_support::validation::Validated;
use composable_traits::bonded_finance::{BondDuration, BondOffer, BondOfferReward};
use frame_benchmarking::{benchmarks, impl_benchmark_test_suite, whitelisted_caller};
use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller};
use frame_support::{
dispatch::UnfilteredDispatchable,
traits::{fungible::Mutate as _, fungibles::Mutate as _},
Expand Down Expand Up @@ -83,17 +83,18 @@ benchmarks! {
where_clause {
where BalanceOf<T>: From<u128>
}

offer {
let [bond_asset, reward_asset] = assets::<T>();
let caller: T::AccountId = whitelisted_caller();
let caller: T::AccountId = account("caller", 0, 0xCAFEBABE);
initial_mint::<T>(bond_asset, &caller, reward_asset);
let bond_offer = bond_offer::<T>(bond_asset, reward_asset);
let validated_bond_offer = Validated::new(bond_offer).unwrap();
}: _(RawOrigin::Signed(caller), validated_bond_offer, false)

bond {
let [bond_asset, reward_asset] = assets::<T>();
let caller: T::AccountId = whitelisted_caller();
let caller: T::AccountId = account("caller", 0, 0xCAFEBABE);
initial_mint::<T>(bond_asset, &caller, reward_asset);
let bond_offer = bond_offer::<T>(bond_asset, reward_asset);
let nb_of_bonds = bond_offer.nb_of_bonds;
Expand All @@ -103,7 +104,7 @@ benchmarks! {

cancel {
let [bond_asset, reward_asset] = assets::<T>();
let caller: T::AccountId = whitelisted_caller();
let caller: T::AccountId = account("caller", 0, 0xCAFEBABE);
initial_mint::<T>(bond_asset, &caller, reward_asset);
let bond_offer = bond_offer::<T>(bond_asset, reward_asset);
let nb_of_bonds = bond_offer.nb_of_bonds;
Expand Down
2 changes: 0 additions & 2 deletions frame/bonded-finance/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ use frame_support::{
use mock::{Event, *};
use proptest::prelude::*;

#[test]

prop_compose! {
// NOTE(hussein-aitlahcen): we use u32 before casting to avoid overflows
/// Pseudo random valid simple offer
Expand Down
9 changes: 9 additions & 0 deletions frame/mosaic/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use frame_support::{
traits::{fungibles::Mutate, Get},
};
use frame_system::RawOrigin;
const MIN_TRANSFER_SIZE: u128 = 1_000_000_000_000;
const MAX_TRANSFER_SIZE: u128 = 100_000_000_000_000_000;
const BUDGET_AMOUNT: u128 = 100_000_000_000_000_000_000;
const TRANSFER_AMOUNT: u128 = 100_000_000_000_000;
Expand Down Expand Up @@ -36,6 +37,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};

Expand All @@ -55,6 +57,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};
assert_ok!(Mosaic::<T>::set_network(RawOrigin::Signed(relayer).into(), network_id.clone(), network_info));
Expand Down Expand Up @@ -82,6 +85,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};
assert_ok!(Mosaic::<T>::set_network(RawOrigin::Signed(relayer.clone()).into(), network_id.clone(), network_info));
Expand Down Expand Up @@ -110,6 +114,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};
assert_ok!(Mosaic::<T>::set_network(RawOrigin::Signed(relayer.clone()).into(), network_id.clone(), network_info));
Expand Down Expand Up @@ -139,6 +144,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};
assert_ok!(Mosaic::<T>::set_network(RawOrigin::Signed(relayer.clone()).into(), network_id.clone(), network_info));
Expand Down Expand Up @@ -174,6 +180,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};
assert_ok!(Mosaic::<T>::set_network(RawOrigin::Signed(relayer.clone()).into(), network_id.clone(), network_info));
Expand Down Expand Up @@ -209,6 +216,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};
assert_ok!(Mosaic::<T>::set_network(RawOrigin::Signed(relayer.clone()).into(), network_id.clone(), network_info));
Expand Down Expand Up @@ -244,6 +252,7 @@ benchmarks! {
let network_id: T::NetworkId = 1.into();
let network_info = NetworkInfo {
enabled: true,
min_transfer_size: MIN_TRANSFER_SIZE.into(),
max_transfer_size: MAX_TRANSFER_SIZE.into(),
};

Expand Down
3 changes: 3 additions & 0 deletions frame/mosaic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ pub mod pallet {
#[derive(Clone, Debug, Encode, Decode, MaxEncodedLen, TypeInfo, PartialEq)]
pub struct NetworkInfo<Balance> {
pub enabled: bool,
pub min_transfer_size: Balance,
pub max_transfer_size: Balance,
}

Expand Down Expand Up @@ -341,6 +342,7 @@ pub mod pallet {
NoStaleTransactions,
InsufficientBudget,
ExceedsMaxTransferSize,
BelowMinTransferSize,
NoClaimableTx,
TxStillLocked,
NoOutgoingTx,
Expand Down Expand Up @@ -462,6 +464,7 @@ pub mod pallet {
NetworkInfos::<T>::get(network_id.clone()).ok_or(Error::<T>::UnsupportedNetwork)?;
ensure!(network_info.enabled, Error::<T>::NetworkDisabled);
ensure!(network_info.max_transfer_size >= amount, Error::<T>::ExceedsMaxTransferSize);
ensure!(network_info.min_transfer_size <= amount, Error::<T>::BelowMinTransferSize);
vimukthi-git marked this conversation as resolved.
Show resolved Hide resolved

T::Assets::transfer(
asset_id,
Expand Down
86 changes: 69 additions & 17 deletions frame/mosaic/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::validation::{ValidTTL, ValidTimeLockPeriod};
/// TODO
///
/// 1. Test each extrinsic
Expand Down Expand Up @@ -223,7 +222,8 @@ mod set_network {
#[test]
fn relayer_can_set_network() {
let network_id = 3;
let network_info = NetworkInfo { enabled: false, max_transfer_size: 100000 };
let network_info =
NetworkInfo { enabled: false, min_transfer_size: 1, max_transfer_size: 100000 };
new_test_ext().execute_with(|| {
assert_ok!(Mosaic::set_relayer(Origin::root(), RELAYER));

Expand All @@ -235,7 +235,8 @@ mod set_network {
#[test]
fn root_cannot_set_network() {
let network_id = 3;
let network_info = NetworkInfo { enabled: false, max_transfer_size: 100000 };
let network_info =
NetworkInfo { enabled: false, min_transfer_size: 1, max_transfer_size: 100000 };
new_test_ext().execute_with(|| {
assert_ok!(Mosaic::set_relayer(Origin::root(), RELAYER));

Expand All @@ -249,7 +250,8 @@ mod set_network {
#[test]
fn none_cannot_set_network() {
let network_id = 3;
let network_info = NetworkInfo { enabled: false, max_transfer_size: 100000 };
let network_info =
NetworkInfo { enabled: false, min_transfer_size: 1, max_transfer_size: 100000 };
new_test_ext().execute_with(|| {
assert_ok!(Mosaic::set_relayer(Origin::root(), RELAYER));

Expand Down Expand Up @@ -391,7 +393,7 @@ fn initialize() {
assert_ok!(Mosaic::set_network(
Origin::relayer(),
1,
NetworkInfo { enabled: true, max_transfer_size: 100000 },
NetworkInfo { enabled: true, min_transfer_size: 1, max_transfer_size: 100000 },
));
assert_ok!(Mosaic::set_budget(Origin::root(), 1, BUDGET, BudgetPenaltyDecayer::linear(10)));
assert_ok!(Mosaic::update_asset_mapping(
Expand Down Expand Up @@ -617,10 +619,11 @@ mod timelocked_mint {
fn can_mint_up_to_the_penalised_budget(
account_a in account_id(),
decay in 1..100u128, // todo,
max_transfer_size in 1..10_000_000u128,
min_transfer_size in 1..10_000_000u128,
max_transfer_size in 10_000_000u128..100_000_000u128,
asset_id in 1..100u128,
network_id in 1..100u32,
remote_asset_id in any::<RemoteAssetId>(),
remote_asset_id in any::<RemoteAssetId>(),
start_block in 1..10_000u64,
(budget, first_part, second_part) in budget_with_split(),
) {
Expand All @@ -632,7 +635,7 @@ mod timelocked_mint {
prop_assert_ok!(Mosaic::set_network(
Origin::relayer(),
network_id,
NetworkInfo { enabled: true, max_transfer_size },
NetworkInfo { enabled: true, min_transfer_size, max_transfer_size },
), "relayer may set network info");
prop_assert_ok!(Mosaic::set_budget(Origin::root(), asset_id, budget, BudgetPenaltyDecayer::linear(decay)), "root may set budget");
prop_assert_ok!(Mosaic::update_asset_mapping(Origin::root(), asset_id, network_id, Some(remote_asset_id)));
Expand All @@ -654,10 +657,11 @@ mod timelocked_mint {
fn cannot_mint_more_than_the_penalised_budget(
account_a in account_id(),
decay in 1..100u128, // todo,
max_transfer_size in 1..10_000_000u128,
min_transfer_size in 1..10_000_000u128,
max_transfer_size in 10_000_000u128..100_000_000u128,
asset_id in 1..100u128,
network_id in 1..100u32,
remote_asset_id in any::<RemoteAssetId>(),
remote_asset_id in any::<RemoteAssetId>(),
start_block in 1..10_000u64,
(budget, first_part, second_part) in budget_with_split(),
) {
Expand All @@ -669,7 +673,7 @@ mod timelocked_mint {
prop_assert_ok!(Mosaic::set_network(
Origin::relayer(),
network_id,
NetworkInfo { enabled: true, max_transfer_size },
NetworkInfo { enabled: true, min_transfer_size, max_transfer_size },
), "relayer may set network info");
prop_assert_ok!(Mosaic::set_budget(Origin::root(), asset_id, budget, BudgetPenaltyDecayer::linear(decay)), "root may set budget");
prop_assert_ok!(Mosaic::update_asset_mapping(Origin::root(), asset_id, network_id, Some(remote_asset_id)));
Expand All @@ -692,10 +696,11 @@ mod timelocked_mint {
fn should_be_able_to_mint_again_after_waiting_for_penalty_to_decay(
account_a in account_id(),
decay_factor in 1..100u128, // todo,
max_transfer_size in 1..10_000_000u128,
min_transfer_size in 1..10_000_000u128,
max_transfer_size in 10_000_000u128..100_000_000u128,
asset_id in 1..100u128,
network_id in 1..100u32,
remote_asset_id in any::<RemoteAssetId>(),
remote_asset_id in any::<RemoteAssetId>(),
start_block in 1..10_000u64,
(budget, first_part, second_part) in budget_with_split(),
iteration_count in 2..10u64,
Expand All @@ -713,7 +718,7 @@ mod timelocked_mint {
prop_assert_ok!(Mosaic::set_network(
Origin::relayer(),
network_id,
NetworkInfo { enabled: true, max_transfer_size },
NetworkInfo { enabled: true, min_transfer_size, max_transfer_size },
), "relayer may set network info");
prop_assert_ok!(Mosaic::set_budget(Origin::root(), asset_id, budget, budget_penalty_decayer.clone()), "root may set budget");
prop_assert_ok!(Mosaic::update_asset_mapping(Origin::root(), asset_id, network_id, Some(remote_asset_id)));
Expand Down Expand Up @@ -1031,9 +1036,57 @@ mod transfer_to {
})
}

#[test]
fn transfer_to_below_min_transfer_size() {
ExtBuilder { balances: Default::default() }.build().execute_with(|| {
let min_transfer_size = 1000;
let max_transfer_size = 100000;

assert_ok!(Mosaic::set_relayer(Origin::root(), RELAYER));

let network_id = 1;
assert_ok!(Mosaic::set_network(
Origin::relayer(),
network_id,
NetworkInfo { enabled: true, min_transfer_size, max_transfer_size },
));

let asset_id: u128 = 1;
assert_ok!(Mosaic::set_budget(
Origin::root(),
asset_id,
10000,
BudgetPenaltyDecayer::linear(10)
));

let remote_asset_id = [0xFFu8; 20];
assert_ok!(Mosaic::update_asset_mapping(
Origin::root(),
asset_id,
network_id,
Some(remote_asset_id)
));

let amount = min_transfer_size - 1;
assert_ok!(Tokens::mint_into(asset_id, &ALICE, amount));
assert_noop!(
Mosaic::transfer_to(
Origin::signed(ALICE),
network_id,
asset_id,
[0; 20],
amount,
true
),
Error::<Test>::BelowMinTransferSize
);
})
}

#[test]
fn transfer_to_exceeds_max_transfer_size() {
ExtBuilder { balances: Default::default() }.build().execute_with(|| {
let min_transfer_size = 1;
let max_transfer_size = 100000;

assert_ok!(Mosaic::set_relayer(Origin::root(), RELAYER));
Expand All @@ -1042,7 +1095,7 @@ mod transfer_to {
assert_ok!(Mosaic::set_network(
Origin::relayer(),
network_id,
NetworkInfo { enabled: true, max_transfer_size },
NetworkInfo { enabled: true, min_transfer_size, max_transfer_size },
));

let asset_id: u128 = 1;
Expand Down Expand Up @@ -1114,7 +1167,7 @@ mod transfer_to {
assert_ok!(Mosaic::set_network(
Origin::relayer(),
1,
NetworkInfo { enabled: true, max_transfer_size: 100000 },
NetworkInfo { enabled: true, min_transfer_size: 1, max_transfer_size: 100000 },
));

// We don't register the asset
Expand Down Expand Up @@ -1268,7 +1321,6 @@ mod test_validation {
use super::*;
use composable_support::validation::Validate;
use frame_support::assert_ok;
use mock::Test;
use validation::{ValidTTL, ValidTimeLockPeriod};

#[test]
Expand Down
2 changes: 1 addition & 1 deletion frame/vesting/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ benchmarks! {

vested_transfer {
let asset_id = asset::<T>();
let from: T::AccountId = zero_account::<T>();
let from: T::AccountId = create_account::<T>("from", 0xCAFEBABE);
fund_account::<T>(&from, asset_id.clone(), FUNDING.into());
let dest = T::Lookup::unlookup(create_account::<T>("dest", 1));
let per_period = T::MinVestedTransfer::get();
Expand Down
4 changes: 4 additions & 0 deletions frame/vesting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ pub mod module {
AmountLow,
/// Failed because the maximum vesting schedules was exceeded
MaxVestingSchedulesExceeded,
/// Trying to vest to ourselves
TryingToSelfVest,
}

#[pallet::event]
Expand Down Expand Up @@ -307,6 +309,8 @@ impl<T: Config> VestedTransfer for Pallet<T> {
to: &Self::AccountId,
schedule: VestingSchedule<Self::BlockNumber, Self::Moment, Self::Balance>,
) -> frame_support::dispatch::DispatchResult {
ensure!(from != to, Error::<T>::TryingToSelfVest);

let schedule_amount = ensure_valid_vesting_schedule::<T>(&schedule)?;

let total_amount = Self::locked_balance(to, asset)
Expand Down
23 changes: 23 additions & 0 deletions frame/vesting/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,29 @@ fn vesting_from_chain_spec_works() {
});
}

#[test]
fn vested_transfer_self_vest_ko() {
ExtBuilder::build().execute_with(|| {
System::set_block_number(1);

let schedule = VestingSchedule {
window: BlockNumberBased { start: 0_u64, period: 10_u64 },
period_count: 1_u32,
per_period: 100_u64,
};
assert_noop!(
Vesting::vested_transfer(
Origin::root(),
ALICE,
ALICE,
MockCurrencyId::BTC,
schedule.clone(),
),
Error::<Runtime>::TryingToSelfVest
);
});
}

#[test]
fn vested_transfer_works() {
ExtBuilder::build().execute_with(|| {
Expand Down