# FPMMFactory

**FPMMFactory** deploys and tracks FPMM pool proxies. Each pool is created via a **proxy** (FPMMProxy) pointing to a registered implementation. The factory stores default parameters (fees, rebalance incentive, thresholds) and enforces caps on deployment defaults; individual pools can later be reconfigured within pool-level limits.

**Contract:** [mento-protocol/mento-core](https://github.com/mento-protocol/mento-core) — `contracts/swap/FPMMFactory.sol`

***

## Interacting with the factory (code examples)

### Finding a pool for a token pair

Tokens are ordered by address. Use `sortTokens` so you pass the pair in the order the factory expects:

```solidity
IFPMMFactory factory = IFPMMFactory(factoryAddress);

(address token0, address token1) = factory.sortTokens(tokenA, tokenB);
address pool = factory.getPool(token0, token1);

if (pool != address(0)) {
    // Pool exists; use it for getAmountOut, swap, etc.
}
```

### Precomputing the pool address (before deployment)

If the pool is not deployed yet, you can compute the proxy address that will be used when the owner deploys it. Useful for integrators that need to show a “future” pool address or for CREATE2-style flows:

```solidity
address poolOrFuture = factory.getOrPrecomputeProxyAddress(token0, token1);
// If pool exists, returns deployed address; else returns precomputed proxy address
```

### Listing all deployed pools

```solidity
address[] memory pools = factory.deployedFPMMAddresses();
for (uint256 i = 0; i < pools.length; i++) {
    address pool = pools[i];
    // Use pool with IFPMM(pool).tokens(), getAmountOut, etc.
}
```

***

## State

| Field                              | Meaning                                                                                                    |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `oracleAdapter`                    | Default oracle adapter address used when deploying a pool (can be overridden per deployment).              |
| `proxyAdmin`                       | Admin for the FPMM proxy (upgrade authority).                                                              |
| `deployedFPMMs[token0][token1]`    | Address of the deployed pool for the token pair (tokens sorted by address).                                |
| `isPool[pool]`                     | True if the address is a pool deployed by this factory.                                                    |
| `deployedFPMMAddresses[]`          | List of all deployed pool addresses.                                                                       |
| `isRegisteredImplementation[impl]` | True if `impl` is an allowed FPMM implementation for deployment.                                           |
| `registeredImplementations[]`      | List of registered implementations.                                                                        |
| `defaultParams`                    | Default `FPMMParams` (fees, rebalance incentive, thresholds) applied when deploying with factory defaults. |

***

## Token order

* **sortTokens(tokenA, tokenB)** — Returns `(token0, token1)` with `token0 < token1` by address. Reverts if `tokenA == tokenB` or zero. All pool lookups use this order.
* **getPool(token0, token1)** — Returns the pool address for that pair. Caller must pass tokens in the same order as `sortTokens` (or use `getPool` with sorted pair).

***

## Deployment

* **deployFPMM(...)** — `onlyOwner`. Parameters: `fpmmImplementation`, `customOracleAdapter`, `customProxyAdmin`, `customOwner`, `token0`, `token1`, `referenceRateFeedID`, `invertRateFeed`, `customParams`.
  * Tokens are sorted; pair must not already exist.
  * Deploys an **FPMMProxy** (CreateX) with the given implementation, then initializes the proxy with the provided oracle adapter, rate feed ID, invert flag, owner, and params.
  * Registers the new pool in `deployedFPMMs` and `isPool`.
* **getOrPrecomputeProxyAddress(token0, token1)** — Returns the deployed pool address if it exists, otherwise the **precomputed** CreateX address for that pair (so integrators can compute the pool address before deployment).

***

## Default params and caps

`defaultParams` is an `IFPMM.FPMMParams` struct. When setting defaults via **setDefaultParams**:

* `protocolFee + lpFee` ≤ **200** (2% combined).
* `protocolFeeRecipient != address(0)`.
* `rebalanceIncentive` ≤ **100** (1%).
* `rebalanceThresholdAbove` ≤ **10,000** bps.
* `rebalanceThresholdBelow` ≤ **5,000** bps.

Pool-level setters (on FPMM) allow the same threshold caps; the factory only restricts **default** values at deployment.

***

## Admin

| Function                                    | Effect                                                                                 |
| ------------------------------------------- | -------------------------------------------------------------------------------------- |
| `setOracleAdapter(addr)`                    | Set default oracle adapter.                                                            |
| `setProxyAdmin(addr)`                       | Set proxy admin.                                                                       |
| `setDefaultParams(params)`                  | Set default FPMM params (subject to caps above).                                       |
| `registerFPMMImplementation(impl)`          | Allow an implementation for deployment.                                                |
| `unregisterFPMMImplementation(impl, index)` | Remove implementation; `index` must match its position in `registeredImplementations`. |

***

## See also

* [FPMM](/mento-v3/build/smart-contracts/fpmm.md) — Pool contract.
* [Deployments](/mento-v3/build/deployments.md) — Addresses and verification.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mento.org/mento-v3/build/smart-contracts/fpmmfactory.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
