From e1e3a62293261131529f1a4c8b779863e9d5091b Mon Sep 17 00:00:00 2001 From: MrPai <1164934857@qq.com> Date: Sun, 8 Oct 2023 17:30:58 +0800 Subject: [PATCH 1/4] add do_redeem --- pallets/crowdloans/src/lib.rs | 126 +++++++++++++++++++++------------- 1 file changed, 79 insertions(+), 47 deletions(-) diff --git a/pallets/crowdloans/src/lib.rs b/pallets/crowdloans/src/lib.rs index b8859b23c..b92dcbdf5 100644 --- a/pallets/crowdloans/src/lib.rs +++ b/pallets/crowdloans/src/lib.rs @@ -872,53 +872,7 @@ pub mod pallet { #[pallet::compact] amount: BalanceOf, ) -> DispatchResult { let who = ensure_signed(origin)?; - - let ctoken = Self::ctoken_of((&lease_start, &lease_end)) - .ok_or(Error::::CTokenDoesNotExist)?; - let mut vault = Self::vaults((&crowdloan, &lease_start, &lease_end)) - .ok_or(Error::::VaultDoesNotExist)?; - - ensure!( - vault.phase == VaultPhase::Expired, - Error::::IncorrectVaultPhase - ); - - log::trace!( - target: "crowdloans::redeem", - "who: {:?}, ctoken: {:?}, amount: {:?}, para_id: {:?}, lease_start: {:?}, lease_end: {:?}", - &who, - &ctoken, - &amount, - &crowdloan, - &lease_start, - &lease_end - ); - - let ctoken_balance = T::Assets::reducible_balance(ctoken, &who, false); - ensure!(ctoken_balance >= amount, Error::::InsufficientBalance); - - vault.contributed = vault - .contributed - .checked_sub(amount) - .ok_or(ArithmeticError::Underflow)?; - - T::Assets::burn_from(ctoken, &who, amount)?; - // SovereignAccount on relaychain must have - // withdrawn the contribution - T::Assets::mint_into(T::RelayCurrency::get(), &who, amount)?; - - Vaults::::insert((&crowdloan, &lease_start, &lease_end), vault); - - Self::deposit_event(Event::::VaultRedeemed( - crowdloan, - (lease_start, lease_end), - ctoken, - who, - amount, - VaultPhase::Expired, - )); - - Ok(()) + Self::do_redeem(who, crowdloan, lease_start, lease_end, amount) } /// If a `crowdloan` succeeded and its slot expired, use `call` to @@ -1237,6 +1191,28 @@ pub mod pallet { let who = T::Lookup::lookup(dest)?; Self::do_claim_for(who, crowdloan, lease_start, lease_end, true) } + + /// If a `crowdloan` expired, redeem the contributed assets + /// and lend it to Money market + #[pallet::call_index(23)] + #[pallet::weight(::WeightInfo::redeem())] + #[transactional] + pub fn redeem_and_lend_for( + origin: OriginFor, + dest: ::Source, + crowdloan: ParaId, + lease_start: LeasePeriod, + lease_end: LeasePeriod, + #[pallet::compact] amount: BalanceOf, + ) -> DispatchResult { + ensure_origin!(SlotExpiredOrigin, origin)?; + let who = T::Lookup::lookup(dest)?; + Self::do_redeem(who, crowdloan, lease_start, lease_end, amount)?; + + //TODO: lend to MM + + Ok(()) + } } impl Pallet { @@ -1816,6 +1792,62 @@ pub mod pallet { Ok(()) } + #[require_transactional] + fn do_redeem( + who: T::AccountId, + crowdloan: ParaId, + lease_start: LeasePeriod, + lease_end: LeasePeriod, + amount: BalanceOf, + ) -> DispatchResult { + let ctoken = Self::ctoken_of((&lease_start, &lease_end)) + .ok_or(Error::::CTokenDoesNotExist)?; + let mut vault = Self::vaults((&crowdloan, &lease_start, &lease_end)) + .ok_or(Error::::VaultDoesNotExist)?; + + ensure!( + vault.phase == VaultPhase::Expired, + Error::::IncorrectVaultPhase + ); + + log::trace!( + target: "crowdloans::redeem", + "who: {:?}, ctoken: {:?}, amount: {:?}, para_id: {:?}, lease_start: {:?}, lease_end: {:?}", + &who, + &ctoken, + &amount, + &crowdloan, + &lease_start, + &lease_end + ); + + let ctoken_balance = T::Assets::reducible_balance(ctoken, &who, false); + ensure!(ctoken_balance >= amount, Error::::InsufficientBalance); + + vault.contributed = vault + .contributed + .checked_sub(amount) + .ok_or(ArithmeticError::Underflow)?; + + T::Assets::burn_from(ctoken, &who, amount)?; + // SovereignAccount on relaychain must have + // withdrawn the contribution + T::Assets::mint_into(T::RelayCurrency::get(), &who, amount)?; + + Vaults::::insert((&crowdloan, &lease_start, &lease_end), vault); + + Self::deposit_event(Event::::VaultRedeemed( + crowdloan, + (lease_start, lease_end), + ctoken, + who, + amount, + VaultPhase::Expired, + )); + + Ok(()) + } + // just iterate now and require improve later when CTokensRegistry increased fn find_vault_by_asset_id(asset_id: &AssetIdOf) -> Option<(AssetIdOf, AssetIdOf)> { for (vault, ctoken_id) in CTokensRegistry::::iter() { From 6811d1161330229cec0e6a76c348bf9f3b64f6b7 Mon Sep 17 00:00:00 2001 From: MrPai <1164934857@qq.com> Date: Sun, 8 Oct 2023 19:38:27 +0800 Subject: [PATCH 2/4] add type Loans in Config --- pallets/crowdloans/src/lib.rs | 10 ++++---- pallets/crowdloans/src/mock.rs | 44 +++++++++++++++++++++++++++++++++- runtime/heiko/src/lib.rs | 1 + runtime/kerria/src/lib.rs | 1 + runtime/parallel/src/lib.rs | 1 + runtime/vanilla/src/lib.rs | 1 + 6 files changed, 53 insertions(+), 5 deletions(-) diff --git a/pallets/crowdloans/src/lib.rs b/pallets/crowdloans/src/lib.rs index b92dcbdf5..5e892d25f 100644 --- a/pallets/crowdloans/src/lib.rs +++ b/pallets/crowdloans/src/lib.rs @@ -68,7 +68,8 @@ pub mod pallet { use xcm::latest::prelude::*; use pallet_traits::{ - DecimalProvider, Streaming, VaultTokenCurrenciesFilter, VaultTokenExchangeRateProvider, + DecimalProvider, Loans, Streaming, VaultTokenCurrenciesFilter, + VaultTokenExchangeRateProvider, }; use parallel_support::math_helper::f64::{ @@ -202,6 +203,9 @@ pub mod pallet { /// Decimal provider. type Decimal: DecimalProvider; + + /// Money market + type Loans: Loans, Self::AccountId, BalanceOf>; } #[pallet::event] @@ -1208,9 +1212,7 @@ pub mod pallet { ensure_origin!(SlotExpiredOrigin, origin)?; let who = T::Lookup::lookup(dest)?; Self::do_redeem(who, crowdloan, lease_start, lease_end, amount)?; - - //TODO: lend to MM - + T::Loans::do_mint(&who, T::RelayCurrency::get(), amount)?; Ok(()) } } diff --git a/pallets/crowdloans/src/mock.rs b/pallets/crowdloans/src/mock.rs index deacfe265..f102e5ea4 100644 --- a/pallets/crowdloans/src/mock.rs +++ b/pallets/crowdloans/src/mock.rs @@ -46,7 +46,7 @@ pub use kusama_runtime; use pallet_traits::{ ump::{XcmCall, XcmWeightFeeMisc}, xcm::MultiCurrencyAdapter, - DecimalProvider, + DecimalProvider, Loans, }; pub struct RelayChainBlockNumberProvider(sp_std::marker::PhantomData); @@ -560,6 +560,48 @@ impl crate::Config for Test { type Streaming = (); type GetNativeCurrencyId = NativeCurrencyId; type Decimal = Decimal; + type Loans = MockLoans; +} + +pub struct MockLoans; + +#[allow(unused)] +impl Loans for MockLoans { + fn do_mint( + supplier: &AccountId, + asset_id: CurrencyId, + amount: Balance, + ) -> Result<(), DispatchError> { + Ok(()) + } + fn do_borrow( + borrower: &AccountId, + asset_id: CurrencyId, + amount: Balance, + ) -> Result<(), DispatchError> { + Ok(()) + } + fn do_collateral_asset( + supplier: &AccountId, + asset_id: CurrencyId, + enable: bool, + ) -> Result<(), DispatchError> { + Ok(()) + } + fn do_repay_borrow( + borrower: &AccountId, + asset_id: CurrencyId, + amount: Balance, + ) -> Result<(), DispatchError> { + Ok(()) + } + fn do_redeem( + supplier: &AccountId, + asset_id: CurrencyId, + amount: Balance, + ) -> Result<(), DispatchError> { + Ok(()) + } } pub struct Decimal; diff --git a/runtime/heiko/src/lib.rs b/runtime/heiko/src/lib.rs index 746187ffa..2ebd9ed45 100644 --- a/runtime/heiko/src/lib.rs +++ b/runtime/heiko/src/lib.rs @@ -1858,6 +1858,7 @@ impl pallet_crowdloans::Config for Runtime { type Streaming = (); type GetNativeCurrencyId = NativeCurrencyId; type Decimal = Decimal; + type Loans = Loans; } parameter_types! { diff --git a/runtime/kerria/src/lib.rs b/runtime/kerria/src/lib.rs index d61754827..aa567b05e 100644 --- a/runtime/kerria/src/lib.rs +++ b/runtime/kerria/src/lib.rs @@ -1857,6 +1857,7 @@ impl pallet_crowdloans::Config for Runtime { type Streaming = Streaming; type GetNativeCurrencyId = NativeCurrencyId; type Decimal = Decimal; + type Loans = Loans; } parameter_types! { diff --git a/runtime/parallel/src/lib.rs b/runtime/parallel/src/lib.rs index 31d77d367..45ae94003 100644 --- a/runtime/parallel/src/lib.rs +++ b/runtime/parallel/src/lib.rs @@ -1861,6 +1861,7 @@ impl pallet_crowdloans::Config for Runtime { type Streaming = Streaming; type GetNativeCurrencyId = NativeCurrencyId; type Decimal = Decimal; + type Loans = Loans; } parameter_types! { diff --git a/runtime/vanilla/src/lib.rs b/runtime/vanilla/src/lib.rs index 6f1013660..ac588972f 100644 --- a/runtime/vanilla/src/lib.rs +++ b/runtime/vanilla/src/lib.rs @@ -1886,6 +1886,7 @@ impl pallet_crowdloans::Config for Runtime { type Streaming = (); type GetNativeCurrencyId = NativeCurrencyId; type Decimal = Decimal; + type Loans = Loans; } parameter_types! { From 5af7e23c0987135b45eb49a6c1836316e699b7f2 Mon Sep 17 00:00:00 2001 From: MrPai <1164934857@qq.com> Date: Tue, 10 Oct 2023 19:09:31 +0800 Subject: [PATCH 3/4] ensure nonce > 0 --- pallets/amm/src/tests.rs | 2 +- pallets/crowdloans/src/lib.rs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/pallets/amm/src/tests.rs b/pallets/amm/src/tests.rs index eed03b7fa..2417dd89a 100644 --- a/pallets/amm/src/tests.rs +++ b/pallets/amm/src/tests.rs @@ -1162,7 +1162,7 @@ fn handling_fees_should_work() { // we can check the total balance // - // no extra fees should be minted becuase liquidty has not been added or removed + // no extra fees should be minted because liquidty has not been added or removed // assert_eq!(Assets::total_issuance(SAMPLE_LP_TOKEN), 100_000_000_000); diff --git a/pallets/crowdloans/src/lib.rs b/pallets/crowdloans/src/lib.rs index 5e892d25f..253cbaaad 100644 --- a/pallets/crowdloans/src/lib.rs +++ b/pallets/crowdloans/src/lib.rs @@ -1211,7 +1211,13 @@ pub mod pallet { ) -> DispatchResult { ensure_origin!(SlotExpiredOrigin, origin)?; let who = T::Lookup::lookup(dest)?; - Self::do_redeem(who, crowdloan, lease_start, lease_end, amount)?; + + ensure!( + frame_system::Pallet::::account_nonce(who.clone()) > 0, + Error::::InvalidParams, + ); + + Self::do_redeem(who.clone(), crowdloan, lease_start, lease_end, amount)?; T::Loans::do_mint(&who, T::RelayCurrency::get(), amount)?; Ok(()) } From c2590d58c361045d8c2dca8028c52d50e9e53fc3 Mon Sep 17 00:00:00 2001 From: MrPai <1164934857@qq.com> Date: Tue, 10 Oct 2023 19:23:35 +0800 Subject: [PATCH 4/4] fix ci --- pallets/crowdloans/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/crowdloans/src/lib.rs b/pallets/crowdloans/src/lib.rs index 253cbaaad..76b73a8a4 100644 --- a/pallets/crowdloans/src/lib.rs +++ b/pallets/crowdloans/src/lib.rs @@ -1213,7 +1213,7 @@ pub mod pallet { let who = T::Lookup::lookup(dest)?; ensure!( - frame_system::Pallet::::account_nonce(who.clone()) > 0, + frame_system::Pallet::::account_nonce(who.clone()) > Zero::zero(), Error::::InvalidParams, );