diff --git a/crates/redeem/src/lib.rs b/crates/redeem/src/lib.rs index 2cbccaf2ec..45943d7eb8 100644 --- a/crates/redeem/src/lib.rs +++ b/crates/redeem/src/lib.rs @@ -679,7 +679,7 @@ impl Pallet { amount_to_slash }; - // first update the issued tokens; this logic is the same regardless of whether or not the vault is liquidated + // first update the issued tokens let new_status = if reimburse { // Transfer the transaction fee to the pool. Even though the redeem was not // successful, the user receives a premium in collateral, so it's OK to take the fee. @@ -688,7 +688,14 @@ impl Pallet { fee.transfer(&redeem.redeemer, &ext::fee::fee_pool_account_id::())?; ext::fee::distribute_rewards::(&fee)?; - if ext::vault_registry::is_vault_below_secure_threshold::(&redeem.vault)? { + if vault.is_liquidated() { + // In this situation, tokens are burned and the collateral gets transferred + // to the user. This is similar to what happens in a liquidation_redeem. + vault_to_be_burned_tokens.burn_from(&redeemer)?; + ext::vault_registry::decrease_tokens::(&redeem.vault, &redeem.redeemer, &vault_to_be_burned_tokens)?; + // set to Reimbursed(true) such that the vault can't mint the ibtc/kbtc later on + Self::set_redeem_status(redeem_id, RedeemRequestStatus::Reimbursed(true)) + } else if ext::vault_registry::is_vault_below_secure_threshold::(&redeem.vault)? { // vault can not afford to back the tokens that it would receive, so we burn it vault_to_be_burned_tokens.burn_from(&redeemer)?; ext::vault_registry::decrease_tokens::(&redeem.vault, &redeem.redeemer, &vault_to_be_burned_tokens)?; diff --git a/parachain/runtime/runtime-tests/src/parachain/redeem.rs b/parachain/runtime/runtime-tests/src/parachain/redeem.rs index d6527cf1dc..16cf7ae147 100644 --- a/parachain/runtime/runtime-tests/src/parachain/redeem.rs +++ b/parachain/runtime/runtime-tests/src/parachain/redeem.rs @@ -963,17 +963,15 @@ mod spec_based_tests { // to-be-redeemed decreased, forwarding to liquidation vault vault.to_be_redeemed -= redeem.amount_btc() + redeem.transfer_fee_btc(); liquidation_vault.to_be_redeemed -= redeem.amount_btc() + redeem.transfer_fee_btc(); + liquidation_vault.issued -= redeem.amount_btc() + redeem.transfer_fee_btc(); *fee_pool.rewards_for(&vault_id) += redeem.fee(); // the collateral that remained with the vault to back this redeem is now transferred to the - // liquidation vault + // user let collateral_for_this_redeem = collateral_vault / 4; vault.liquidated_collateral -= collateral_for_this_redeem; - *vault.free_balance.get_mut(&vault_id.wrapped_currency()).unwrap() += - redeem.amount_btc() + redeem.transfer_fee_btc(); - // user's tokens get unlocked (*user.balances.get_mut(&vault_id.wrapped_currency()).unwrap()).locked -= redeem.amount_btc() + redeem.fee() + redeem.transfer_fee_btc(); @@ -1780,10 +1778,12 @@ fn integration_test_redeem_wrapped_cancel_liquidated_reimburse() { // to-be-redeemed decreased, forwarding to liquidation vault vault.to_be_redeemed -= redeem.amount_btc() + redeem.transfer_fee_btc(); liquidation_vault.to_be_redeemed -= redeem.amount_btc() + redeem.transfer_fee_btc(); + // decrease issued tokens on the liquidation vault by the same amount, s.t. the + // effective exchange rate (i.e. the one accounting for to_be_redeemed tokens) + // of the liquidation vault does not change. + liquidation_vault.issued -= redeem.amount_btc() + redeem.transfer_fee_btc(); // tokens are given to the vault, minus a fee that is given to the fee pool - *vault.free_balance.get_mut(&vault_id.wrapped_currency()).unwrap() += - redeem.amount_btc() + redeem.transfer_fee_btc(); *fee_pool.rewards_for(&vault_id) += redeem.fee(); // the collateral that remained with the vault to back this redeem is transferred to the user