use cfg_traits::{investments::ForeignInvestment, liquidity_pools::OutboundMessageHandler};
use cfg_types::domain_address::{Domain, DomainAddress};
use frame_support::{
ensure,
traits::{fungibles::Mutate, tokens::Preservation, OriginTrait},
};
use sp_core::Get;
use sp_runtime::{traits::Zero, DispatchResult};
use crate::{pallet::Error, Config, GeneralCurrencyIndexOf, Message, Pallet};
impl<T: Config> Pallet<T> {
pub fn handle_transfer(
currency: GeneralCurrencyIndexOf<T>,
receiver: T::AccountId,
amount: <T as Config>::Balance,
) -> DispatchResult {
ensure!(!amount.is_zero(), Error::<T>::InvalidTransferAmount);
let currency_id = Self::try_get_currency_id(currency)?;
T::Tokens::mint_into(currency_id, &receiver, amount)?;
Ok(())
}
pub fn handle_tranche_tokens_transfer(
pool_id: T::PoolId,
tranche_id: T::TrancheId,
sending_domain: Domain,
receiver: DomainAddress,
amount: <T as Config>::Balance,
) -> DispatchResult {
ensure!(!amount.is_zero(), Error::<T>::InvalidTransferAmount);
let local_representation_of_receiver = receiver.account();
Self::validate_investor_can_transfer(
local_representation_of_receiver.clone(),
pool_id,
tranche_id,
)?;
let invest_id = Self::derive_invest_id(pool_id, tranche_id)?;
T::Tokens::transfer(
invest_id.into(),
&sending_domain.into_account(),
&local_representation_of_receiver,
amount,
Preservation::Expendable,
)?;
if receiver.domain() != Domain::Centrifuge {
Pallet::<T>::transfer_tranche_tokens(
T::RuntimeOrigin::signed(local_representation_of_receiver),
pool_id,
tranche_id,
receiver,
amount,
)?;
}
Ok(())
}
pub fn handle_deposit_request(
pool_id: T::PoolId,
tranche_id: T::TrancheId,
investor: T::AccountId,
currency_index: GeneralCurrencyIndexOf<T>,
amount: <T as Config>::Balance,
) -> DispatchResult {
let invest_id = Self::derive_invest_id(pool_id, tranche_id)?;
let payment_currency = Self::try_get_currency_id(currency_index)?;
T::Tokens::mint_into(payment_currency, &investor, amount)?;
T::ForeignInvestment::increase_foreign_investment(
&investor,
invest_id,
amount,
payment_currency,
)?;
Ok(())
}
pub fn handle_cancel_deposit_request(
pool_id: T::PoolId,
tranche_id: T::TrancheId,
investor: T::AccountId,
currency_index: GeneralCurrencyIndexOf<T>,
) -> DispatchResult {
let invest_id = Self::derive_invest_id(pool_id, tranche_id)?;
let payout_currency = Self::try_get_currency_id(currency_index)?;
T::ForeignInvestment::cancel_foreign_investment(&investor, invest_id, payout_currency)
}
pub fn handle_redeem_request(
pool_id: T::PoolId,
tranche_id: T::TrancheId,
investor: T::AccountId,
amount: <T as Config>::Balance,
currency_index: GeneralCurrencyIndexOf<T>,
sending_domain: DomainAddress,
) -> DispatchResult {
let invest_id = Self::derive_invest_id(pool_id, tranche_id)?;
let payout_currency = Self::try_get_currency_id(currency_index)?;
T::Tokens::transfer(
invest_id.into(),
&sending_domain.domain().into_account(),
&investor,
amount,
Preservation::Expendable,
)?;
T::ForeignInvestment::increase_foreign_redemption(
&investor,
invest_id,
amount,
payout_currency,
)?;
Ok(())
}
pub fn handle_cancel_redeem_request(
pool_id: T::PoolId,
tranche_id: T::TrancheId,
investor: T::AccountId,
currency_index: GeneralCurrencyIndexOf<T>,
destination: DomainAddress,
) -> DispatchResult {
let invest_id = Self::derive_invest_id(pool_id, tranche_id)?;
let currency_u128 = currency_index.index;
let payout_currency = Self::try_get_currency_id(currency_index)?;
let amount =
T::ForeignInvestment::cancel_foreign_redemption(&investor, invest_id, payout_currency)?;
T::Tokens::transfer(
invest_id.into(),
&investor,
&destination.domain().into_account(),
amount,
Preservation::Expendable,
)?;
let message = Message::FulfilledCancelRedeemRequest {
pool_id: pool_id.into(),
tranche_id: tranche_id.into(),
investor: investor.clone().into(),
currency: currency_u128,
tranche_tokens_payout: amount.into(),
};
T::OutboundMessageHandler::handle(
T::TreasuryAccount::get(),
destination.domain(),
message,
)?;
Ok(())
}
}