# EpochBasedTokenClaim

*Contract to claim rewards based on epoch and merkle tree (used for Arbitrum STIP trading incentives)*

## rewardToken

```solidity
contract IERC20 rewardToken
```

## manager

```solidity
address manager
```

## epochRoots

```solidity
mapping(uint256 => bytes32) epochRoots
```

## epochCids

```solidity
mapping(uint256 => string) epochCids
```

## epochTraderClaimed

```solidity
mapping(uint256 => mapping(address => bool)) epochTraderClaimed
```

## ManagerUpdated

```solidity
event ManagerUpdated(address newManager)
```

## TokensWithdrawn

```solidity
event TokensWithdrawn()
```

## EpochMerkleRootSet

```solidity
event EpochMerkleRootSet(uint256 epoch, bytes32 root, uint256 totalRewards, string cid)
```

## TokensClaimed

```solidity
event TokensClaimed(uint256 epoch, address user, uint256 rewardAmount)
```

## TokensClaimed

```solidity
event TokensClaimed(uint256[] epochs, address user, uint256 rewardAmount)
```

## AddressZero

```solidity
error AddressZero()
```

## NotManager

```solidity
error NotManager()
```

## RootAlreadySet

```solidity
error RootAlreadySet()
```

## RootZero

```solidity
error RootZero()
```

## RewardsZero

```solidity
error RewardsZero()
```

## CidZero

```solidity
error CidZero()
```

## InvalidEpochs

```solidity
error InvalidEpochs()
```

## ArrayLengthMismatch

```solidity
error ArrayLengthMismatch()
```

## EpochNotSet

```solidity
error EpochNotSet()
```

## NotEnoughBalance

```solidity
error NotEnoughBalance()
```

## AlreadyClaimed

```solidity
error AlreadyClaimed()
```

## InvalidProof

```solidity
error InvalidProof()
```

## constructor

```solidity
constructor(contract IERC20 _rewardToken, address _owner, address _manager) public
```

## onlyManager

```solidity
modifier onlyManager()
```

## setManager

```solidity
function setManager(address _manager) external
```

*Sets manager address to `_manager`. Only callable by `owner()` (multisig)*

## setRoot

```solidity
function setRoot(uint256 _epoch, bytes32 _root, uint256 _totalRewards, string _cid) external
```

\_Sets Merkle Tree `_root` and '*cid' for an `_epoch` and transfers `_totalRewards` from the `owner()` (multisig) to this contract. Only callable by `manager`.*

## withdrawTokens

```solidity
function withdrawTokens() external
```

*Prevents stuck tokens in case of misconfiguration; Only `owner()` (multisig) can claim the tokens back*

## claimRewards

```solidity
function claimRewards(uint256 _epoch, uint256 _rewardAmount, bytes32[] _proof) external
```

*Claims trader rewards for a specific `_epoch`*

## claimMultipleRewards

```solidity
function claimMultipleRewards(uint256[] _epochs, uint256[] _rewardAmounts, bytes32[][] _proofs) external
```

*Claims trader rewards for multiple `_epochs`*

## \_hashLeaf

```solidity
function _hashLeaf(address _user, uint256 _amount) internal pure returns (bytes32)
```

*Returns a hashed leaf of `_user` + `_amount`*

## \_validateClaim

```solidity
function _validateClaim(uint256 _epoch, address _trader, uint256 _rewardAmount, bytes32[] _proof) internal view
```

\_Validates that:

1. The `_epoch` merkle tree root is set
2. There are enough token rewards in the contract
3. Rewards for leaf are unclaimed
4. The `leaf` and `_proof` validate against `epochRoot`\_


---

# 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.gains.trade/developer/technical-reference/contracts/misc/epochbasedtokenclaim.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.
