# Vote, Revote, Withdraw

## **Timeline**

EGL voting works in weekly epochs, using the block's timestamps.  At the end of each week the votes are tallied (`tallyVotes()`) and the `desiredEgl` is updated (see [Calculating desiredEgl](https://docs.egl.vote/protocol-overview/voting/calculating-desiredegl)). The first vote is to be calculated one week after the EGL smart contract is launched and every week thereafter.

Votes may be cast using `vote()` or `revote()` at any time, up until 4 hrs before the weekly tally is scheduled to take place.

`tallyVotes()` can be called directly by anyone once an epoch has ended, or indirectly by any `vote()`, `revote()`, or `withdraw()` calls.

{% hint style="warning" %}
You cannot vote or revote within 4 hours of a given epoch ending. EGL.vote will not allow you to vote, but if you call the contract directly within this time period, your vote will fail.&#x20;
{% endhint %}

## **Lockup**

To cast a vote, an EGL holder must lock up some amount of EGLs (`eglAmount`) for  a period of 1-8 weeks (`lockupDuration`) . The lockup starts from the time of the `vote()`or `revote()` Tx being mined. Therefore, a voter who votes on Wednesday Jan 1st at noon and specifies `lockupDuration=2` will be able to withdraw said EGLs on Wednesday Jan 15th at noon.&#x20;

It is possible for voters to adjust their vote using `revote()` (outlined [below](#vote-withdraw-and-revote)), however the locked `eglAmount` will not be released any sooner.

## `vote()`, `withdraw()` and `revote()`

To keep the design as clean and simple as possible:

* `vote()` can only be called if the wallet/address has no active vote nor EGLs locked or uncollected.
* `withdraw()` withdraws *all the EGLs* including [Voter Reward](https://docs.egl.vote/protocol-overview/voting/rewards), leaving a clean slate, and can be called after the lockup has expired.
* `revote()` calls `withdraw()` *internally,* cleaning any existing votes and their effect on the vote, collecting any rewards, and then calls `vote()` *internally* using the original `eglAmount` plus any reward tokens due as the new `eglAmount`, but ensuring the EGLs release date is the later between
  * The existing vote (now removed)
  * The new vote, based on current time and `lockupDuration`.

{% hint style="info" %}
Revote can be used in two ways: 1) to change your vote when EGLs are locked and owned by the contract (i.e. not available for withdrawal) and 2)  to submit a new vote when EGLs are in the contract but available for withdrawal.&#x20;
{% endhint %}

## Maintaining Votes for Multiple Epochs

Votes can be cast for up to `8` weeks into the future, thus at any given time the EGL smart contract maintains `8` sets of variables to track the weight-averaged desired change to `desiredEGL`, and `vote()` and `revote()` affect the relevant variables depending on their `lockupDuration`. Once `tallyVotes()` is called and `desiredEGL` is adjusted, the values for each epoch are advanced by 1 slot, and the last (8th) variables are initialized with 0.
