# ZivoeRewardsVesting.sol

## Introduction

This contract facilitates staking and yield distribution, as well as vesting tokens.

This contract has the following responsibilities:

* Allows creation of vesting schedules (and revocation) for "vestingToken".&#x20;
* Allows unstaking of vested tokens.
* Allows claiming yield distributed / "deposited" to this contract.
* Allows multiple assets to be added as "rewardToken" for distributions (except for "vestingToken").
* Vests rewardTokens linearly overtime to stakers.

{% embed url="<https://www.figma.com/board/qjuQ0uGQl9QD7KeBwyf73d/Zivoe-Visualization?node-id=207-546&t=zWYnaX4jJkLHscwT-4>" %}

#### State Variables

<table><thead><tr><th width="212.33333333333331">Type</th><th width="150">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>GBL</td><td>The ZivoeGlobals contract.</td></tr><tr><td>address</td><td>vestingToken</td><td>The token vesting, in this case Zivoe ($ZVE).</td></tr><tr><td>address[]</td><td>rewardTokens</td><td>Array of ERC20 tokens distributed as rewards (if present).</td></tr><tr><td>uint256</td><td>vestingTokenAllocated</td><td>The amount of vestingToken currently allocated.</td></tr><tr><td>uint256</td><td>_totalSupply</td><td>Total supply of (non-transferrable) LP tokens for reards contract.</td></tr><tr><td>mapping(address => <a data-mention href="#reward">#reward</a>)</td><td>rewardData</td><td>Contains rewards information for each rewardToken.</td></tr><tr><td>mapping(address => bool)</td><td>vestingScheduleSet</td><td>Tracks if a wallet has been assigned a schedule.</td></tr><tr><td>mapping(address => <a data-mention href="#vestingschedule">#vestingschedule</a>)</td><td>vestingScheduleOf</td><td>Tracks the vesting schedule of accounts.</td></tr><tr><td>mapping(address => mapping(address => (uint256))</td><td>accountRewardPerTokenPaid</td><td>The order is account -> rewardAsset -> amount.</td></tr><tr><td>mapping(address => mapping(address => (uint256))</td><td>rewards</td><td>The order is account -> rewardAsset -> amount.</td></tr><tr><td>mapping(address => uint256)</td><td>_balances</td><td>Contains LP token balance of each account (is 1:1 ratio with amount deposited).</td></tr><tr><td>IERC20</td><td>stakingToken</td><td>IERC20 wrapper for the stakingToken (deposited to receive LP tokens).</td></tr></tbody></table>

#### `Reward`

This struct stores information for reward tokens.

<table><thead><tr><th width="137.33333333333331">Type</th><th width="254">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>rewardsDuration</td><td>How long rewards take to vest, e.g. 30 days.</td></tr><tr><td>uint256</td><td>periodFinish</td><td>When current rewards will finish vesting.</td></tr><tr><td>uint256</td><td>rewardRate</td><td>Rewards emitted per second.</td></tr><tr><td>uint256</td><td>lastUpdateTime</td><td>Last time this data struct was updated.</td></tr><tr><td>uint256</td><td>rewardPerTokenStored</td><td>Last snapshot of rewardPerToken taken.</td></tr></tbody></table>

#### `VestingSchedule`

This struct stores information for vesting schedules.

<table><thead><tr><th width="144.33333333333331">Type</th><th width="205">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>start</td><td>The block.timestamp at which tokens will start vesting.</td></tr><tr><td>uint256</td><td>cliff</td><td>The block.timestamp at which tokens are first claimable.</td></tr><tr><td>uint256</td><td>end</td><td>The block.timestamp at which tokens will stop vesting (finished).</td></tr><tr><td>uint256</td><td>totalVesting</td><td>The total amount to vest.</td></tr><tr><td>uint256</td><td>totalWithdrawn</td><td>The total amount withdrawn so far.</td></tr><tr><td>uint256</td><td>vestingPerSecond</td><td>The amount of vestingToken that vests per second.</td></tr><tr><td>bool</td><td>revokable</td><td>Whether or not this vesting schedule can be revoked.</td></tr></tbody></table>

## **Sections**

[#read-functions](#read-functions "mention")

* [#balanceof](#balanceof "mention") - Returns the amount of tokens owned by "account", received when depositing via `stake()`.
* [#getrewardforduration](#getrewardforduration "mention") - Returns the total amount of rewards being distributed to everyone for current rewardsDuration.
* [#totalsupply](#totalsupply "mention") - Returns the amount of tokens in existence; these are minted and burned when depositing or withdrawing.
* [#viewaccountrewardpertokenpaid](#viewaccountrewardpertokenpaid "mention") - Returns the last snapshot of rewardPerTokenStored taken for a reward asset.
* [#viewrewards](#viewrewards "mention") - Returns the rewards earned of a specific rewardToken for an address.
* [#viewschedule](#viewschedule "mention") - Provides information for a vesting schedule. See [#vestingschedule](#vestingschedule "mention")
* [#amountwithdrawable](#amountwithdrawable "mention") - Returns the amount of $ZVE tokens a user can withdraw.
* [#earned](#earned "mention") - Provides information on the rewards available for claim.
* [#lasttimerewardapplicable](#lasttimerewardapplicable "mention") - Helper function for assessing distribution timelines.
* [#rewardpertoken](#rewardpertoken "mention") - Cumulative amount of rewards distributed per LP token.

[#write-functions](#write-functions "mention")

* [#addreward](#addreward "mention") - Adds a new asset as a reward to this contract.
* [#depositreward](#depositreward "mention") - Deposits a reward to this contract for distribution.
* [#fullwithdraw](#fullwithdraw "mention") - Simultaneously calls `withdraw()` and `getRewards()` for convenience.
* [#createvestingschedule](#createvestingschedule "mention") - Sets the vestingSchedule for an account.
* [#revokevestingschedule](#revokevestingschedule "mention") - Ends vesting schedule for a given account (if revokable).
* [#getrewards](#getrewards "mention") - Claim rewards for all possible \_rewardTokens.
* [#withdraw](#withdraw "mention") - Withdraws the specified amount of stakingToken from this contract.

[#events](#events "mention")

* [#rewardadded](#rewardadded "mention")
* [#rewarddeposited](#rewarddeposited "mention")
* [#rewarddistributed](#rewarddistributed "mention")
* [#staked](#staked "mention")
* [#vestingschedulecreated](#vestingschedulecreated "mention")
* [#vestingschedulerevoked](#vestingschedulerevoked "mention")
* [#withdrawn](#withdrawn "mention")

## Read Functions

#### `balanceOf()`

Returns the amount of tokens owned by "account", received when depositing via `stake()`.

```solidity
function balanceOf(
    address account
) external view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="120">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to view information of.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The amount of tokens owned by "account".</td></tr></tbody></table>

#### `getRewardForDuration()`

Returns the total amount of rewards being distributed to everyone for current rewardsDuration.

```solidity
function getRewardForDuration(
    address _rewardsToken
) external view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="151">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>_rewardsToken</td><td>The asset that's being distributed.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The amount of rewards being distributed.</td></tr></tbody></table>

#### `totalSupply()`

Returns the amount of tokens in existence; these are minted and burned when depositing or withdrawing.

```solidity
function totalSupply() external view returns (uint256 amount);
```

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The amount of tokens in existence.</td></tr></tbody></table>

#### `viewAccountRewardPerTokenPaid()`

Returns the last snapshot of rewardPerTokenStored taken for a reward asset.

```solidity
function viewAccountRewardPerTokenPaid(
    address account, 
    address rewardAsset
) external view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="157">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to view information of.</td></tr><tr><td>address</td><td>rewardAsset</td><td>The reward token for which we want to return the rewardPerTokenstored.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The latest up-to-date value of rewardPerTokenStored.</td></tr></tbody></table>

#### `viewRewards()`

Returns the rewards earned of a specific rewardToken for an address.

```solidity
function viewRewards(
    address account,
    address rewardAsset
) external view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="144">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to view information of.</td></tr><tr><td>address</td><td>rewardAsset</td><td>The asset earned as a reward.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The amount of rewards earned.</td></tr></tbody></table>

#### `viewSchedule()`

Provides information for a vesting schedule. See [#vestingschedule](#vestingschedule "mention")

```solidity
function viewSchedule(address account) external view returns (
    uint256 start, 
    uint256 cliff, 
    uint256 end, 
    uint256 totalVesting, 
    uint256 totalWithdrawn, 
    uint256 vestingPerSecond, 
    bool revokable
);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="144">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to view information of.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="178">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>start</td><td>The block.timestamp at which tokens will start vesting.</td></tr><tr><td>uint256</td><td>cliff</td><td>The block.timestamp at which tokens are first claimable.</td></tr><tr><td>uint256</td><td>end</td><td>The block.timestamp at which tokens will stop vesting (finished).</td></tr><tr><td>uint256</td><td>totalVesting</td><td>The total amount to vest.</td></tr><tr><td>uint256</td><td>totalWithdrawn</td><td>The total amount withdrawn so far.</td></tr><tr><td>uint256</td><td>vestingPerSecond</td><td>The amount of vestingToken that vests per second.</td></tr><tr><td>bool</td><td>revokable</td><td>Whether or not this vesting schedule can be revoked.</td></tr></tbody></table>

#### `amountWithdrawable()`

Returns the amount of $ZVE tokens a user can withdraw.

```solidity
function amountWithdrawable(
    address account
) public view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="144">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to be withdrawn from.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>Withdrawable amount of $ZVE tokens.</td></tr></tbody></table>

#### `earned()`

Provides information on the rewards available for claim.

```solidity
function earned(
    address account, 
    address _rewardsToken
) public view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="156">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account to view information of.</td></tr><tr><td>address</td><td>_rewardsToken</td><td>The asset that's being distributed.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The amount of rewards earned.</td></tr></tbody></table>

#### `lastTimeRewardApplicable()`

Helper function for assessing distribution timelines.

```solidity
function lastTimeRewardApplicable(
    address _rewardsToken
) public view returns (uint256 timestamp); 
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="155">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>_rewardsToken</td><td>The asset that's being distributed.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>timestamp</td><td>The most recent time (in UNIX format) at which rewards are available for distribution.</td></tr></tbody></table>

#### `rewardPerToken()`

Cumulative amount of rewards distributed per LP token.

```solidity
function rewardPerToken(
    address _rewardsToken
) public view returns (uint256 amount);
```

<table><thead><tr><th width="143.33333333333331">Type</th><th width="168">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>_rewardsToken</td><td>The asset that's being distributed.</td></tr></tbody></table>

*Returns*

<table><thead><tr><th width="148.33333333333331">Type</th><th width="121">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The cumulative amount of rewards distributed per LP token.</td></tr></tbody></table>

## Write Functions

#### `addReward()`

Adds a new asset as a reward to this contract.

```solidity
function addReward(
    address _rewardsToken, 
    uint256 _rewardsDuration
) external;
```

<table><thead><tr><th width="160">Type</th><th width="201.33333333333331">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>_rewardsToken</td><td>The asset that's being distributed</td></tr><tr><td>uint256</td><td>_rewardsDuration</td><td>How long rewards take to vest, e.g. 30 days (denoted in seconds).</td></tr></tbody></table>

Emits the [#rewardadded](#rewardadded "mention") event

#### `depositReward()`

Deposits a reward to this contract for distribution.

```solidity
function depositReward(
    address _rewardsToken, 
    uint256 reward
) external updateReward(address(0)) nonReentrant;
```

<table><thead><tr><th width="149.33333333333331">Type</th><th width="179">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>_rewardsToken</td><td>The asset that's being distributed.</td></tr><tr><td>uint256</td><td>reward</td><td>The amount of the _rewardsToken to deposit.</td></tr></tbody></table>

Emits the [#rewarddeposited](#rewarddeposited "mention") event

#### `fullWithdraw()`

Simultaneously calls `withdraw()` and `getRewards()` for convenience.

```solidity
function fullWithdraw() external;
```

Emits the [#withdrawn](#withdrawn "mention") and [#rewarddistributed](#rewarddistributed "mention") event(s)

#### `createVestingSchedule()`

Sets the vestingSchedule for an account.

```solidity
function createVestingSchedule(
    address account,
    uint256 daysToCliff, 
    uint256 daysToVest, 
    uint256 amountToVest, 
    bool revokable
) external onlyZVLorITO;
```

<table><thead><tr><th width="95">Type</th><th width="158.33333333333331">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The account vesting $ZVE</td></tr><tr><td>uint256</td><td>daysToCliff</td><td>The number of days before vesting is claimable (a.k.a. cliff period).</td></tr><tr><td>uint256</td><td>daysToVest</td><td>The number of days for the entire vesting period, from beginning to end.</td></tr><tr><td>uint256</td><td>amountToVest</td><td>The amount of tokens being vested.</td></tr><tr><td>bool</td><td>revokable</td><td>If the vested amount can be revoked.</td></tr></tbody></table>

Emits the [#vestingschedulecreated](#vestingschedulecreated "mention") and [#staked](#staked "mention") event

#### `revokeVestingSchedule()`

Ends vesting schedule for a given account (if revokable).

```solidity
function revokeVestingSchedule(
    address account
) external updateReward(account) onlyZVLOrITO nonReentrant;
```

<table><thead><tr><th width="130.33333333333331">Type</th><th width="134">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>account</td><td>The acount to revoke a vesting schedule for.</td></tr></tbody></table>

Emits the [#vestingschedulerevoked](#vestingschedulerevoked "mention") event

#### `getRewards()`

Claim rewards for all possible \_rewardTokens.

```solidity
function getRewards() public updateReward(_msgSender());
```

Emits the [#rewarddistributed](#rewarddistributed "mention") event

#### `withdraw()`

Withdraws the specified amount of stakingToken from this contract.

```solidity
function withdraw(uint256 amount) public nonReentrant updateReward(_msgSender());
```

<table><thead><tr><th width="149.33333333333331">Type</th><th width="179">Name</th><th>Description</th></tr></thead><tbody><tr><td>uint256</td><td>amount</td><td>The amount of the _rewardsToken to withdraw.</td></tr></tbody></table>

Emits the [#withdrawn](#withdrawn "mention") event

## Events

#### **`RewardAdded()`**

Emitted during [#addreward](#addreward "mention")

```solidity
event RewardAdded(address indexed reward);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>reward</td><td>The asset that's being distributed.</td></tr></tbody></table>

#### **`RewardDeposited()`**

Emitted during [#depositreward](#depositreward "mention")

```solidity
event RewardDeposited(
    address indexed reward, 
    uint256 amount, 
    address indexed depositor
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>reward</td><td>The asset that's being deposited.</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The amount deposited.</td></tr><tr><td>address</td><td>True</td><td>depositor</td><td>The _msgSender() who deposited said reward.</td></tr></tbody></table>

#### **`RewardDistributed()`**

Emitted during [#getrewardat](#getrewardat "mention")

```solidity
event RewardDistributed(
    address indexed account, 
    address indexed rewardsToken, 
    uint256 reward
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="142">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>account</td><td>The account receiving a reward.</td></tr><tr><td>address</td><td>True</td><td>rewardsToken</td><td>The ERC20 asset distributed as a reward.</td></tr><tr><td>uint256</td><td>False</td><td>reward</td><td>The amount of "rewardsToken" distributed.</td></tr></tbody></table>

#### **`Staked()`**

Emitted during [#createvestingschedule](#createvestingschedule "mention")

```solidity
event Staked(address indexed account, uint256 amount);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>account</td><td>The account staking "stakingToken".</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The amount of "stakingToken" staked.</td></tr></tbody></table>

#### **`VestingScheduleCreated()`**

Emitted during [#createvestingschedule](#createvestingschedule "mention")

```solidity
event VestingScheduleCreated(
    address indexed account, 
    uint256 start, 
    uint256 cliff, 
    uint256 end, 
    uint256 totalVesting, 
    uint256 vestingPerSecond, 
    bool revokable
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>account</td><td>The account that was given a vesting schedule.</td></tr><tr><td>uint256</td><td>False</td><td>start</td><td>The block.timestamp at which tokens will start vesting.</td></tr><tr><td>uint256</td><td>False</td><td>cliff</td><td>The block.timestamp at which tokens are first claimable.</td></tr><tr><td>uint256</td><td>False</td><td>end</td><td>The block.timestamp at which tokens will stop vesting (finished).</td></tr><tr><td>uint256</td><td>False</td><td>totalVesting</td><td>The total amount to vest.</td></tr><tr><td>uint256</td><td>False</td><td>vestingPerSecond</td><td>The amount of vestingToken that vests per second.</td></tr><tr><td>bool</td><td>False</td><td>revokable</td><td>Whether or not this vesting schedule can be revoked.</td></tr></tbody></table>

#### **`VestingScheduleRevoked()`**

Emitted during [#revokevestingschedule](#revokevestingschedule "mention")

```solidity
event VestingScheduleRevoked(
    address indexed account, 
    uint256 amountRevoked, 
    uint256 cliff, 
    uint256 end, 
    uint256 totalVesting, 
    bool revokable
);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>account</td><td>The account that was revoked a vesting schedule.</td></tr><tr><td>uint256</td><td>False</td><td>amountRevoked</td><td>The amount of tokens revoked.</td></tr><tr><td>uint256</td><td>False</td><td>cliff</td><td>The updated value for cliff.</td></tr><tr><td>uint256</td><td>False</td><td>end</td><td>The updated value for end.</td></tr><tr><td>uint256</td><td>False</td><td>totalVesting</td><td>The total amount to vested (claimable).</td></tr><tr><td>bool</td><td>False</td><td>revokable</td><td>The final revokable status of schedule (always false after revocation).</td></tr></tbody></table>

#### **`Withdrawn()`**

Emitted during [#withdraw](#withdraw "mention")

```solidity
event Withdrawn(address indexed account, uint256 amount);
```

<table><thead><tr><th width="127.33333333333331">Type</th><th width="98">Indexed</th><th width="132">Name</th><th>Description</th></tr></thead><tbody><tr><td>address</td><td>True</td><td>account</td><td>The account withdrawing "stakingToken".</td></tr><tr><td>uint256</td><td>False</td><td>amount</td><td>The amount of "stakingToken" to withdraw.</td></tr></tbody></table>


---

# 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.zivoe.com/developer-docs/core-contracts/zivoerewardsvesting.sol.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.
