fn liquidate_borrow_fresh(
		borrower: &T::AccountId,
		liquidated_pool_id: CurrencyId,
		mut seize_amount: Balance,
	) -> result::Result<(Vec<CurrencyId>, Balance), DispatchError> {
		let liquidation_pool_account_id = T::LiquidationPoolsManager::pools_account_id();
		let liquidity_pool_account_id = <T as Config>::LiquidityPoolsManager::pools_account_id();

		// Get an array of collateral pools for the borrower.
		// The array is sorted in descending order by the number of wrapped tokens in USD.
		let collateral_pools = <LiquidityPools<T>>::get_is_collateral_pools(&borrower)?;

		// Collect seized pools.
		let mut seized_pools: Vec<CurrencyId> = Vec::new();
		let mut already_seized_amount = Balance::zero();

		for collateral_pool_id in collateral_pools.into_iter() {
			if !seize_amount.is_zero() {
				<T as module::Config>::ControllerManager::accrue_interest_rate(collateral_pool_id)?;

				let wrapped_id = collateral_pool_id
					.wrapped_asset()
					.ok_or(Error::<T>::NotValidUnderlyingAssetId)?;
				let balance_wrapped_token = T::MultiCurrency::free_balance(wrapped_id, &borrower);

				// Get the exchange rate, read price for collateral pool and calculate the number
				// of collateral tokens to seize:
				// seize_tokens = seize_amount / (price_collateral * exchange_rate)
				let price_collateral =
					T::PriceSource::get_underlying_price(collateral_pool_id).ok_or(Error::<T>::InvalidFeedPrice)?;
				let exchange_rate = <LiquidityPools<T>>::get_exchange_rate(collateral_pool_id)?;
				let seize_tokens = Rate::from_inner(seize_amount)
					.checked_div(
						&price_collateral
							.checked_mul(&exchange_rate)
							.ok_or(Error::<T>::NumOverflow)?,
					)
					.map(|x| x.into_inner())
					.ok_or(Error::<T>::NumOverflow)?;

				<T as module::Config>::MntManager::update_mnt_supply_index(collateral_pool_id)?;
				<T as module::Config>::MntManager::distribute_supplier_mnt(collateral_pool_id, &borrower, false)?;

				// Check if there are enough collateral wrapped tokens to withdraw seize_tokens.
				let seize_underlying = match balance_wrapped_token.cmp(&seize_tokens) {
					// Not enough collateral wrapped tokens.
					Ordering::Less => {
						// seize_underlying = balance_wrapped_token * exchange_rate
						let seize_underlying =
							<LiquidityPools<T>>::convert_from_wrapped(wrapped_id, balance_wrapped_token)?;
						T::MultiCurrency::withdraw(wrapped_id, &borrower, balance_wrapped_token)?;
						// seize_amount = seize_amount - (seize_underlying * price_collateral)
						seize_amount -= Rate::from_inner(seize_underlying)
							.checked_mul(&price_collateral)
							.map(|x| x.into_inner())
							.ok_or(Error::<T>::NumOverflow)?;
						seize_underlying
					}
					// Enough collateral wrapped tokens. Transfer all seize_tokens to liquidation_pool.
					_ => {
						// seize_underlying = seize_tokens * exchange_rate
						let seize_underlying = <LiquidityPools<T>>::convert_from_wrapped(wrapped_id, seize_tokens)?;
						T::MultiCurrency::withdraw(wrapped_id, &borrower, seize_tokens)?;
						// seize_amount = 0, since all seize_tokens have already been withdrawn
						seize_amount = Balance::zero();
						seize_underlying
					}
				};
				T::MultiCurrency::transfer(
					collateral_pool_id,
					&liquidity_pool_account_id,
					&liquidation_pool_account_id,
					seize_underlying,
				)?;
				// already_seized_amount = already_seized_amount + (seize_underlying * price_collateral)
				already_seized_amount += Rate::from_inner(seize_underlying)
					.checked_mul(&price_collateral)
					.map(|x| x.into_inner())
					.ok_or(Error::<T>::NumOverflow)?;
				// Collecting seized pools to display in an Event.
				seized_pools.push(collateral_pool_id);
			}
		}

		let liquidation_fee = Self::risk_manager_params(liquidated_pool_id).liquidation_fee;

		let repay_amount = Rate::from_inner(already_seized_amount)
			.checked_div(&liquidation_fee)
			.map(|x| x.into_inner())
			.ok_or(Error::<T>::NumOverflow)?;

		let price_borrowed =
			T::PriceSource::get_underlying_price(liquidated_pool_id).ok_or(Error::<T>::InvalidFeedPrice)?;

		// Calculating the number of assets that must be repaid out of the liquidation pool.
		// repay_assets = already_seized_amount / (liquidation_fee * price_borrowed)
		let repay_assets = Rate::from_inner(repay_amount)
			.checked_div(&price_borrowed)
			.map(|x| x.into_inner())
			.ok_or(Error::<T>::NumOverflow)?;

		<MinterestProtocol<T>>::do_repay_fresh(
			&liquidation_pool_account_id,
			&borrower,
			liquidated_pool_id,
			repay_assets,
			false,
		)?;

		Ok((seized_pools, repay_amount))
	}
/// The liquidation pool liquidates the borrowers collateral. The collateral seized is
/// transferred to the liquidation pool.
///
/// - `borrower`: the borrower in automatic liquidation.
/// - `liquidated_pool_id`: the CurrencyId of the pool with loan, for which automatic
/// liquidation is performed.
/// - `repay_assets`: the amount of the underlying borrowed asset to repay.
/// - `seize_amount`: the number of collateral tokens to seize converted into USD.
The liquidation pool liquidates the borrowers collateral. The collateral seized is
transferred to the liquidation pool.

`borrower`: the borrower in automatic liquidation.
`liquidated_pool_id`: the CurrencyId of the pool with loan, for which automatic
liquidation is performed.
`repay_assets`: the amount of the underlying borrowed asset to repay.
`seize_amount`: the number of collateral tokens to seize converted into USD.
The liquidation pool liquidates the borrowers collateral . The collateral seized is transferred to the liquidation pool . ` borrower ` : the borrower in automatic liquidation . ` liquidated_pool_id ` : the CurrencyId of the pool with loan for which automatic liquidation is performed . ` repay_assets ` : the amount of the underlying borrowed asset to repay . ` seize_amount ` : the number of collateral tokens to seize converted into USD .
fn liquidate_borrow_fresh(
		borrower: &T::AccountId,
		liquidated_pool_id: CurrencyId,
		mut seize_amount: Balance,
	) -> result::Result<(Vec<CurrencyId>, Balance), DispatchError> {
		let liquidation_pool_account_id = T::LiquidationPoolsManager::pools_account_id();
		let liquidity_pool_account_id = <T as Config>::LiquidityPoolsManager::pools_account_id();
		// Get an array of collateral pools for the borrower.
		// The array is sorted in descending order by the number of wrapped tokens in USD.
		let collateral_pools = <LiquidityPools<T>>::get_is_collateral_pools(&borrower)?;
		// Collect seized pools.
		let mut seized_pools: Vec<CurrencyId> = Vec::new();
		let mut already_seized_amount = Balance::zero();
		for collateral_pool_id in collateral_pools.into_iter() {
			if !seize_amount.is_zero() {
				<T as module::Config>::ControllerManager::accrue_interest_rate(collateral_pool_id)?;
				let wrapped_id = collateral_pool_id
					.wrapped_asset()
					.ok_or(Error::<T>::NotValidUnderlyingAssetId)?;
				let balance_wrapped_token = T::MultiCurrency::free_balance(wrapped_id, &borrower);
				// Get the exchange rate, read price for collateral pool and calculate the number
				// of collateral tokens to seize:
				// seize_tokens = seize_amount / (price_collateral * exchange_rate)
				let price_collateral =
					T::PriceSource::get_underlying_price(collateral_pool_id).ok_or(Error::<T>::InvalidFeedPrice)?;
				let exchange_rate = <LiquidityPools<T>>::get_exchange_rate(collateral_pool_id)?;
				let seize_tokens = Rate::from_inner(seize_amount)
					.checked_div(
						&price_collateral
							.checked_mul(&exchange_rate)
							.ok_or(Error::<T>::NumOverflow)?,
					)
					.map(|x| x.into_inner())
					.ok_or(Error::<T>::NumOverflow)?;
				<T as module::Config>::MntManager::update_mnt_supply_index(collateral_pool_id)?;
				<T as module::Config>::MntManager::distribute_supplier_mnt(collateral_pool_id, &borrower, false)?;
				// Check if there are enough collateral wrapped tokens to withdraw seize_tokens.
				let seize_underlying = match balance_wrapped_token.cmp(&seize_tokens) {
					// Not enough collateral wrapped tokens.
					Ordering::Less => {
						// seize_underlying = balance_wrapped_token * exchange_rate
						let seize_underlying =
							<LiquidityPools<T>>::convert_from_wrapped(wrapped_id, balance_wrapped_token)?;
						T::MultiCurrency::withdraw(wrapped_id, &borrower, balance_wrapped_token)?;
						// seize_amount = seize_amount - (seize_underlying * price_collateral)
						seize_amount -= Rate::from_inner(seize_underlying)
							.checked_mul(&price_collateral)
							.map(|x| x.into_inner())
							.ok_or(Error::<T>::NumOverflow)?;
						seize_underlying
					}
					// Enough collateral wrapped tokens. Transfer all seize_tokens to liquidation_pool.
					_ => {
						// seize_underlying = seize_tokens * exchange_rate
						let seize_underlying = <LiquidityPools<T>>::convert_from_wrapped(wrapped_id, seize_tokens)?;
						T::MultiCurrency::withdraw(wrapped_id, &borrower, seize_tokens)?;
						// seize_amount = 0, since all seize_tokens have already been withdrawn
						seize_amount = Balance::zero();
						seize_underlying
					}
				};
				T::MultiCurrency::transfer(
					collateral_pool_id,
					&liquidity_pool_account_id,
					&liquidation_pool_account_id,
					seize_underlying,
				)?;
				// already_seized_amount = already_seized_amount + (seize_underlying * price_collateral)
				already_seized_amount += Rate::from_inner(seize_underlying)
					.checked_mul(&price_collateral)
					.map(|x| x.into_inner())
					.ok_or(Error::<T>::NumOverflow)?;
				// Collecting seized pools to display in an Event.
				seized_pools.push(collateral_pool_id);
			}
		}
		let liquidation_fee = Self::risk_manager_params(liquidated_pool_id).liquidation_fee;
		let repay_amount = Rate::from_inner(already_seized_amount)
			.checked_div(&liquidation_fee)
			.map(|x| x.into_inner())
			.ok_or(Error::<T>::NumOverflow)?;
		let price_borrowed =
			T::PriceSource::get_underlying_price(liquidated_pool_id).ok_or(Error::<T>::InvalidFeedPrice)?;
		// Calculating the number of assets that must be repaid out of the liquidation pool.
		// repay_assets = already_seized_amount / (liquidation_fee * price_borrowed)
		let repay_assets = Rate::from_inner(repay_amount)
			.checked_div(&price_borrowed)
			.map(|x| x.into_inner())
			.ok_or(Error::<T>::NumOverflow)?;
		<MinterestProtocol<T>>::do_repay_fresh(
			&liquidation_pool_account_id,
			&borrower,
			liquidated_pool_id,
			repay_assets,
			false,
		)?;
		Ok((seized_pools, repay_amount))
	}
fn liquidate_borrow_fresh ( borrower : & T :: AccountId , liquidated_pool_id : CurrencyId , mut seize_amount : Balance , ) -> result :: Result < ( Vec < CurrencyId > , Balance ) , DispatchError > { let liquidation_pool_account_id = T :: LiquidationPoolsManager :: pools_account_id ( ) ; let liquidity_pool_account_id = < T as Config > :: LiquidityPoolsManager :: pools_account_id ( ) ; // Get an array of collateral pools for the borrower. // The array is sorted in descending order by the number of wrapped tokens in USD. let collateral_pools = < LiquidityPools < T > > :: get_is_collateral_pools ( & borrower ) ? ; // Collect seized pools. let mut seized_pools : Vec < CurrencyId > = Vec :: new ( ) ; let mut already_seized_amount = Balance :: zero ( ) ; for collateral_pool_id in collateral_pools . into_iter ( ) { if ! seize_amount . is_zero ( ) { < T as module :: Config > :: ControllerManager :: accrue_interest_rate ( collateral_pool_id ) ? ; let wrapped_id = collateral_pool_id . wrapped_asset ( ) . ok_or ( Error :: < T > :: NotValidUnderlyingAssetId ) ? ; let balance_wrapped_token = T :: MultiCurrency :: free_balance ( wrapped_id , & borrower ) ; // Get the exchange rate, read price for collateral pool and calculate the number // of collateral tokens to seize: // seize_tokens = seize_amount / (price_collateral * exchange_rate) let price_collateral = T :: PriceSource :: get_underlying_price ( collateral_pool_id ) . ok_or ( Error :: < T > :: InvalidFeedPrice ) ? ; let exchange_rate = < LiquidityPools < T > > :: get_exchange_rate ( collateral_pool_id ) ? ; let seize_tokens = Rate :: from_inner ( seize_amount ) . checked_div ( & price_collateral . checked_mul ( & exchange_rate ) . ok_or ( Error :: < T > :: NumOverflow ) ? , ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; < T as module :: Config > :: MntManager :: update_mnt_supply_index ( collateral_pool_id ) ? ; < T as module :: Config > :: MntManager :: distribute_supplier_mnt ( collateral_pool_id , & borrower , false ) ? ; // Check if there are enough collateral wrapped tokens to withdraw seize_tokens. let seize_underlying = match balance_wrapped_token . cmp ( & seize_tokens ) { // Not enough collateral wrapped tokens. Ordering :: Less => { // seize_underlying = balance_wrapped_token * exchange_rate let seize_underlying = < LiquidityPools < T > > :: convert_from_wrapped ( wrapped_id , balance_wrapped_token ) ? ; T :: MultiCurrency :: withdraw ( wrapped_id , & borrower , balance_wrapped_token ) ? ; // seize_amount = seize_amount - (seize_underlying * price_collateral) seize_amount -= Rate :: from_inner ( seize_underlying ) . checked_mul ( & price_collateral ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; seize_underlying } // Enough collateral wrapped tokens. Transfer all seize_tokens to liquidation_pool. _ => { // seize_underlying = seize_tokens * exchange_rate let seize_underlying = < LiquidityPools < T > > :: convert_from_wrapped ( wrapped_id , seize_tokens ) ? ; T :: MultiCurrency :: withdraw ( wrapped_id , & borrower , seize_tokens ) ? ; // seize_amount = 0, since all seize_tokens have already been withdrawn seize_amount = Balance :: zero ( ) ; seize_underlying } } ; T :: MultiCurrency :: transfer ( collateral_pool_id , & liquidity_pool_account_id , & liquidation_pool_account_id , seize_underlying , ) ? ; // already_seized_amount = already_seized_amount + (seize_underlying * price_collateral) already_seized_amount += Rate :: from_inner ( seize_underlying ) . checked_mul ( & price_collateral ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; // Collecting seized pools to display in an Event. seized_pools . push ( collateral_pool_id ) ; } } let liquidation_fee = Self :: risk_manager_params ( liquidated_pool_id ) . liquidation_fee ; let repay_amount = Rate :: from_inner ( already_seized_amount ) . checked_div ( & liquidation_fee ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; let price_borrowed = T :: PriceSource :: get_underlying_price ( liquidated_pool_id ) . ok_or ( Error :: < T > :: InvalidFeedPrice ) ? ; // Calculating the number of assets that must be repaid out of the liquidation pool. // repay_assets = already_seized_amount / (liquidation_fee * price_borrowed) let repay_assets = Rate :: from_inner ( repay_amount ) . checked_div ( & price_borrowed ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; < MinterestProtocol < T > > :: do_repay_fresh ( & liquidation_pool_account_id , & borrower , liquidated_pool_id , repay_assets , false , ) ? ; Ok ( ( seized_pools , repay_amount ) ) }
The liquidation pool liquidates the borrowers collateral.
The liquidation pool liquidates the borrowers collateral .
borrower
&T::AccountId
liquidated_pool_id
CurrencyId
seize_amount
Balance
borrower
&T::AccountId
liquidated_pool_id
CurrencyId
seize_amount
Balance