# GNSStaking

*Staking contract for GNS token to earn in multiple reward tokens from fees generated on gTrade.*

## gns

```solidity
contract IERC20 gns
```

## dai

```solidity
contract IERC20 dai
```

## accDaiPerToken

```solidity
uint128 accDaiPerToken
```

## gnsBalance

```solidity
uint128 gnsBalance
```

## stakers

```solidity
mapping(address => struct IGNSStaking.Staker) stakers
```

## unlockManagers

```solidity
mapping(address => bool) unlockManagers
```

## rewardTokens

```solidity
address[] rewardTokens
```

## rewardTokenState

```solidity
mapping(address => struct IGNSStaking.RewardState) rewardTokenState
```

## userTokenRewards

```solidity
mapping(address => mapping(address => struct IGNSStaking.RewardInfo)) userTokenRewards
```

## userTokenUnlockRewards

```solidity
mapping(address => mapping(address => mapping(uint256 => struct IGNSStaking.RewardInfo))) userTokenUnlockRewards
```

## stakerInfos

```solidity
mapping(address => struct IGNSStaking.StakerInfo) stakerInfos
```

## constructor

```solidity
constructor() public
```

## initialize

```solidity
function initialize(address _owner, contract IERC20 _gns, contract IERC20 _dai) external
```

*Sets `owner` and initializes `dai` and `gns` state variables*

## initializeV2

```solidity
function initializeV2() external
```

*Add `dai` as a reward token (old stakers.debtDai, unlockSchedules.debtDai and accDaiPerToken are deprecacted now) Necessary to call right after contract is updated because otherwise distributeRewardDai() reverts.*

## onlyAuthorizedUnlockManager

```solidity
modifier onlyAuthorizedUnlockManager(address _staker, bool _revocable)
```

*Modifier used for vest creation access control. Users can create non-revocable vests for themselves only, `owner` and `unlockManagers` can create both types for anyone.*

## onlyRewardToken

```solidity
modifier onlyRewardToken(address _token)
```

*Modifier to reject any `_token` not configured as a reward token*

## notInCooldown

```solidity
modifier notInCooldown()
```

*Modifier to ensure operation is not performed before cooldown period has expired*

## setUnlockManager

```solidity
function setUnlockManager(address _manager, bool _authorized) external
```

\_Sets whether `_manager` is `_authorized` to create vests for other users.

Emits {UnlockManagerUpdated}\_

## addRewardToken

```solidity
function addRewardToken(address _token) external
```

\_Forwards call to {*addRewardToken}. Only callable by `owner`.*

## setDelegatee

```solidity
function setDelegatee(address _token, address _delegatee) external
```

*Attempts to set the delegatee of `_token` to `_delegatee`. `_token` must be a valid reward token.*

## unlockedGns

```solidity
function unlockedGns(struct IGNSStaking.UnlockSchedule _schedule, uint48 _timestamp) public pure returns (uint128)
```

*Returns the unlocked GNS tokens amount of `_schedule` at `_timestamp`. Includes already claimed GNS tokens.*

## releasableGns

```solidity
function releasableGns(struct IGNSStaking.UnlockSchedule _schedule, uint48 _timestamp) public pure returns (uint128)
```

*Returns the releasable GNS tokens amount (1e18 precision) of `_schedule` at `_timestamp`. Doesn't include already claimed GNS tokens.*

## owner

```solidity
function owner() public view returns (address)
```

*Returns the owner of the contract.*

## isRewardToken

```solidity
function isRewardToken(address _token) public view returns (bool)
```

*Returns whether `_token` is a listed reward token.*

## distributeReward

```solidity
function distributeReward(address _token, uint256 _amountToken) external
```

\_Transfers `_amountToken` of `_token` (valid reward token) from caller to this contract and updates `accRewardPerGns`.

Note: `accRewardPerGns` is normalized to 1e18 for all reward tokens (even those with less than 18 decimals)

Emits {RewardDistributed}\_

## harvestToken

```solidity
function harvestToken(address _token) public returns (uint128)
```

*Harvests the caller's regular pending `_token` rewards. `_token` must be a valid reward token.*

## harvestTokenFromUnlock

```solidity
function harvestTokenFromUnlock(address _token, uint256[] _ids) public returns (uint128)
```

*Harvests the caller's pending `_token` rewards for vests `_ids`. `_token` must be a valid reward token.*

## harvestTokenAll

```solidity
function harvestTokenAll(address _token, uint256[] _ids) public returns (uint128)
```

*Harvests the caller's regular pending `_token` rewards and pending rewards for vests `_ids`.*

## harvestTokens

```solidity
function harvestTokens() public
```

*Harvests the caller's regular pending rewards for all supported reward tokens.*

## harvestTokensFromUnlock

```solidity
function harvestTokensFromUnlock(uint256[] _ids) public
```

*Harvests the caller's pending rewards of vests `_ids` for all supported reward tokens.*

## harvestTokensAll

```solidity
function harvestTokensAll(uint256[] _ids) public
```

*Harvests the caller's regular pending rewards and pending rewards of vests `_ids` for all supported reward tokens.*

## compoundGnsRewards

```solidity
function compoundGnsRewards(uint256[] _ids) external
```

*Harvests the caller's GNS pending rewards and then stakes them*

## harvestDai

```solidity
function harvestDai() public
```

*Harvests caller's old regular dai rewards.*

## harvestDaiFromUnlock

```solidity
function harvestDaiFromUnlock(uint256[] _ids) public
```

*Harvests caller's old dai rewards for vests `_ids`.*

## harvestDaiAll

```solidity
function harvestDaiAll(uint256[] _ids) public
```

*Harvests caller's old regular dai rewards and old dai rewards of vests `_ids`.*

## harvestAll

```solidity
function harvestAll(uint256[] _ids) external
```

*Harvests the caller's regular pending rewards and pending rewards for vests `_ids` for all supported reward tokens (+ old DAI rewards).*

## stakeGns

```solidity
function stakeGns(uint128 _amountGns) public
```

\_Stakes non-vested `_amountGns` from caller.

Emits {GnsStaked}\_

## unstakeGns

```solidity
function unstakeGns(uint128 _amountGns) external
```

\_Unstakes non-vested `_amountGns` from caller.

Emits {GnsUnstaked}\_

## claimUnlockedGns

```solidity
function claimUnlockedGns(uint256[] _ids) external
```

*Claims caller's unlocked GNS from vests `_ids`.*

## createUnlockSchedule

```solidity
function createUnlockSchedule(struct IGNSStaking.UnlockScheduleInput _schedule, address _staker) external
```

\_Creates vest for `_staker` given `_schedule` input parameters. Restricted with onlyAuthorizedUnlockManager access control.

Emits {UnlockScheduled}\_

## revokeUnlockSchedule

```solidity
function revokeUnlockSchedule(address _staker, uint256 _id) external
```

\_Revokes vest `_id` for `_staker`. Sends the unlocked GNS to `_staker` and sends the remaining locked GNS to `owner`. Only callable by `owner`.

Emits {UnlockScheduleRevoked}\_

## pendingRewardToken

```solidity
function pendingRewardToken(address _staker, address _token) public view returns (uint128)
```

*Returns the pending `_token` rewards (precision depends on token) for `_staker`.*

## pendingRewardTokens

```solidity
function pendingRewardTokens(address _staker) external view returns (uint128[] pendingTokens)
```

*Returns an array of `_staker`'s pending rewards (precision depends on token) for all supported tokens.*

## pendingRewardTokensFromUnlocks

```solidity
function pendingRewardTokensFromUnlocks(address _staker, uint256[] _ids) external view returns (uint128[] pendingTokens)
```

*Returns an array of `_staker`'s pending rewards (precision depends on token) from vests `_ids` for all supported tokens.*

## pendingRewardDai

```solidity
function pendingRewardDai(address _staker) external view returns (uint128)
```

*Returns `_staker`'s pending old dai rewards (1e18 precision).*

## pendingRewardDaiFromUnlocks

```solidity
function pendingRewardDaiFromUnlocks(address _staker, uint256[] _ids) external view returns (uint128 pending)
```

*Returns `_staker`'s pending old dai rewards (1e18 precision) from vests `_ids`.*

## totalGnsStaked

```solidity
function totalGnsStaked(address _staker) external view returns (uint128)
```

*Returns `_staker's` total non-vested and vested GNS staked (1e18 precision)*

## getUnlockSchedules

```solidity
function getUnlockSchedules(address _staker) external view returns (struct IGNSStaking.UnlockSchedule[])
```

*Returns all `_staker's` vests.*

## getUnlockSchedules

```solidity
function getUnlockSchedules(address _staker, uint256 _index) external view returns (struct IGNSStaking.UnlockSchedule)
```

*Returns `_staker's` vest at `_index'`*

## getRewardTokens

```solidity
function getRewardTokens() external view returns (address[])
```

*Returns the address of all supported reward tokens*
