# Pool Factory

## Overview

The `PoolFactory` contract is a factory contract that deploys `Pool` contracts. It is owned by a single address, which can be set using the `Ownable` contract. The contract uses `Clones` from OpenZeppelin to clone the `Pool` contract when a new pool is created. The `PoolFactory` contract uses `ReentrancyGuard` to prevent reentrancy attacks. The contract has several public variables, including `router`, `pid`, `maxNumberOfCollateralAssets`, and `originationFee`. The `router` variable holds the address of the Router contract, while `pid` holds the number of pools that have been created. The `maxNumberOfCollateralAssets` variable holds the maximum number of unique collateral assets per pool, and `originationFee` holds the origination fee in wad (1e18 = 100%) for the pools that the contract deploys. The `PoolFactory` contract has a public function called `createPool` that deploys a new `Pool` contract with the specified parameters.

## Creating a pool

The process of creating a pool in the contract involves several steps. First, the `createPool` function is called, providing it with the necessary parameters such as the address of the lending and collateral assets, the coupon yield, the loan-to-value ratio, and the timestamps for when the pool becomes active and matures.

Next, the function performs several checks to ensure that the supplied parameters are valid. This includes checking that the provided addresses are not null, that the loan-to-value ratio and coupon yield are within acceptable ranges, and that the pool will become active and mature at the specified times.

Once the parameters have been validated, the contract uses the OpenZeppelin Clones library to clone the implementation contract for the pool, which is stored in the `poolImplementation` variable. This creates a new instance of the `Pool` contract with the supplied parameters.

The newly created pool is then added to the `pidToPoolAddress` mapping, which maps pool IDs to their corresponding addresses. This allows the contract to easily track and retrieve the address of any created pool by its ID.

Finally, the function returns the address of the newly created pool.

## Helper functions

The contract uses a number of helper functions to assist with the main functionality of deploying new pool contracts. These helper functions include:

* `getAllPools` - this function returns an array of all the pool contracts that have been deployed using this contract.
* `getAllPoolsSlice` - this function allows the caller to retrieve a slice of the array of all pool contracts, starting at a specified index and returning a specified number of contracts.
* `_executeTransferFromWithBalanceChecks` - this is an internal function used by the contract to transfer ERC20 tokens from one address to another, while returning the received amount. It is used to make sure the lent asset is not a fee-on-transfer token.
* `setMaxNumberOfCollateralAssets` - this function allows the owner of the contract to set the maximum number of unique collateral assets that can be included in a pool contract.
* `setOriginationFee` - this function allows the owner of the contract to set the origination fee for pool contracts. This is the fee that borrowers must pay when creating a new loan.
