# GaugeV1

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

**GaugeV1** is an upgradeable contract used to manage reward distributions for a particular pool or strategy in the EYWA ecosystem. The contract primarily integrates with the **Escrow Vote Manager** (`s_escrowVoteManager`) to authorize reward notifications and uses a **Distribution Creator** (`DISTRIBUTION_CREATOR`) for executing reward distribution campaigns.

Key features include:

* **Upgradeable (UUPS Pattern):** The contract can be updated while preserving state.
* **Owner-Based Access Control:** Critical functions (like upgrading the contract and updating campaign parameters) are restricted to the owner.
* **Reward Notification:** The `notifyRewardAmount` function can only be invoked by the authorized escrow vote manager, ensuring a controlled flow of rewards.
* **Campaign Parameters:** The gauge uses dynamic campaign parameters (`s_campaignParameters`) to manage reward distribution schedules and amounts, which can be updated by the owner if needed.

By implementing `IGaugeV1`, **GaugeV1** provides a standardized interface for initializing, updating campaign parameters, and receiving new reward amounts within the EYWA ecosystem.

***

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

* **UUPSUpgradeable (OpenZeppelin):**\
  Enables upgradeability under the UUPS (Universal Upgradeable Proxy Standard) pattern, restricted to the contract owner.
* **OwnableUpgradeable (OpenZeppelin):**\
  Provides ownership logic, limiting certain state changes (e.g., upgrading, updating parameters) to the contract owner.
* **IGaugeV1:**\
  Interface defining core functions (e.g., `initialize`, `updateCampaignParameters`, `notifyRewardAmount`) and events (`RewardNotified`, `CampaignParametersUpdated`) for the gauge contract.

**Additional External References:**

* **SafeERC20, IERC20 (OpenZeppelin):**\
  Library and interface for safe ERC20 token transfers.
* **IEscrowVoteManagerV1:**\
  Tracks and authorizes reward notifications, ensuring that only the designated manager can call `notifyRewardAmount`.
* **IDistributionCreator:**\
  Contract on Arbitrum that actually creates or schedules distribution campaigns (Merkl distributions).
  * The contract uses `DISTRIBUTION_CREATOR` with a known address (`0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd`) on Arbitrum.

***

### Constants <a href="#constants-3" id="constants-3"></a>

```solidity
uint256 public constant EPOCH_DURATION = 1 weeks;
IDistributionCreator public constant DISTRIBUTION_CREATOR = IDistributionCreator(0x8BB4C975Ff3c250e0ceEA271728547f3802B36Fd);

```

* **EPOCH\_DURATION:** The duration of an epoch (1 week). Used to align reward distribution campaigns with discrete time intervals.
* **DISTRIBUTION\_CREATOR:** The address of the Merkl distribution contract on Arbitrum. This contract is responsible for orchestrating reward distributions once campaigns are created.

***

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

* **`s_escrowVoteManager (address)`**\
  Address of the escrow vote manager contract, which is authorized to call `notifyRewardAmount`.
* **`s_eywa (address)`**\
  The EYWA token address used for rewards distribution.
* **`s_campaignParameters (IDistributionCreator.CampaignParameters)`**\
  Holds the current campaign parameters for distributing rewards. These parameters include data like amount, duration, start timestamp, and distribution logic, which can be updated by the owner.

***

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

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

```

* **Description:**\
  Disables contract initializers to prevent multiple initializations. Enforces that `initialize` can be called only once in a UUPS upgradeable context.

***

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

#### `initialize(...)` <a href="#initialize-3" id="initialize-3"></a>

```solidity
function initialize(
    address owner_,
    address escrowVoteManager_,
    address eywa_,
    IDistributionCreator.CampaignParameters calldata campaignParameters_
) 
    external
    initializer

```

* **Description:**
  * Initializes the gauge contract by setting the owner, escrow vote manager, EYWA token address, and the initial campaign parameters for rewards.
  * Can only be called once, marked by the `initializer` modifier from OpenZeppelin upgradeable patterns.
* **Parameters:**
  * `owner_`: The address designated as the contract owner.
  * `escrowVoteManager_`: The address of the escrow vote manager, authorized to call `notifyRewardAmount`.
  * `eywa_`: The address of the EYWA token used for distributing rewards.
  * `campaignParameters_`: Initial set of campaign parameters (amount, duration, schedule, etc.) used in distribution campaigns.
* **Effects:**
  * Calls `__UUPSUpgradeable_init()` and `__Ownable_init(owner_)` to set up UUPS upgrade and ownership.
  * Assigns `s_escrowVoteManager` and `s_eywa` references.
  * Stores `s_campaignParameters` from input.

***

#### `updateCampaignParameters(...)` <a href="#updatecampaignparameters" id="updatecampaignparameters"></a>

```solidity
function updateCampaignParameters(
    IDistributionCreator.CampaignParameters calldata newCampaignParameters_
) 
    external 
    onlyOwner

```

* **Description:**
  * Allows the contract owner to update the gauge’s campaign parameters.
  * The newly provided parameters (`newCampaignParameters_`) overwrite the existing ones in `s_campaignParameters`.
* **Parameters:**
  * `newCampaignParameters_`: The updated distribution parameters (e.g., new schedule or amounts) for this gauge.
* **Events:**
  * Emits `CampaignParametersUpdated(address(this), oldCampaignParameters, newCampaignParameters_)` to log the changes.

***

#### `notifyRewardAmount(uint256 amount_)` <a href="#notifyrewardamountuint256-amount" id="notifyrewardamountuint256-amount"></a>

```solidity
function notifyRewardAmount(uint256 amount_) external

```

* **Description:**
  * Notifies the gauge of a newly available `amount_` of EYWA tokens to be distributed as rewards.
  * Can only be called by `s_escrowVoteManager`.
  * The function transfers `amount_` from the caller to this gauge, checks if the resulting balance is sufficient to meet the minimum distribution threshold, and if so, triggers the distribution campaign via `DISTRIBUTION_CREATOR.createCampaign(...)`.
* **Parameters:**
  * `amount_`: The amount of EYWA tokens to be added for distribution.
* **Checks & Logic:**
  1. Verifies `msg.sender == s_escrowVoteManager`, otherwise reverts with `UnauthorizedCaller()`.
  2. Transfers `amount_` of EYWA from the caller to the contract.
  3. If the new balance (multiplied by 1 hour / `EPOCH_DURATION`) meets the `rewardTokenMinAmounts(...)` requirement of `DISTRIBUTION_CREATOR`, the contract approves `DISTRIBUTION_CREATOR` to spend its entire balance and initiates a campaign:
     * Sets `m_campaignParameters.amount` to the new gauge balance.
     * Sets `startTimestamp = uint32(block.timestamp)`.
     * Sets `duration = uint32(EPOCH_DURATION)` (one week).
     * Calls `createCampaign(...)` on `DISTRIBUTION_CREATOR`.
  4. Emits `RewardNotified(amount_)`.
* **Events:**
  * `RewardNotified(amount_)` logs the newly notified reward amount.

***

### Internal and Private Functions <a href="#internal-and-private-functions-4" id="internal-and-private-functions-4"></a>

#### `_authorizeUpgrade(address)` <a href="#authorizeupgradeaddress-4" id="authorizeupgradeaddress-4"></a>

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

```

* **Description:**
  * Ensures that only the contract owner can authorize upgrades.
  * Enforced by the `UUPSUpgradeable` pattern.

***

### Events <a href="#events-4" id="events-4"></a>

1. **`RewardNotified(uint256 indexed amount)`**
   * Emitted when new rewards are notified to the gauge, indicating the total tokens added.
2. **`CampaignParametersUpdated( address indexed gauge, IDistributionCreator.CampaignParameters oldCampaignParameters, IDistributionCreator.CampaignParameters newCampaignParameters )`**
   * Logged when the owner updates the gauge’s distribution campaign parameters.

***

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

* **`UnauthorizedCaller()`**
  * Thrown if a function restricted to `s_escrowVoteManager` or `onlyOwner` is called by an unauthorized address.

***

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

**GaugeV1** is an upgradeable contract that manages reward distributions for a specific pool or strategy within the EYWA ecosystem. By connecting to an **Escrow Vote Manager**, it ensures only authorized parties can add new rewards (`notifyRewardAmount`). Through **DistributionCreator** on Arbitrum, it transforms these rewards into time-bound distribution campaigns. The contract owner can update campaign parameters if needed, while all major functionalities (initialization, upgrade, parameter updates) remain protected by ownership and authorized checks.
