From cb6c62fd53095835123f0056a41c6836a33fe2a6 Mon Sep 17 00:00:00 2001 From: Roy Yang Date: Mon, 11 Oct 2021 16:55:14 +1300 Subject: [PATCH] Fixed a bug where if there are dust AvailableStakingBalance, redeem amount is lost --- modules/homa-lite/src/lib.rs | 3 ++- modules/homa-lite/src/tests.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/modules/homa-lite/src/lib.rs b/modules/homa-lite/src/lib.rs index 78704945a6..22e2ae8540 100644 --- a/modules/homa-lite/src/lib.rs +++ b/modules/homa-lite/src/lib.rs @@ -434,6 +434,7 @@ pub mod module { Self::convert_staking_to_liquid(available_staking_balance)?, ); + let mut liquid_remaining = liquid_amount; if Self::convert_liquid_to_staking(actual_liquid_amount)? > T::XcmUnbondFee::get() { // Immediately redeem from the available_staking_balances let actual_staking_amount = Self::convert_liquid_to_staking(actual_liquid_amount)?; @@ -456,10 +457,10 @@ pub mod module { actual_staking_amount, actual_liquid_amount, )); + liquid_remaining = liquid_remaining.saturating_sub(actual_liquid_amount); } // Unredeemed requests are added to a queue. - let liquid_remaining = liquid_amount.saturating_sub(actual_liquid_amount); if Self::liquid_amount_is_above_minimum_threshold(liquid_remaining) { // Check if there's already a queued redeem request. let (request_amount, _) = Self::redeem_requests(&who).unwrap_or((0, Permill::default())); diff --git a/modules/homa-lite/src/tests.rs b/modules/homa-lite/src/tests.rs index b44b19282d..d0033a8de9 100644 --- a/modules/homa-lite/src/tests.rs +++ b/modules/homa-lite/src/tests.rs @@ -799,3 +799,30 @@ fn staking_and_liquid_conversion_works() { assert_eq!(HomaLite::convert_liquid_to_staking(5_000_000), Ok(1_000_000)); }); } + +#[test] +fn redeem_can_handle_dust_available_staking_currency() { + ExtBuilder::default().build().execute_with(|| { + // If AvailableStakingBalance is not enough to pay for the unbonding fee, ignore it. + // pub XcmUnbondFee: Balance = dollar(1); + assert_ok!(HomaLite::schedule_unbond(Origin::root(), 999_000_000, 0)); + MockRelayBlockNumberProvider::set(0); + HomaLite::on_idle(MockRelayBlockNumberProvider::get(), 5_000_000_000); + + assert_eq!(AvailableStakingBalance::::get(), 999_000_000); + + // Ignore the dust AvailableStakingBalance and put the full amount onto the queue. + assert_ok!(HomaLite::request_redeem( + Origin::signed(ROOT), + dollar(1000), + Permill::zero() + )); + + assert_eq!(HomaLite::redeem_requests(ROOT), Some((dollar(1000), Permill::zero()))); + System::assert_last_event(Event::HomaLite(crate::Event::RedeemRequested( + ROOT, + dollar(1000), + Permill::zero(), + ))); + }); +}