fn collects_sales_list() -> sp_std::result::Result<Vec<Sales>, DispatchError> {
		// Collecting information about the current state of liquidation pools.
		let (mut information_vec, mut sum_oversupply, mut sum_shortfall) =
			CurrencyId::get_enabled_tokens_in_protocol(UnderlyingAsset)
				.iter()
				.filter(|&underlying_id| T::LiquidityPoolsManager::pool_exists(underlying_id))
				.try_fold(
					(Vec::<LiquidationInformation>::new(), Balance::zero(), Balance::zero()),
					|(mut current_vec, mut current_sum_oversupply, mut current_sum_shortfall),
					 pool_id|
					 -> sp_std::result::Result<(Vec<LiquidationInformation>, Balance, Balance), DispatchError> {
						let oracle_price =
							T::PriceSource::get_underlying_price(*pool_id).ok_or(Error::<T>::InvalidFeedPrice)?;
						// Liquidation pool balance in USD: liquidation_pool_balance * oracle_price
						let liquidation_pool_balance = Rate::from_inner(Self::get_pool_available_liquidity(*pool_id))
							.checked_mul(&oracle_price)
							.map(|x| x.into_inner())
							.ok_or(Error::<T>::BalanceOverflow)?;
						let ideal_balance = Self::calculate_ideal_balance(*pool_id)?;

						// If the pool is not balanced:
						// oversupply = liquidation_pool_balance - ideal_balance
						// shortfall = ideal_balance - liquidation_pool_balance
						let (oversupply, shortfall) = match liquidation_pool_balance.cmp(&ideal_balance) {
							Ordering::Greater => (liquidation_pool_balance - ideal_balance, Balance::zero()),
							Ordering::Less => (Balance::zero(), ideal_balance - liquidation_pool_balance),
							Ordering::Equal => (Balance::zero(), Balance::zero()),
						};

						current_vec.push(LiquidationInformation {
							pool_id: *pool_id,
							balance: liquidation_pool_balance,
							oversupply,
							shortfall,
						});

						// Calculate sum_extra and sum_shortfall for all pools.
						let deviation_threshold = Self::liquidation_pools_data(*pool_id).deviation_threshold;
						// right_border = ideal_balance + ideal_balance * deviation_threshold
						let right_border = sum_with_mult_result(ideal_balance, ideal_balance, deviation_threshold)
							.map_err(|_| Error::<T>::BalanceOverflow)?;

						// left_border = ideal_balance - ideal_balance * deviation_threshold
						let left_border = ideal_balance
							.checked_sub(
								Rate::from_inner(ideal_balance)
									.checked_mul(&deviation_threshold)
									.map(|x| x.into_inner())
									.ok_or(Error::<T>::NumOverflow)?,
							)
							.ok_or(Error::<T>::NumOverflow)?;

						if liquidation_pool_balance > right_border {
							current_sum_oversupply = current_sum_oversupply
								.checked_add(oversupply)
								.ok_or(Error::<T>::BalanceOverflow)?;
						}
						if liquidation_pool_balance < left_border {
							current_sum_shortfall = current_sum_shortfall
								.checked_add(shortfall)
								.ok_or(Error::<T>::BalanceOverflow)?;
						}

						Ok((current_vec, current_sum_oversupply, current_sum_shortfall))
					},
				)?;

		// Contains information about the necessary transactions on the DEX.
		let mut to_sell_list: Vec<Sales> = Vec::new();

		while sum_shortfall > Balance::zero() && sum_oversupply > Balance::zero() {
			// Find the pool with the maximum oversupply and the pool with the maximum shortfall.
			let (max_oversupply_index, max_oversupply_pool_id, max_oversupply) = information_vec
				.iter()
				.enumerate()
				.max_by(|(_, a), (_, b)| a.oversupply.cmp(&b.oversupply))
				.map(|(index, pool)| (index, pool.pool_id, pool.oversupply))
				.ok_or(Error::<T>::PoolNotFound)?;

			let (max_shortfall_index, max_shortfall_pool_id, max_shortfall) = information_vec
				.iter()
				.enumerate()
				.max_by(|(_, a), (_, b)| a.shortfall.cmp(&b.shortfall))
				.map(|(index, pool)| (index, pool.pool_id, pool.shortfall))
				.ok_or(Error::<T>::PoolNotFound)?;

			// The number USD equivalent to be sent to the DEX will be equal to
			// the minimum value between (max_shortfall, max_oversupply).
			let bite_in_usd = max_oversupply.min(max_shortfall);

			// Add "sale" to the sales list.
			to_sell_list.push(Sales {
				supply_pool_id: max_oversupply_pool_id,
				target_pool_id: max_shortfall_pool_id,
				amount: bite_in_usd,
			});

			// Updating the information vector.
			let pool_with_max_oversupply = &mut information_vec[max_oversupply_index];
			pool_with_max_oversupply.balance = pool_with_max_oversupply
				.balance
				.checked_sub(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;
			pool_with_max_oversupply.oversupply = pool_with_max_oversupply
				.oversupply
				.checked_sub(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;

			let pool_with_max_shortfall = &mut information_vec[max_shortfall_index];
			pool_with_max_shortfall.balance = pool_with_max_shortfall
				.balance
				.checked_add(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;
			pool_with_max_shortfall.shortfall = pool_with_max_shortfall
				.shortfall
				.checked_sub(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;

			sum_oversupply = sum_oversupply.checked_sub(bite_in_usd).ok_or(Error::<T>::NumOverflow)?;
			sum_shortfall = sum_shortfall.checked_sub(bite_in_usd).ok_or(Error::<T>::NumOverflow)?;
		}

		Ok(to_sell_list)
	}
/// Collects information about required transactions on DEX.
Collects information about required transactions on DEX.
Collects information about required transactions on DEX .
fn collects_sales_list() -> sp_std::result::Result<Vec<Sales>, DispatchError> {
		// Collecting information about the current state of liquidation pools.
		let (mut information_vec, mut sum_oversupply, mut sum_shortfall) =
			CurrencyId::get_enabled_tokens_in_protocol(UnderlyingAsset)
				.iter()
				.filter(|&underlying_id| T::LiquidityPoolsManager::pool_exists(underlying_id))
				.try_fold(
					(Vec::<LiquidationInformation>::new(), Balance::zero(), Balance::zero()),
					|(mut current_vec, mut current_sum_oversupply, mut current_sum_shortfall),
					 pool_id|
					 -> sp_std::result::Result<(Vec<LiquidationInformation>, Balance, Balance), DispatchError> {
						let oracle_price =
							T::PriceSource::get_underlying_price(*pool_id).ok_or(Error::<T>::InvalidFeedPrice)?;
						// Liquidation pool balance in USD: liquidation_pool_balance * oracle_price
						let liquidation_pool_balance = Rate::from_inner(Self::get_pool_available_liquidity(*pool_id))
							.checked_mul(&oracle_price)
							.map(|x| x.into_inner())
							.ok_or(Error::<T>::BalanceOverflow)?;
						let ideal_balance = Self::calculate_ideal_balance(*pool_id)?;
						// If the pool is not balanced:
						// oversupply = liquidation_pool_balance - ideal_balance
						// shortfall = ideal_balance - liquidation_pool_balance
						let (oversupply, shortfall) = match liquidation_pool_balance.cmp(&ideal_balance) {
							Ordering::Greater => (liquidation_pool_balance - ideal_balance, Balance::zero()),
							Ordering::Less => (Balance::zero(), ideal_balance - liquidation_pool_balance),
							Ordering::Equal => (Balance::zero(), Balance::zero()),
						};
						current_vec.push(LiquidationInformation {
							pool_id: *pool_id,
							balance: liquidation_pool_balance,
							oversupply,
							shortfall,
						});
						// Calculate sum_extra and sum_shortfall for all pools.
						let deviation_threshold = Self::liquidation_pools_data(*pool_id).deviation_threshold;
						// right_border = ideal_balance + ideal_balance * deviation_threshold
						let right_border = sum_with_mult_result(ideal_balance, ideal_balance, deviation_threshold)
							.map_err(|_| Error::<T>::BalanceOverflow)?;
						// left_border = ideal_balance - ideal_balance * deviation_threshold
						let left_border = ideal_balance
							.checked_sub(
								Rate::from_inner(ideal_balance)
									.checked_mul(&deviation_threshold)
									.map(|x| x.into_inner())
									.ok_or(Error::<T>::NumOverflow)?,
							)
							.ok_or(Error::<T>::NumOverflow)?;
						if liquidation_pool_balance > right_border {
							current_sum_oversupply = current_sum_oversupply
								.checked_add(oversupply)
								.ok_or(Error::<T>::BalanceOverflow)?;
						}
						if liquidation_pool_balance < left_border {
							current_sum_shortfall = current_sum_shortfall
								.checked_add(shortfall)
								.ok_or(Error::<T>::BalanceOverflow)?;
						}
						Ok((current_vec, current_sum_oversupply, current_sum_shortfall))
					},
				)?;
		// Contains information about the necessary transactions on the DEX.
		let mut to_sell_list: Vec<Sales> = Vec::new();
		while sum_shortfall > Balance::zero() && sum_oversupply > Balance::zero() {
			// Find the pool with the maximum oversupply and the pool with the maximum shortfall.
			let (max_oversupply_index, max_oversupply_pool_id, max_oversupply) = information_vec
				.iter()
				.enumerate()
				.max_by(|(_, a), (_, b)| a.oversupply.cmp(&b.oversupply))
				.map(|(index, pool)| (index, pool.pool_id, pool.oversupply))
				.ok_or(Error::<T>::PoolNotFound)?;
			let (max_shortfall_index, max_shortfall_pool_id, max_shortfall) = information_vec
				.iter()
				.enumerate()
				.max_by(|(_, a), (_, b)| a.shortfall.cmp(&b.shortfall))
				.map(|(index, pool)| (index, pool.pool_id, pool.shortfall))
				.ok_or(Error::<T>::PoolNotFound)?;
			// The number USD equivalent to be sent to the DEX will be equal to
			// the minimum value between (max_shortfall, max_oversupply).
			let bite_in_usd = max_oversupply.min(max_shortfall);
			// Add "sale" to the sales list.
			to_sell_list.push(Sales {
				supply_pool_id: max_oversupply_pool_id,
				target_pool_id: max_shortfall_pool_id,
				amount: bite_in_usd,
			});
			// Updating the information vector.
			let pool_with_max_oversupply = &mut information_vec[max_oversupply_index];
			pool_with_max_oversupply.balance = pool_with_max_oversupply
				.balance
				.checked_sub(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;
			pool_with_max_oversupply.oversupply = pool_with_max_oversupply
				.oversupply
				.checked_sub(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;
			let pool_with_max_shortfall = &mut information_vec[max_shortfall_index];
			pool_with_max_shortfall.balance = pool_with_max_shortfall
				.balance
				.checked_add(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;
			pool_with_max_shortfall.shortfall = pool_with_max_shortfall
				.shortfall
				.checked_sub(bite_in_usd)
				.ok_or(Error::<T>::NotEnoughBalance)?;
			sum_oversupply = sum_oversupply.checked_sub(bite_in_usd).ok_or(Error::<T>::NumOverflow)?;
			sum_shortfall = sum_shortfall.checked_sub(bite_in_usd).ok_or(Error::<T>::NumOverflow)?;
		}
		Ok(to_sell_list)
	}
fn collects_sales_list ( ) -> sp_std :: result :: Result < Vec < Sales > , DispatchError > { // Collecting information about the current state of liquidation pools. let ( mut information_vec , mut sum_oversupply , mut sum_shortfall ) = CurrencyId :: get_enabled_tokens_in_protocol ( UnderlyingAsset ) . iter ( ) . filter ( | & underlying_id | T :: LiquidityPoolsManager :: pool_exists ( underlying_id ) ) . try_fold ( ( Vec :: < LiquidationInformation > :: new ( ) , Balance :: zero ( ) , Balance :: zero ( ) ) , | ( mut current_vec , mut current_sum_oversupply , mut current_sum_shortfall ) , pool_id | -> sp_std :: result :: Result < ( Vec < LiquidationInformation > , Balance , Balance ) , DispatchError > { let oracle_price = T :: PriceSource :: get_underlying_price ( * pool_id ) . ok_or ( Error :: < T > :: InvalidFeedPrice ) ? ; // Liquidation pool balance in USD: liquidation_pool_balance * oracle_price let liquidation_pool_balance = Rate :: from_inner ( Self :: get_pool_available_liquidity ( * pool_id ) ) . checked_mul ( & oracle_price ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: BalanceOverflow ) ? ; let ideal_balance = Self :: calculate_ideal_balance ( * pool_id ) ? ; // If the pool is not balanced: // oversupply = liquidation_pool_balance - ideal_balance // shortfall = ideal_balance - liquidation_pool_balance let ( oversupply , shortfall ) = match liquidation_pool_balance . cmp ( & ideal_balance ) { Ordering :: Greater => ( liquidation_pool_balance - ideal_balance , Balance :: zero ( ) ) , Ordering :: Less => ( Balance :: zero ( ) , ideal_balance - liquidation_pool_balance ) , Ordering :: Equal => ( Balance :: zero ( ) , Balance :: zero ( ) ) , } ; current_vec . push ( LiquidationInformation { pool_id : * pool_id , balance : liquidation_pool_balance , oversupply , shortfall , } ) ; // Calculate sum_extra and sum_shortfall for all pools. let deviation_threshold = Self :: liquidation_pools_data ( * pool_id ) . deviation_threshold ; // right_border = ideal_balance + ideal_balance * deviation_threshold let right_border = sum_with_mult_result ( ideal_balance , ideal_balance , deviation_threshold ) . map_err ( | _ | Error :: < T > :: BalanceOverflow ) ? ; // left_border = ideal_balance - ideal_balance * deviation_threshold let left_border = ideal_balance . checked_sub ( Rate :: from_inner ( ideal_balance ) . checked_mul ( & deviation_threshold ) . map ( | x | x . into_inner ( ) ) . ok_or ( Error :: < T > :: NumOverflow ) ? , ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; if liquidation_pool_balance > right_border { current_sum_oversupply = current_sum_oversupply . checked_add ( oversupply ) . ok_or ( Error :: < T > :: BalanceOverflow ) ? ; } if liquidation_pool_balance < left_border { current_sum_shortfall = current_sum_shortfall . checked_add ( shortfall ) . ok_or ( Error :: < T > :: BalanceOverflow ) ? ; } Ok ( ( current_vec , current_sum_oversupply , current_sum_shortfall ) ) } , ) ? ; // Contains information about the necessary transactions on the DEX. let mut to_sell_list : Vec < Sales > = Vec :: new ( ) ; while sum_shortfall > Balance :: zero ( ) && sum_oversupply > Balance :: zero ( ) { // Find the pool with the maximum oversupply and the pool with the maximum shortfall. let ( max_oversupply_index , max_oversupply_pool_id , max_oversupply ) = information_vec . iter ( ) . enumerate ( ) . max_by ( | ( _ , a ) , ( _ , b ) | a . oversupply . cmp ( & b . oversupply ) ) . map ( | ( index , pool ) | ( index , pool . pool_id , pool . oversupply ) ) . ok_or ( Error :: < T > :: PoolNotFound ) ? ; let ( max_shortfall_index , max_shortfall_pool_id , max_shortfall ) = information_vec . iter ( ) . enumerate ( ) . max_by ( | ( _ , a ) , ( _ , b ) | a . shortfall . cmp ( & b . shortfall ) ) . map ( | ( index , pool ) | ( index , pool . pool_id , pool . shortfall ) ) . ok_or ( Error :: < T > :: PoolNotFound ) ? ; // The number USD equivalent to be sent to the DEX will be equal to // the minimum value between (max_shortfall, max_oversupply). let bite_in_usd = max_oversupply . min ( max_shortfall ) ; // Add "sale" to the sales list. to_sell_list . push ( Sales { supply_pool_id : max_oversupply_pool_id , target_pool_id : max_shortfall_pool_id , amount : bite_in_usd , } ) ; // Updating the information vector. let pool_with_max_oversupply = & mut information_vec [ max_oversupply_index ] ; pool_with_max_oversupply . balance = pool_with_max_oversupply . balance . checked_sub ( bite_in_usd ) . ok_or ( Error :: < T > :: NotEnoughBalance ) ? ; pool_with_max_oversupply . oversupply = pool_with_max_oversupply . oversupply . checked_sub ( bite_in_usd ) . ok_or ( Error :: < T > :: NotEnoughBalance ) ? ; let pool_with_max_shortfall = & mut information_vec [ max_shortfall_index ] ; pool_with_max_shortfall . balance = pool_with_max_shortfall . balance . checked_add ( bite_in_usd ) . ok_or ( Error :: < T > :: NotEnoughBalance ) ? ; pool_with_max_shortfall . shortfall = pool_with_max_shortfall . shortfall . checked_sub ( bite_in_usd ) . ok_or ( Error :: < T > :: NotEnoughBalance ) ? ; sum_oversupply = sum_oversupply . checked_sub ( bite_in_usd ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; sum_shortfall = sum_shortfall . checked_sub ( bite_in_usd ) . ok_or ( Error :: < T > :: NumOverflow ) ? ; } Ok ( to_sell_list ) }
Collects information about required transactions on DEX.
Collects information about required transactions on DEX .