# Factory

[Git Source](https://github.com/outdoteth/caviar-private-pools/blob/4214d102e516c8e0735261ce0b0adad9ffef842f/src/Factory.sol)

**Inherits:** ERC721, Owned

**Author:** out.eth (@outdoteth)

This contract is used to create and initialize new private pools. Each time a private pool is created, a new NFT representing that private pool is minted to the creator. All protocol fees also accrue to this contract and can be withdrawn by the admin.

## State Variables

### privatePoolImplementation

The address of the private pool implementation that proxies point to.

```solidity
address public privatePoolImplementation;
```

### privatePoolMetadata

Helper contract that constructs the private pool metadata svg and json for each pool NFT.

```solidity
address public privatePoolMetadata;
```

### protocolFeeRate

The protocol fee that is taken on each buy/sell/change. It's in basis points: 350 = 3.5%.

```solidity
uint16 public protocolFeeRate;
```

## Functions

### constructor

```solidity
constructor() ERC721("Caviar Private Pools", "POOL") Owned(msg.sender);
```

### receive

```solidity
receive() external payable;
```

### create

Creates a new private pool using the minimal proxy pattern that points to the private pool implementation. The caller must approve the factory to transfer the NFTs that will be deposited to the pool.

```solidity
function create(
    address _baseToken,
    address _nft,
    uint128 _virtualBaseTokenReserves,
    uint128 _virtualNftReserves,
    uint56 _changeFee,
    uint16 _feeRate,
    bytes32 _merkleRoot,
    bool _useStolenNftOracle,
    bool _payRoyalties,
    bytes32 _salt,
    uint256[] memory tokenIds,
    uint256 baseTokenAmount
) public payable returns (PrivatePool privatePool);
```

**Parameters**

| Name                        | Type        | Description                                       |
| --------------------------- | ----------- | ------------------------------------------------- |
| `_baseToken`                | `address`   | The address of the base token.                    |
| `_nft`                      | `address`   | The address of the NFT.                           |
| `_virtualBaseTokenReserves` | `uint128`   | The virtual base token reserves.                  |
| `_virtualNftReserves`       | `uint128`   | The virtual NFT reserves.                         |
| `_changeFee`                | `uint56`    | The change fee.                                   |
| `_feeRate`                  | `uint16`    | The fee rate.                                     |
| `_merkleRoot`               | `bytes32`   | The merkle root.                                  |
| `_useStolenNftOracle`       | `bool`      | Whether to use the stolen NFT oracle.             |
| `_payRoyalties`             | `bool`      |                                                   |
| `_salt`                     | `bytes32`   | The salt that will used on deployment.            |
| `tokenIds`                  | `uint256[]` | The token ids to deposit to the pool.             |
| `baseTokenAmount`           | `uint256`   | The amount of base tokens to deposit to the pool. |

**Returns**

| Name          | Type          | Description                      |
| ------------- | ------------- | -------------------------------- |
| `privatePool` | `PrivatePool` | The address of the private pool. |

### predictPoolDeploymentAddress

Predicts the deployment address of a new private pool.

```solidity
function predictPoolDeploymentAddress(bytes32 salt) public view returns (address predictedAddress);
```

**Parameters**

| Name   | Type      | Description                            |
| ------ | --------- | -------------------------------------- |
| `salt` | `bytes32` | The salt that will used on deployment. |

**Returns**

| Name               | Type      | Description                                           |
| ------------------ | --------- | ----------------------------------------------------- |
| `predictedAddress` | `address` | The predicted deployment address of the private pool. |

### setPrivatePoolMetadata

Sets private pool metadata contract.

```solidity
function setPrivatePoolMetadata(address _privatePoolMetadata) public onlyOwner;
```

**Parameters**

| Name                   | Type      | Description                         |
| ---------------------- | --------- | ----------------------------------- |
| `_privatePoolMetadata` | `address` | The private pool metadata contract. |

### setPrivatePoolImplementation

Sets the private pool implementation contract that newly deployed proxies point to.

```solidity
function setPrivatePoolImplementation(address _privatePoolImplementation) public onlyOwner;
```

**Parameters**

| Name                         | Type      | Description                               |
| ---------------------------- | --------- | ----------------------------------------- |
| `_privatePoolImplementation` | `address` | The private pool implementation contract. |

### setProtocolFeeRate

Sets the protocol fee that is taken on each buy/sell/change. It's in basis points: 350 = 3.5%.

```solidity
function setProtocolFeeRate(uint16 _protocolFeeRate) public onlyOwner;
```

**Parameters**

| Name               | Type     | Description       |
| ------------------ | -------- | ----------------- |
| `_protocolFeeRate` | `uint16` | The protocol fee. |

### withdraw

Withdraws the earned protocol fees.

```solidity
function withdraw(address token, uint256 amount) public onlyOwner;
```

**Parameters**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `token`  | `address` | The token to withdraw.  |
| `amount` | `uint256` | The amount to withdraw. |

### tokenURI

Returns the token URI for a given token id.

```solidity
function tokenURI(uint256 id) public view override returns (string memory);
```

**Parameters**

| Name | Type      | Description   |
| ---- | --------- | ------------- |
| `id` | `uint256` | The token id. |

**Returns**

| Name     | Type     | Description        |
| -------- | -------- | ------------------ |
| `<none>` | `string` | uri The token URI. |

## Events

### Create

```solidity
event Create(address indexed privatePool, uint256[] tokenIds, uint256 baseTokenAmount);
```

### Withdraw

```solidity
event Withdraw(address indexed token, uint256 indexed amount);
```


---

# 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.caviar.sh/technical-reference/custom-pools/smart-contract-api/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.
