> For the complete documentation index, see [llms.txt](https://abc-71.gitbook.io/curriculum/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://abc-71.gitbook.io/curriculum/week-5/dex-factory.md).

# DEX: Factory

The **factory contract** is a central smart contract in many decentralized exchanges (DEXs) built on Automated Market Makers (AMMs), such as Uniswap. This contract handles the creation and tracking of individual **liquidity pools** for each token pair traded on the platform. Here’s a closer look at its workings, as well as how to test a factory contract.

## Factory Contract:

In an AMM, each token pair (e.g., ETH/DAI) has its own **pair contract** (or **pool**), responsible for managing liquidity and enabling swaps between those tokens. The **factory contract** is responsible for:

* **Creating new pairs**: The factory contract deploys a new pool for each unique token pair, ensuring that there’s only one pool per pair.
* **Storing pair addresses**: It maintains a mapping between token pairs and their corresponding pool addresses, allowing the DEX to identify and interact with the correct pool.
* **Tracking all pairs**: For platforms with multiple pools, the factory contract also serves as a directory, enabling easy tracking and querying of all created pairs.

For example, in a Uniswap-style DEX, the factory contract uses a `createPair()` function to create pools for each token pair. If a user tries to swap tokens for a new pair, the factory checks if a pool exists and, if not, deploys a new pool contract.

### Factory Contract Example (Pseudo Solidity Code)

Here's an example of what a factory contract might look like:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Factory {
    mapping(address => mapping(address => address)) public getPair;  // Tracks pairs
    address[] public allPairs;  // List of all pairs

    event PairCreated(address indexed tokenA, address indexed tokenB, address pair, uint);

    function createPair(address tokenA, address tokenB) external returns (address pair) {
        require(tokenA != tokenB, "Identical addresses not allowed");
        require(getPair[tokenA][tokenB] == address(0), "Pair already exists");

        bytes memory bytecode = abi.encodePacked(type(Pair).creationCode, abi.encode(tokenA, tokenB));
        bytes32 salt = keccak256(abi.encodePacked(tokenA, tokenB));
        assembly {
            pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
        }

        getPair[tokenA][tokenB] = pair;
        getPair[tokenB][tokenA] = pair;
        allPairs.push(pair);

        emit PairCreated(tokenA, tokenB, pair, allPairs.length);
    }

    function getAllPairs() external view returns (address[] memory) {
        return allPairs;
    }
}
```

* **`getPair[tokenA][tokenB]`**: Maps a token pair to its respective pool.
* **`createPair()`**: Deploys a new pair contract for a token pair.
* **Event Logging**: The `PairCreated` event logs the new pair creation, which can be useful for tracking.

### Testing the Factory Contract

To test the factory contract and ensure it operates as expected, you can use a framework like **Hardhat** or **Truffle**. Below is a guide on setting up a test for this contract:

**Step 1: Install Dependencies**

Ensure you have **Node.js** and **npm** installed, then install Hardhat:

```bash
npm install --save-dev hardhat
```

**Step 2: Create and Configure Your Testing Project**

Inside your Hardhat project, set up the factory contract in `contracts/Factory.sol`, then create a test file in `test/Factory.test.js` for JavaScript tests.

**Step 3: Write Unit Tests for the Factory Contract**

Here’s a sample test script for the factory contract using Hardhat and Mocha:

```javascript
const { expect } = require("chai");

describe("Factory Contract", function () {
  let Factory;
  let factory;
  let owner;
  let tokenA;
  let tokenB;

  beforeEach(async function () {
    [owner, tokenA, tokenB] = await ethers.getSigners();
    Factory = await ethers.getContractFactory("Factory");
    factory = await Factory.deploy();
    await factory.deployed();
  });

  it("Should create a new pair", async function () {
    await factory.createPair(tokenA.address, tokenB.address);

    const pairAddress = await factory.getPair(tokenA.address, tokenB.address);
    expect(pairAddress).to.not.equal(ethers.constants.AddressZero);
  });

  it("Should not allow identical addresses", async function () {
    await expect(factory.createPair(tokenA.address, tokenA.address)).to.be.revertedWith("Identical addresses not allowed");
  });

  it("Should not allow duplicate pairs", async function () {
    await factory.createPair(tokenA.address, tokenB.address);
    await expect(factory.createPair(tokenA.address, tokenB.address)).to.be.revertedWith("Pair already exists");
  });

  it("Should list all pairs", async function () {
    await factory.createPair(tokenA.address, tokenB.address);
    const allPairs = await factory.getAllPairs();
    expect(allPairs.length).to.equal(1);
  });
});
```

**Explanation of Tests:**

* **Create a New Pair**: Verifies that calling `createPair()` for unique tokens successfully creates a new pair.
* **Identical Address Check**: Ensures that creating a pair with the same token address fails.
* **Duplicate Pair Check**: Confirms that a pair for the same tokens cannot be created more than once.
* **Get All Pairs**: Checks that `getAllPairs()` correctly lists the created pairs.

#### Running Tests

1. Compile the contracts:

   ```bash
   npx hardhat compile
   ```
2. Run the tests:

   ```bash
   npx hardhat test
   ```

If all tests pass, this confirms that your factory contract functions as expected, allowing only unique pairs, deploying them correctly, and listing them accurately.

### Additional Test Cases

To expand on testing:

* **Event Emission**: Check that the `PairCreated` event is emitted with correct data upon pair creation.
* **Gas Cost Analysis**: Measure gas costs for pair creation, as this can impact usability on mainnet deployments.

### Links and Resources

For additional information on setting up Hardhat and contract testing, visit:

* [Hardhat Documentation](https://hardhat.org/docs)
* [Solidity Documentation](https://docs.soliditylang.org/)

Testing your factory contract is essential for ensuring reliable operation within a DEX environment. By verifying contract creation, preventing duplicate pairs, and listing pairs accurately, you ensure a more stable and predictable exchange functionality.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://abc-71.gitbook.io/curriculum/week-5/dex-factory.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.
