diff --git a/crates/nomination/src/ext.rs b/crates/nomination/src/ext.rs index cdd8af0091..f1e33244cb 100644 --- a/crates/nomination/src/ext.rs +++ b/crates/nomination/src/ext.rs @@ -29,11 +29,11 @@ pub(crate) mod vault_registry { >::compute_collateral(vault_id) } - pub fn is_allowed_to_withdraw_collateral( + pub fn is_nominator_allowed_to_withdraw_collateral( vault_id: &DefaultVaultId, amount: &Amount, ) -> Result { - >::is_allowed_to_withdraw_collateral(vault_id, amount) + >::is_nominator_allowed_to_withdraw_collateral(vault_id, amount) } pub fn try_increase_total_backing_collateral( diff --git a/crates/nomination/src/lib.rs b/crates/nomination/src/lib.rs index e6d8249424..5059c5848a 100644 --- a/crates/nomination/src/lib.rs +++ b/crates/nomination/src/lib.rs @@ -247,7 +247,7 @@ impl Pallet { // we can only withdraw nominated collateral if the vault is still // above the secure threshold for issued + to_be_issued tokens ensure!( - ext::vault_registry::is_allowed_to_withdraw_collateral::(vault_id, &amount)?, + ext::vault_registry::is_nominator_allowed_to_withdraw_collateral::(vault_id, &amount)?, Error::::CannotWithdrawCollateral ); @@ -332,7 +332,10 @@ impl Pallet { ensure!(Self::is_opted_in(&vault_id), Error::::VaultNotOptedInToNomination); let total_nominated_collateral = Self::get_total_nominated_collateral(&vault_id)?; ensure!( - ext::vault_registry::is_allowed_to_withdraw_collateral::(&vault_id, &total_nominated_collateral)?, + ext::vault_registry::is_nominator_allowed_to_withdraw_collateral::( + &vault_id, + &total_nominated_collateral + )?, Error::::CollateralizationTooLow ); diff --git a/crates/replace/src/ext.rs b/crates/replace/src/ext.rs index b1a2037436..185fb2710b 100644 --- a/crates/replace/src/ext.rs +++ b/crates/replace/src/ext.rs @@ -135,11 +135,11 @@ pub(crate) mod vault_registry { >::force_withdraw_collateral(vault_id, amount) } - pub fn is_allowed_to_withdraw_collateral( + pub fn is_vault_allowed_to_withdraw_collateral( vault_id: &DefaultVaultId, amount: &Amount, ) -> Result { - >::is_allowed_to_withdraw_collateral(vault_id, amount) + >::is_vault_allowed_to_withdraw_collateral(vault_id, amount) } pub fn calculate_collateral( diff --git a/crates/replace/src/lib.rs b/crates/replace/src/lib.rs index ad5c4b82b4..029b094b15 100644 --- a/crates/replace/src/lib.rs +++ b/crates/replace/src/lib.rs @@ -594,7 +594,7 @@ impl Pallet { // if the new_vault locked additional collateral especially for this replace, // release it if it does not cause them to be undercollateralized if !ext::vault_registry::is_vault_liquidated::(&new_vault_id)? - && ext::vault_registry::is_allowed_to_withdraw_collateral::(&new_vault_id, &collateral)? + && ext::vault_registry::is_vault_allowed_to_withdraw_collateral::(&new_vault_id, &collateral)? { ext::vault_registry::force_withdraw_collateral::(&new_vault_id, &collateral)?; } diff --git a/crates/replace/src/tests.rs b/crates/replace/src/tests.rs index e88e3a9afb..8428688f3b 100644 --- a/crates/replace/src/tests.rs +++ b/crates/replace/src/tests.rs @@ -260,7 +260,8 @@ mod cancel_replace_tests { ext::vault_registry::is_vault_liquidated::.mock_safe(|_| MockResult::Return(Ok(false))); ext::vault_registry::cancel_replace_tokens::.mock_safe(|_, _, _| MockResult::Return(Ok(()))); ext::vault_registry::transfer_funds::.mock_safe(|_, _, _| MockResult::Return(Ok(()))); - ext::vault_registry::is_allowed_to_withdraw_collateral::.mock_safe(|_, _| MockResult::Return(Ok(false))); + ext::vault_registry::is_vault_allowed_to_withdraw_collateral:: + .mock_safe(|_, _| MockResult::Return(Ok(false))); } #[test] diff --git a/crates/vault-registry/src/lib.rs b/crates/vault-registry/src/lib.rs index a6215eb29c..ad75ea55e5 100644 --- a/crates/vault-registry/src/lib.rs +++ b/crates/vault-registry/src/lib.rs @@ -831,9 +831,51 @@ impl Pallet { } /// Checks if the vault would be above the secure threshold after withdrawing collateral + /// + /// # Arguments + /// * `vault_id` - The identifier of the vault. + /// * `amount` - The amount of collateral to be withdrawn. + /// + /// # Returns + /// Returns `Ok(true)` if the vault is allowed to withdraw the collateral, otherwise returns `Ok(false)`. + /// Returns `Err` in case of an error. + pub fn is_vault_allowed_to_withdraw_collateral( + vault_id: &DefaultVaultId, + amount: &Amount, + ) -> Result { + Self::is_allowed_to_withdraw_collateral(vault_id, amount, false) + } + + /// Checks if a nominator is allowed to withdraw collateral. + /// + /// # Arguments + /// * `vault_id` - The identifier of the vault. + /// * `amount` - The amount of collateral to be withdrawn. + /// + /// # Returns + /// Returns `Ok(true)` if the nominator is allowed to withdraw the collateral, otherwise returns `Ok(false)`. + /// Returns `Err` in case of an error. + pub fn is_nominator_allowed_to_withdraw_collateral( + vault_id: &DefaultVaultId, + amount: &Amount, + ) -> Result { + Self::is_allowed_to_withdraw_collateral(vault_id, amount, true) + } + + /// Checks if an entity is allowed to withdraw collateral. + /// + /// # Arguments + /// * `vault_id` - The identifier of the vault. + /// * `amount` - The amount of collateral to be withdrawn. + /// * `is_nominator` - A boolean indicating whether the entity is a nominator. + /// + /// # Returns + /// Returns `Ok(true)` if the entity is allowed to withdraw the collateral, otherwise returns `Ok(false)`. + /// Returns `Err` in case of an error. pub fn is_allowed_to_withdraw_collateral( vault_id: &DefaultVaultId, amount: &Amount, + is_nominator: bool, ) -> Result { let vault = Self::get_rich_vault_from_id(vault_id)?; @@ -842,9 +884,9 @@ impl Pallet { Err(x) if x == ArithmeticError::Underflow.into() => return Ok(false), Err(x) => return Err(x), }; - ensure!( - new_collateral.is_zero() + is_nominator + || new_collateral.is_zero() || new_collateral.ge(&Self::get_minimum_collateral_vault(vault_id.currencies.collateral))?, Error::::InsufficientVaultCollateralAmount ); diff --git a/crates/vault-registry/src/tests.rs b/crates/vault-registry/src/tests.rs index 998f7186fe..1db7df057c 100644 --- a/crates/vault-registry/src/tests.rs +++ b/crates/vault-registry/src/tests.rs @@ -215,17 +215,17 @@ fn should_check_withdraw_collateral() { // should allow withdraw all assert_ok!( - VaultRegistry::is_allowed_to_withdraw_collateral(&DEFAULT_ID, &amount(DEFAULT_COLLATERAL)), + VaultRegistry::is_vault_allowed_to_withdraw_collateral(&DEFAULT_ID, &amount(DEFAULT_COLLATERAL)), true, ); // should allow withdraw above minimum assert_ok!( - VaultRegistry::is_allowed_to_withdraw_collateral(&DEFAULT_ID, &amount(DEFAULT_COLLATERAL / 4)), + VaultRegistry::is_vault_allowed_to_withdraw_collateral(&DEFAULT_ID, &amount(DEFAULT_COLLATERAL / 4)), true, ); // should not allow withdraw above zero, below minimum assert_err!( - VaultRegistry::is_allowed_to_withdraw_collateral(&DEFAULT_ID, &amount(DEFAULT_COLLATERAL / 4 * 3)), + VaultRegistry::is_vault_allowed_to_withdraw_collateral(&DEFAULT_ID, &amount(DEFAULT_COLLATERAL / 4 * 3)), TestError::InsufficientVaultCollateralAmount, ); });