diff --git a/Cargo.lock b/Cargo.lock index 7872e4e3e3..af281e85d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3777,6 +3777,7 @@ dependencies = [ "hex-literal 0.3.4", "interbtc-primitives", "issue", + "itertools", "mocktopus", "module-btc-relay-rpc-runtime-api", "module-issue-rpc-runtime-api", diff --git a/crates/escrow/src/lib.rs b/crates/escrow/src/lib.rs index 38c010ada3..28d71c6ed3 100644 --- a/crates/escrow/src/lib.rs +++ b/crates/escrow/src/lib.rs @@ -196,7 +196,7 @@ pub mod pallet { /// Previous lock has expired. LockHasExpired, /// Lock amount is too large. - LockAmountTooLarge, + LockAmountTooLow, /// Insufficient account balance. InsufficientFunds, /// Not supported. @@ -490,7 +490,7 @@ impl Pallet { // total amount can't be less than the max period to prevent rounding errors ensure!( new_locked.amount >= T::BlockNumberToBalance::convert(T::MaxPeriod::get()), - Error::::LockAmountTooLarge, + Error::::LockAmountTooLow, ); ensure!( diff --git a/crates/escrow/src/tests.rs b/crates/escrow/src/tests.rs index 1ca243fa21..a4b9567879 100644 --- a/crates/escrow/src/tests.rs +++ b/crates/escrow/src/tests.rs @@ -205,7 +205,7 @@ fn should_not_allow_amount_smaller_than_max_period() { >::make_free_balance_be(&ALICE, amount); assert_err!( Escrow::create_lock(Origin::signed(ALICE), amount, end_time), - TestError::LockAmountTooLarge + TestError::LockAmountTooLow ); }) } diff --git a/standalone/runtime/Cargo.toml b/standalone/runtime/Cargo.toml index dafdfe3d27..5c3f57d156 100644 --- a/standalone/runtime/Cargo.toml +++ b/standalone/runtime/Cargo.toml @@ -99,6 +99,7 @@ mocktopus = "0.7.0" serde_json = "1.0" pretty_assertions = "0.7.2" flate2= "1.0" +itertools = "0.10.0" bitcoin = { path = "../../crates/bitcoin", default-features = false } diff --git a/standalone/runtime/tests/mock/mod.rs b/standalone/runtime/tests/mock/mod.rs index 7e36ef1e26..6139a2a44d 100644 --- a/standalone/runtime/tests/mock/mod.rs +++ b/standalone/runtime/tests/mock/mod.rs @@ -55,6 +55,7 @@ pub mod redeem_testing_utils; pub mod replace_testing_utils; pub mod reward_testing_utils; +pub use itertools::Itertools; pub use pretty_assertions::assert_eq; pub type VaultId = DefaultVaultId; @@ -355,7 +356,7 @@ pub fn iter_currency_pairs() -> impl Iterator impl Iterator { - vec![Token(DOT), Token(KSM), ForeignAsset(1)].into_iter() + vec![Token(DOT), Token(KSM), Token(INTR), ForeignAsset(1)].into_iter() } pub fn iter_native_currencies() -> impl Iterator { @@ -1355,6 +1356,7 @@ impl ExtBuilder { .flat_map(|(account, balance)| { iter_collateral_currencies() .chain(iter_native_currencies()) + .unique() .map(move |currency| (account.clone(), currency, balance)) }) .chain(iter_wrapped_currencies().map(move |currency| (account_of(FAUCET), currency, 1 << 60))) diff --git a/standalone/runtime/tests/test_escrow.rs b/standalone/runtime/tests/test_escrow.rs index 201bbed2bc..ecbd2ada61 100644 --- a/standalone/runtime/tests/test_escrow.rs +++ b/standalone/runtime/tests/test_escrow.rs @@ -52,6 +52,37 @@ fn integration_test_individual_balance_and_total_supply() { }); } +#[test] +fn integration_test_lock_reserved() { + // check that locking does not touch the reserved balance + ExtBuilder::build().execute_with(|| { + let span = ::Span::get(); + let current_height = SystemPallet::block_number(); + let lock_amount = 1000_000_000_000_000; + let initial_free = 1500_000_000_000_000; + let initial_reserved = 500_000_000_000_000; + + assert_ok!(Call::Tokens(TokensCall::set_balance { + who: account_of(ALICE), + currency_id: DEFAULT_NATIVE_CURRENCY, + new_free: initial_free, + new_reserved: initial_reserved, + }) + .dispatch(root())); + + assert_ok!(Call::Escrow(EscrowCall::create_lock { + amount: lock_amount, + unlock_height: current_height + span + }) + .dispatch(origin_of(account_of(ALICE)))); + + let account = orml_tokens::Pallet::::accounts(account_of(ALICE), DEFAULT_NATIVE_CURRENCY); + assert_eq!(account.free, initial_free); + assert_eq!(account.reserved, initial_reserved); + assert_eq!(account.frozen, lock_amount); + }); +} + fn ensure_reward_stake_is_escrow_balance(height: BlockNumber) { assert_ok!( >::get_stake(&account_of(ALICE)), diff --git a/standalone/runtime/tests/test_vault_registry.rs b/standalone/runtime/tests/test_vault_registry.rs index c89e2720b4..8a08e2a3c5 100644 --- a/standalone/runtime/tests/test_vault_registry.rs +++ b/standalone/runtime/tests/test_vault_registry.rs @@ -94,6 +94,42 @@ mod deposit_collateral_test { }); } + #[test] + fn integration_test_vault_registry_lock_additional_using_locked_tokens_fails() { + ExtBuilder::build().execute_with(|| { + let vault_id = VaultId::new(account_of(VAULT), DEFAULT_NATIVE_CURRENCY, DEFAULT_WRAPPED_CURRENCY); + + let currency_id = vault_id.collateral_currency(); + + let amount_1 = 1000_000_000_000_000; + + let mut vault_data = default_vault_state(&vault_id); + *vault_data.free_balance.get_mut(¤cy_id).unwrap() = Amount::new(amount_1, currency_id); + CoreVaultData::force_to(&vault_id, vault_data); + + let q = currency::get_free_balance::(currency_id, &vault_id.account_id); + assert_eq!(q.amount(), amount_1); + + let span = ::Span::get(); + let current_height = SystemPallet::block_number(); + + assert_ok!(Call::Escrow(EscrowCall::create_lock { + amount: amount_1 / 2, + unlock_height: current_height + span + }) + .dispatch(origin_of(vault_id.account_id.clone()))); + + assert_noop!( + Call::VaultRegistry(VaultRegistryCall::deposit_collateral { + currency_pair: vault_id.currencies.clone(), + amount: amount_1 + }) + .dispatch(origin_of(vault_id.account_id.clone())), + TokensError::LiquidityRestrictions + ); + }); + } + #[test] fn integration_test_vault_registry_lock_additional_respects_fund_limit() { test_with(|vault_id| {