# RewardsDistributorFactoryV1

### Overview <a href="#overview" id="overview"></a>

**RewardsDistributorFactoryV1** is an upgradeable contract (using UUPS) that deploys new instances of **IncentiveRewardsDistributor**. It restricts calls to `createRewardsDistributor` such that only the **escrow vote manager** can request a new distributor, thus ensuring controlled creation of additional reward distribution contracts.

**Key Roles and Features:**

1. **Factory Pattern:** It centralizes the instantiation of **IncentiveRewardsDistributor** contracts, simplifying the process of creating new distributors for different escrow managers.
2. **Access Control:** Only the **escrow vote manager** can call `createRewardsDistributor`, preventing unauthorized distribution contract creation.
3. **Upgradeable via UUPS:** Ensures the factory contract can be upgraded over time, with ownership-based control on upgrades.

By implementing `IRewardsDistributorFactoryV1`, **RewardsDistributorFactoryV1** provides a standard interface for deployment logic and event transparency (though no new custom events are declared here beyond the interface's contract structure).

***

### Inherited Contracts and Interfaces <a href="#inherited-contracts-and-interfaces" id="inherited-contracts-and-interfaces"></a>

* **UUPSUpgradeable (OpenZeppelin):**\
  Provides the upgrade mechanism under the UUPS proxy standard, restricting upgrades to the contract owner.
* **OwnableUpgradeable (OpenZeppelin):**\
  Establishes ownership logic, allowing the owner to authorize upgrades and potentially modify other aspects of the factory (not used extensively here but available if needed).
* **IRewardsDistributorFactoryV1:**\
  Declares the `initialize` and `createRewardsDistributor` functions, along with an `InvalidCaller` error.

**Additional External References:**

* **IncentiveRewardsDistributor:**\
  The contract being deployed by this factory. It manages incentive reward distributions for an escrow manager and is constructed with references to the escrow vote manager and escrow manager.

***

### State Variables <a href="#state-variables" id="state-variables"></a>

```solidity
address public s_escrowVoteManager;
```

* **`s_escrowVoteManager (address)`**:\
  The address of the escrow vote manager contract. Only this address may invoke `createRewardsDistributor` on the factory.

***

### Constructor <a href="#constructor" id="constructor"></a>

```solidity
constructor() {
    _disableInitializers();
}
```

* **Description:**\
  Disables contract initializers to ensure `initialize()` can only be called once. A standard pattern for UUPS upgradeable contracts.

***

### External Functions <a href="#external-functions" id="external-functions"></a>

#### 1. **`initialize(address owner_, address escrowVoteManager_)`** <a href="#id-1-initialize-address-owner_-address-escrowvotemanager" id="id-1-initialize-address-owner_-address-escrowvotemanager"></a>

```solidity
function initialize(address owner_, address escrowVoteManager_) external initializer
```

* **Description:**\
  Configures the factory contract by assigning ownership (`owner_`) and storing the **escrow vote manager** address. This function can be called only once due to the `initializer` modifier.
* **Parameters:**
  * `owner_`: The address to be assigned as the owner of this factory contract.
  * `escrowVoteManager_`: The address of the escrow vote manager responsible for orchestrating new distributor creations.
* **Logic and Effects:**
  1. Invokes `__UUPSUpgradeable_init()` and `__Ownable_init(owner_)` for upgrade and ownership setup.
  2. Sets `s_escrowVoteManager = escrowVoteManager_`.

***

#### 2. **`createRewardsDistributor(address escrowManager_)`** <a href="#id-2-createrewardsdistributor-address-escrowmanager" id="id-2-createrewardsdistributor-address-escrowmanager"></a>

```solidity
function createRewardsDistributor(address escrowManager_) external returns (address)
```

* **Description:**\
  Creates and returns a new **IncentiveRewardsDistributor** contract instance, linking it to the calling escrow vote manager (`msg.sender`) and the provided `escrowManager_`. The call reverts if not invoked by `s_escrowVoteManager`.
* **Checks:**
  * Must be called by `s_escrowVoteManager`. Otherwise, it reverts with `InvalidCaller()`.
* **Logic:**
  1. If `msg.sender != s_escrowVoteManager`, revert with `InvalidCaller()`.
  2. Deploys a new **IncentiveRewardsDistributor** by calling its constructor:

     ```solidity
     new IncentiveRewardsDistributor(msg.sender, escrowManager_)
     ```
  3. Returns the newly created contract’s address.
* **Return:**
  * `address`: The address of the newly created incentive rewards distributor contract.

***

### Internal Functions <a href="#internal-functions" id="internal-functions"></a>

#### 1. **`_authorizeUpgrade(address newImplementation)`** <a href="#id-1-_authorizeupgrade-address-newimplementation" id="id-1-_authorizeupgrade-address-newimplementation"></a>

```solidity
function _authorizeUpgrade(address) internal override onlyOwner
```

* **Description:**\
  Restricts upgrades of this factory to the contract’s owner, following the UUPS standard. This ensures that only the owner can deploy a new logic implementation for this factory contract.

***

### Errors <a href="#errors" id="errors"></a>

* **`InvalidCaller()`**\
  Thrown if `createRewardsDistributor` is called by an address other than `s_escrowVoteManager`.

***

### Summary <a href="#summary" id="summary"></a>

**RewardsDistributorFactoryV1** provides a straightforward pattern for creating new **IncentiveRewardsDistributor** instances. By restricting calls to its `createRewardsDistributor` function to the **escrow vote manager**, it ensures that only authorized processes can spin up new distributor contracts. Coupled with UUPS upgradeability, the factory is future-proofed, allowing for modifications to how distributors are instantiated if the protocol’s requirements evolve over time.


---

# 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.crosscurve.fi/developer-documentation/guide-for-developers/technical-documentation-for-crosscurve-dao-smart-contracts/rewardsdistributorfactoryv1.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.
