diff --git a/node/primitives/src/lib.rs b/node/primitives/src/lib.rs index 1e3c6849a8..0a78b6ff9a 100644 --- a/node/primitives/src/lib.rs +++ b/node/primitives/src/lib.rs @@ -149,6 +149,6 @@ pub enum TimeUnit { impl Default for TimeUnit { fn default() -> Self { - TimeUnit::Era(1u32) + TimeUnit::Era(0u32) } } diff --git a/pallets/vtoken-minting/src/lib.rs b/pallets/vtoken-minting/src/lib.rs index fa744b4b6c..e541b2f170 100644 --- a/pallets/vtoken-minting/src/lib.rs +++ b/pallets/vtoken-minting/src/lib.rs @@ -112,7 +112,9 @@ pub mod pallet { fee: BalanceOf, }, RedeemSuccess { + unlock_id: UnlockId, token_id: CurrencyIdOf, + to: AccountIdOf, token_amount: BalanceOf, }, Rebonded { @@ -889,6 +891,46 @@ pub mod pallet { ) -> DispatchResult { if entrance_account_balance >= unlock_amount { TokenUnlockLedger::::remove(&token_id, &index); + + TimeUnitUnlockLedger::::mutate_exists( + &time_unit, + &token_id, + |value| -> Result<(), Error> { + if let Some((total_locked_origin, ledger_list_origin, _)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::CalculationOverflow)?; + ledger_list_origin.retain(|x| x != index); + } else { + return Err(Error::::TimeUnitUnlockLedgerNotFound.into()); + } + return Ok(()); + }, + )?; + + UserUnlockLedger::::mutate_exists( + &account, + &token_id, + |value| -> Result<(), Error> { + if let Some((total_locked_origin, ledger_list_origin)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + ledger_list_origin.retain(|x| x != index); + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::CalculationOverflow)?; + } else { + return Err(Error::::UserUnlockLedgerNotFound.into()); + } + return Ok(()); + }, + )?; } else { unlock_amount = entrance_account_balance; TokenUnlockLedger::::mutate_exists( @@ -909,6 +951,45 @@ pub mod pallet { return Ok(()); }, )?; + + TimeUnitUnlockLedger::::mutate_exists( + &time_unit, + &token_id, + |value| -> Result<(), Error> { + if let Some((total_locked_origin, ledger_list_origin, _)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::CalculationOverflow)?; + } else { + return Err(Error::::TimeUnitUnlockLedgerNotFound.into()); + } + return Ok(()); + }, + )?; + + UserUnlockLedger::::mutate_exists( + &account, + &token_id, + |value| -> Result<(), Error> { + if let Some((total_locked_origin, ledger_list_origin)) = value { + if total_locked_origin == &unlock_amount { + *value = None; + return Ok(()); + } + + *total_locked_origin = total_locked_origin + .checked_sub(&unlock_amount) + .ok_or(Error::::CalculationOverflow)?; + } else { + return Err(Error::::UserUnlockLedgerNotFound.into()); + } + return Ok(()); + }, + )?; } entrance_account_balance = entrance_account_balance @@ -922,46 +1003,6 @@ pub mod pallet { unlock_amount, )?; - TimeUnitUnlockLedger::::mutate_exists( - &time_unit, - &token_id, - |value| -> Result<(), Error> { - if let Some((total_locked_origin, ledger_list_origin, _)) = value { - if total_locked_origin == &unlock_amount { - *value = None; - return Ok(()); - } - *total_locked_origin = total_locked_origin - .checked_sub(&unlock_amount) - .ok_or(Error::::CalculationOverflow)?; - ledger_list_origin.retain(|x| x != index); - } else { - return Err(Error::::TimeUnitUnlockLedgerNotFound.into()); - } - return Ok(()); - }, - )?; - - UserUnlockLedger::::mutate_exists( - &account, - &token_id, - |value| -> Result<(), Error> { - if let Some((total_locked_origin, ledger_list_origin)) = value { - if total_locked_origin == &unlock_amount { - *value = None; - return Ok(()); - } - ledger_list_origin.retain(|x| x != index); - *total_locked_origin = total_locked_origin - .checked_sub(&unlock_amount) - .ok_or(Error::::CalculationOverflow)?; - } else { - return Err(Error::::UserUnlockLedgerNotFound.into()); - } - return Ok(()); - }, - )?; - CurrencyUnlockingTotal::::mutate(|pool| -> Result<(), Error> { *pool = pool.checked_sub(&unlock_amount).ok_or(Error::::CalculationOverflow)?; Ok(()) @@ -977,7 +1018,12 @@ pub mod pallet { Ok(()) })?; - Self::deposit_event(Event::RedeemSuccess { token_id, token_amount: unlock_amount }); + Self::deposit_event(Event::RedeemSuccess { + unlock_id: *index, + token_id, + to: account, + token_amount: unlock_amount, + }); Ok(()) } @@ -995,6 +1041,9 @@ pub mod pallet { if let Some((account, unlock_amount, time_unit)) = Self::token_unlock_ledger(token_id, index) { + if entrance_account_balance == BalanceOf::::zero() { + return; + } Self::on_initialize_update_ledger( token_id, account, diff --git a/pallets/vtoken-minting/src/tests.rs b/pallets/vtoken-minting/src/tests.rs index e1f1c250bb..21c12e1499 100644 --- a/pallets/vtoken-minting/src/tests.rs +++ b/pallets/vtoken-minting/src/tests.rs @@ -125,7 +125,7 @@ fn rebond() { #[test] fn hook() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { - assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(1)); + assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(0)); assert_ok!(VtokenMinting::update_ongoing_time_unit(KSM, TimeUnit::Era(3))); assert_eq!(VtokenMinting::ongoing_time_unit(KSM), Some(TimeUnit::Era(3))); assert_ok!(VtokenMinting::set_unlock_duration(Origin::root(), KSM, TimeUnit::Era(1))); @@ -170,6 +170,20 @@ fn hook() { assert_eq!(VtokenMinting::token_to_add(KSM), 0); assert_eq!(VtokenMinting::token_to_deduct(KSM), 0); assert_eq!(VtokenMinting::currency_unlocking_total(), 0); + assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 100)); + assert_ok!(VtokenMinting::redeem(Some(BOB).into(), vKSM, 200)); + VtokenMinting::on_initialize(0); + assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 2), Some((BOB, 100, TimeUnit::Era(6)))); + let mut ledger_list_origin = BoundedVec::default(); + assert_ok!(ledger_list_origin.try_push(2)); + assert_eq!( + VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(6), KSM), + Some((100, ledger_list_origin.clone(), KSM)) + ); + assert_eq!( + VtokenMinting::user_unlock_ledger(BOB, KSM), + Some((100, ledger_list_origin.clone())) + ); }); }