> For a complete index of Agora Finance documentation, fetch https://docs.agora.finance/llms.txt

# Factory Contract

> Factory contract API reference — creating pairs, querying deployments, and deterministic CREATE3 addresses

# Factory Contract Overview

`AgoraStableSwapFactory` is responsible for deploying Agora Instant Settlement pairs. The deployment process uses [`CREATE3`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L616-L646) for deterministic deployment based off `token0` and `token1`, meaning integrators can discover every pool without relying on off-chain registries.

## Access‑Control Roles

| Role constant                 | Capabilities                                                                                                    |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `ACCESS_CONTROL_MANAGER_ROLE` | Grants/revokes any other role                                                                                   |
| `APPROVED_DEPLOYER_ROLE`      | Allowed to call [`createPair`](#createpair) and deploy new pools. Curated by the `ACCESS_CONTROL_MANAGER_ROLE`. |

## Events

### `PairCreated`

```solidity
event PairCreated(address indexed token0, address indexed token1, address pair);
```

Emitted each time a pair is created via [`createPair`](#createpair).

* Only a user with [`APPROVED_DEPLOYER`](#accesscontrol-roles) role can call the underlying function that triggers this event.
* [`token0`](/instant-settlement/core-concepts#token0) is guaranteed to be strictly less than [`token1`](/instant-settlement/core-concepts#token1) by sorting order

### `SetApprovedDeployer`

```solidity
event SetApprovedDeployer(address indexed approvedDeployer, bool isApproved);
```

Emitted when a new approved deployer is set, by calling `setApprovedDeployers`.

* Only a user with [`ACCESS_CONTROL_MANAGER_ROLE`](/instant-settlement/smart-contracts/pair-contract#accesscontrol-roles) role can call the underlying function that triggers this event.

---

## Read-Only Functions

### `getAllPairData`

```solidity
function getAllPairData() public view returns (PairData[] memory)
```

Returns the information of all pairs deployed on a chain as an array of `PairData` structures, each containing the address of the pair, as well as information about the tokens that comprise the pair.

### `getPairFromTokens`

```solidity
function getPairFromTokens(address _token0, address _token1) public view returns (address)
```

Returns the address of the pair for [`token0`](../core-concepts#token0) and [`token1`](../core-concepts#token1), if it has been created, else `address(0)`

* [`token0`](../core-concepts#token0) and [`token1`](../core-concepts#token1) are interchangeable

### `computePairDeploymentAddress`

```solidity
function computePairDeploymentAddress(
    address _tokenA,
    address _tokenB
) public view returns (address _pairDeploymentAddress)
```

Returns the [deterministic deployment](../core-concepts/#deterministic-deployment) address for a `AgoraStableSwapPair` deployed with `tokenA` and `tokenB` as swapping tokens.

* The tokens are sorted before calculating the deployment address.
* The deployment computation uses [`CreateX.computeCreate3Address`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L830-L855)

### `version`

```solidity
function version() public pure returns (Version memory _version)
```

Returns a `Version` structure with current deployment version for the factory

---

## State-Changing Functions:

### `createPair`

```solidity
function createPair(CreatePairArgs memory _pairArgs) external returns (address pair)
```

Creates a new pair with the given parameters, as long as a pair with [`token0`](../core-concepts#token0) and [`token1`](../core-concepts#token1) don't exist already

* Only a user with `APPROVED_DEPLOYER` role can call this function.
* Emits [`PairCreated`](#paircreated)
* The pair is deployed with its initial configuration, covering initial [`access control roles`](./pair-contract#accesscontrol-roles), [`swapping fees`](./pair-contract#setfeebounds) and [`pricing parameters`](./pair-contract#setoraclepricebounds)
* The pair is deployed deterministically using [`CreateX.deployCreate3`](https://github.com/pcaversaccio/createx/blob/main/src/CreateX.sol#L616-L646)

---

## Interface

```solidity
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.4;

library AgoraStableSwapFactory {
    struct AgoraStableSwapDefaultParamsStorage {
        address initialDefaultAdminAddress;
        address initialDefaultWhitelister;
        address initialDefaultFeeSetter;
        address initialDefaultTokenRemover;
        address initialDefaultPauser;
        address initialDefaultPriceSetter;
        address initialDefaultTokenReceiver;
        address initialDefaultFeeReceiver;
    }

    struct CreatePairArgs {
        address token0;
        uint256 token0Decimals;
        uint256 minToken0PurchaseFee;
        uint256 maxToken0PurchaseFee;
        uint256 token0PurchaseFee;
        address token1;
        uint256 token1Decimals;
        uint256 minToken1PurchaseFee;
        uint256 maxToken1PurchaseFee;
        uint256 token1PurchaseFee;
        uint256 minBasePrice;
        uint256 maxBasePrice;
        uint256 basePrice;
        int256 minAnnualizedInterestRate;
        int256 maxAnnualizedInterestRate;
        int256 annualizedInterestRate;
    }

    struct PairData {
        address pairAddress;
        TokenInfo token0;
        TokenInfo token1;
    }

    struct TokenInfo {
        address tokenAddress;
        string name;
        string symbol;
        uint256 decimals;
    }

    struct Version {
        uint256 major;
        uint256 minor;
        uint256 patch;
    }
}

interface IAgoraStableSwapFactory {
    struct InitializeParams {
        address initialStableSwapImplementation;
        address initialStableSwapProxyAdminAddress;
        address initialFactoryAccessControlManager;
        address[] initialApprovedDeployers;
        address initialDefaultAdminAddress;
        address initialDefaultWhitelister;
        address initialDefaultFeeSetter;
        address initialDefaultTokenRemover;
        address initialDefaultPauser;
        address initialDefaultPriceSetter;
        address initialDefaultTokenReceiver;
        address initialDefaultFeeReceiver;
    }

    error AddressIsNotRole(string role);
    error CannotRemoveLastManager();
    error DecimalDeltaTooLarge();
    error IdenticalAddresses();
    error InvalidInitialization();
    error InvalidTokenOrder();
    error NotInitializing();
    error PairExists();
    error RoleNameTooLong();
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
    error ZeroAddress();

    event Initialized(uint64 version);
    event PairCreated(address indexed token0, address indexed token1, address pair);
    event RoleAssigned(string indexed role, address indexed address_);
    event RoleRevoked(string indexed role, address indexed address_);
    event SetApprovedDeployer(address indexed approvedDeployer, bool isApproved);
    event SetDefaultRoles(
        address initialAdminAddress,
        address initialWhitelister,
        address initialFeeSetter,
        address initialTokenRemover,
        address initialPauser,
        address initialPriceSetter,
        address initialTokenReceiver,
        address initialFeeReceiver
    );

    function ACCESS_CONTROL_MANAGER_ROLE() external view returns (string memory);

    function AGORA_ACCESS_CONTROL_STORAGE_SLOT() external view returns (bytes32);

    function AGORA_STABLE_SWAP_FACTORY_STORAGE_SLOT() external view returns (bytes32);

    function APPROVED_DEPLOYER() external view returns (string memory);

    function allPairs() external view returns (address[] memory _pairs);

    function assignRole(string memory _role, address _newAddress, bool _addRole) external;

    function computePairDeploymentAddress(
        address _tokenA,
        address _tokenB
    ) external view returns (address _pairDeploymentAddress);

    function createPair(AgoraStableSwapFactory.CreatePairArgs memory _pairArgs) external returns (address pair);

    function getAgoraStableSwapDefaultParamsStorage()
        external
        view
        returns (AgoraStableSwapFactory.AgoraStableSwapDefaultParamsStorage memory);

    function getAllPairData() external view returns (AgoraStableSwapFactory.PairData[] memory);

    function getAllRoles() external view returns (string[] memory _roles);

    function getPairFromTokens(address _token0, address _token1) external view returns (address);

    function getRoleMembers(string memory _role) external view returns (address[] memory _members);

    function hasRole(string memory _role, address _address) external view returns (bool);

    function initialize(InitializeParams memory _params) external;

    function name() external pure returns (string memory);

    function setApprovedDeployers(address[] memory _approvedDeployers, bool _setApproved) external;

    function setDefaultRoles(
        address _initialAdminAddress,
        address _initialWhitelister,
        address _initialFeeSetter,
        address _initialTokenRemover,
        address _initialPauser,
        address _initialPriceSetter,
        address _initialTokenReceiver,
        address _initialFeeReceiver
    ) external;

    function sortTokens(address _tokenA, address _tokenB) external pure returns (address _token0, address _token1);

    function stableSwapImplementation() external view returns (address);

    function stableSwapProxyAdmin() external view returns (address);

    function version() external pure returns (AgoraStableSwapFactory.Version memory _version);
}

```

---

## ABI

The ABI of the `AgorastableSwapFactory` is available [here](https://snowscan.xyz/address/0x9a1Fdc4e4EF759877F09455CB49C395ba049634F#code)