# Builders

## Overview

The `Builders` contract is the core component of the protocol. It manages builder pools, allowing users to stake tokens and builders to accumulate and claim MOR rewards based on those stakes.

Each pool is uniquely identified by name and includes parameters such as minimum deposit amount, pool start time, claim lock period, and withdrawal lock time after deposit... Users can deposit tokens into any existing pool, and their effective contribution (virtual deposit) is calculated using a lock multiplier based on how long rewards are locked.

Rewards are not distributed directly to users. Instead, they accumulate at the pool level and can be claimed only by the pool’s builder (admin). Builders then choose how to distribute these rewards off-chain. The global MOR reward rate is calculated across all pools, and each pool receives a share based on its total virtual deposits.

## Key Features

1. Pool creation and configuration: anyone can create a pool with custom parameters; the builder (admin) is assigned at creation.
2. User staking: users stake tokens into any active pool, with lock-based multipliers increasing their contribution weight.
3. Builder-controlled reward claiming: only builders can claim the total pool reward, enabling flexible distribution outside the contract scope.
4. Reward calculation: uses a dynamic rate updated with each user action and proportional to the protocol-wide virtual deposits.
5. Fee system: integrated with `FeeConfig` for applying customizable withdrawal and claim fees.
6. Upgradeable and permissioned: built with UUPS and Ownable patterns for controlled upgrades and ownership-based access.

## Storage

### feeConfig

Address of the `FeeConfig` contract used to calculate protocol fees.

```solidity
address public feeConfig;
```

### buildersTreasury

Address of the `BuildersTreasury` contract which stores and distributes reward tokens.

```solidity
address public buildersTreasury;
```

### depositToken

Address of the MOR token users deposit into builder pools.

```solidity
address public depositToken;
```

### editPoolDeadline

The time window (in seconds) before the pool starts, during which pool parameters can still be edited by the pool admin.

```solidity
uint128 public editPoolDeadline;
```

### minimalWithdrawLockPeriod

Minimum duration (in seconds) after a deposit during which withdrawals are locked.

```solidity
uint256 public minimalWithdrawLockPeriod;
```

### totalPoolData

Aggregated data for all builder pools in the system.

```solidity
TotalPoolData public totalPoolData;

struct TotalPoolData {
  uint256 distributedRewards;
  uint256 rate;
  uint256 totalDeposited;
  uint256 totalVirtualDeposited;
}
```

| Name                    | Description                                                               |
| ----------------------- | ------------------------------------------------------------------------- |
| `distributedRewards`    | Total amount of rewards distributed across all pools. Wei.                |
| `rate`                  | The current reward rate                                                   |
| `totalDeposited`        | Total tokens deposited without applying any multiplier. Wei.              |
| `totalVirtualDeposited` | Total tokens deposited with multiplier (used in reward calculations). Wei |

### builderPools

Mapping of pool ID to pool configuration.

```solidity
mapping(bytes32 => BuilderPool) public builderPools;

struct BuilderPool {
  string name;
  address admin;
  uint128 poolStart;
  uint128 withdrawLockPeriodAfterDeposit;
  uint128 claimLockEnd;
  uint256 minimalDeposit;
}
```

| Name                             | Description                                                                 |
| -------------------------------- | --------------------------------------------------------------------------- |
| `name`                           | The name of the builder project.                                            |
| `admin`                          | The address of the pool administrator (builder).                            |
| `poolStart`                      | Timestamp when the pool becomes active.                                     |
| `withdrawLockPeriodAfterDeposit` | Time period after deposit during which withdrawal is locked. Seconds.       |
| `claimLockEnd`                   | Timestamp after which rewards can be claimed by the builder admin. Seconds. |
| `minimalDeposit`                 | Minimum amount a user must deposit to participate. Wei.                     |

### buildersPoolData

Mapping of pool ID to the current dynamic pool state.

```solidity
mapping(bytes32 => BuilderPoolData) public buildersPoolData;

struct BuilderPoolData {
  uint128 lastDeposit;
  uint256 deposited;
  uint256 virtualDeposited;
  uint256 rate;
  uint256 pendingRewards;
}
```

| Name               | Description                                            |
| ------------------ | ------------------------------------------------------ |
| `lastDeposit`      | Timestamp in seconds of the last deposit into the pool |
| `deposited`        | Total amount deposited without multiplier. Wei.        |
| `virtualDeposited` | Total amount deposited with multipliers applied. Wei.  |
| `rate`             | Current reward rate for the pool                       |
| `pendingRewards`   | Accumulated unclaimed rewards for the pool. Wei.       |

### usersData

Mapping of user address and pool ID to their user-specific data.

```solidity
mapping(address => mapping(bytes32 => UserData)) public usersData;

struct UserData {
  uint128 lastDeposit;
  uint128 claimLockStart;
  uint256 deposited;
  uint256 virtualDeposited;
}
```

| Name               | Description                                                |
| ------------------ | ---------------------------------------------------------- |
| `lastDeposit`      | Timestamp in seconds of the user's last deposit.           |
| `claimLockStart`   | Timestamp when the user activated the reward lock. Seconds |
| `deposited`        | Total tokens the user deposited (raw amount). Wei          |
| `virtualDeposited` | Tokens deposited by user with multiplier applied. Wei.     |

### Fee oprations

The lables for fee operations, uses for fee receiving in the `FeeConfig` contract.

```solidity
bytes32 private constant FEE_WITHDRAW_OPERATION = "withdraw";
bytes32 private constant FEE_CLAIM_OPERATION = "claim";
```

## Write functions for the contract owner

### Builders\_init

Initializes the contract with essential parameters and configuration contracts. This function must be called once after deployment.

```solidity
function Builders_init(
    address depositToken_,
    address feeConfig_,
    address buildersTreasury_,
    uint128 editPoolDeadline_,
    uint256 minimalWithdrawLockPeriod_
) external initializer
```

| Name                         | Description                                                                          |
| ---------------------------- | ------------------------------------------------------------------------------------ |
| `depositToken_`              | Address of the token that users will deposit in builder pools. MOR token.            |
| `feeConfig_`                 | Address of the `FeeConfig` contract used to calculate protocol fees.                 |
| `buildersTreasury_`          | Address of the `BuildersTreasury` contract used to store and distribute rewards.     |
| `editPoolDeadline_`          | Time (in seconds) before pool start when editing is still allowed.                   |
| `minimalWithdrawLockPeriod_` | Minimum lock duration after deposit in seconds before users can withdraw staked MOR. |

### setFeeConfig

Sets the address of the `FeeConfig` contract.

```solidity
function setFeeConfig(address feeConfig_) public onlyOwner
```

| Name         | Description                                      |
| ------------ | ------------------------------------------------ |
| `feeConfig_` | Address of a contract that implements IFeeConfig |

### setBuildersTreasury

Sets the address of the `BuildersTreasury` contract.

```solidity
function setBuildersTreasury(address buildersTreasury_) public onlyOwner
```

| Name                | Description                                             |
| ------------------- | ------------------------------------------------------- |
| `buildersTreasury_` | Address of a contract that implements IBuildersTreasury |

### setEditPoolDeadline

Sets the edit deadline (in seconds) for a builder pools relative to its start time.

```solidity
function setEditPoolDeadline(uint128 editPoolDeadline_) public onlyOwner
```

| Name                | Description                                         |
| ------------------- | --------------------------------------------------- |
| `editPoolDeadline_` | Number of seconds before start when edit is allowed |

### setMinimalWithdrawLockPeriod

Sets the minimum lock period that must pass before a user can withdraw MOR after depositing.

```solidity
function setMinimalWithdrawLockPeriod(
  uint256 minimalWithdrawLockPeriod_
) public onlyOwner
```

| Name                         | Description                                                      |
| ---------------------------- | ---------------------------------------------------------------- |
| `minimalWithdrawLockPeriod_` | Minimum lock period (in seconds) after deposit before withdrawal |

## Write functions

### createBuilderPool<br>

Creates a new builder pool with specific parameters.

```solidity
function createBuilderPool(BuilderPool calldata builderPool_) public
```

| Name           | Description                                                          |
| -------------- | -------------------------------------------------------------------- |
| `builderPool_` | Struct with the new pool’s parameters: name, admin, start time, etc. |

### editBuilderPool

Edits an existing builder pool’s configuration before its edit deadline expires. The caller should be the builder pool admin.&#x20;

```solidity
function editBuilderPool(BuilderPool calldata builderPool_) external
```

| Name           | Description                                                                 |
| -------------- | --------------------------------------------------------------------------- |
| `builderPool_` | Updated struct data of the builder pool to overwrite existing configuration |

### deposit

Allows a user to deposit MOR into a builder pool.

```solidity
function deposit(bytes32 builderPoolId_, uint256 amount_) external
```

| Name             | Description                             |
| ---------------- | --------------------------------------- |
| `builderPoolId_` | ID of the builder pool to deposit into. |
| `amount_`        | Amount of MOR to deposit. Wei.          |

### withdraw

Withdraws tokens from a specific builder pool.

```solidity
function withdraw(bytes32 builderPoolId_, uint256 amount_) external
```

| Name             | Description                                                                     |
| ---------------- | ------------------------------------------------------------------------------- |
| `builderPoolId_` | Identifier of the builder pool from which tokens will be withdrawn              |
| `amount_`        | Amount of tokens to withdraw; will be limited by user balance if too high. Wei. |

### claim

Allows the builder pool admin to claim the pool’s accumulated MOR rewards.

```solidity
function claim(bytes32 builderPoolId_, address receiver_) external
```

| Name             | Description                                                        |
| ---------------- | ------------------------------------------------------------------ |
| `builderPoolId_` | Identifier of the builder pool from which tokens will be withdrawn |
| `receiver_`      | Address to receive the claimed MOR rewards                         |

## Read functions

### getNotDistributedRewards<br>

Returns the total unclaimed MOR rewards stored in the BuildersTreasury.

```solidity
function getNotDistributedRewards() public view returns (uint256)
```

### getCurrentUserMultiplier

Returns the reward multiplier based on the user’s lock period for a pool.

```solidity
function getCurrentUserMultiplier(
  bytes32 builderPoolId_,
  address user_
) public view returns (uint256)
```

| Name             | Description                                                        |
| ---------------- | ------------------------------------------------------------------ |
| `builderPoolId_` | Identifier of the builder pool from which tokens will be withdrawn |
| `user_`          | User address whose multiplier is being calculated                  |

### getCurrentBuilderReward

Returns the current calculated reward for a builder pool.

```solidity
function getCurrentBuilderReward(
  bytes32 builderPoolId_
) external view returns (uint256)
```

| Name             | Description                                                        |
| ---------------- | ------------------------------------------------------------------ |
| `builderPoolId_` | Identifier of the builder pool from which tokens will be withdrawn |

### getLockPeriodMultiplier

Returns the multiplier for rewards based on a lock period.

```solidity
function getLockPeriodMultiplier(
  uint128 lockStart_,
  uint128 lockEnd_
) public pure returns (uint256)
```

| Name         | Description                                 |
| ------------ | ------------------------------------------- |
| `lockStart_` | Timestamp in seconds when the lock started. |
| `lockEnd_`   | Timestamp in seconds when the lock ends.    |

### getPoolId

Computes the unique ID of a builder pool based on its name.

```solidity
function getPoolId(string memory builderPoolName_) public pure returns (bytes32)
```

| Name               | Description              |
| ------------------ | ------------------------ |
| `builderPoolName_` | Name of the builder pool |

### supportsInterface

Used for interface detection (ERC165). Returns true if the contract supports a specific `interfaceId_`. Supports `IBuilders`, `IERC165`.

```solidity
function supportsInterface(bytes4 interfaceId_) external pure returns (bool)
```
