# Voting

There are 2 functions that support voting -&#x20;

1. `vote` - used when the wallet/address has no active vote nor EGLs locked or uncollected
2. `reVote` - used to either change an existing votes parameters (gas target, lockup duration and/or number of EGL's voted with), or to submit a new vote if the existing vote has elapsed (exceeded the lockup duration) without first withdrawing the EGLs to a wallet address

See [Voting](https://docs.egl.vote/protocol-overview/voting/vote-revote-withdraw) for more details

### 1.**`vote()`**&#x20;

Allows any wallet with EGL's to submit a vote to affect the weekly desired gas limit value

{% hint style="warning" %}
Since any vote requires you to spend some amount of EGL's, it is necessary to ensure the voting contract has a sufficient `allowance` to spend that amount of EGL's for the vote on your behalf. If the allowance is set high enough, this only had to be done once
{% endhint %}

{% hint style="info" %}
The `_eglAmount` parameter *must* be passed in as the wei value, i.e. the EGL token uses 18 decimal places so 1 EGL = 1000000000000000000 wei
{% endhint %}

{% hint style="info" %}
This function will additionally call `tallyVotes()` if the current voting period (epoch) has elapsed and the vote for the previous period has not yet been tallied. See [Tally Votes](https://docs.egl.vote/documentation/tally-votes)
{% endhint %}

#### Function Signature

```javascript
function vote(uint _gasTarget, uint _eglAmount, uint8 _lockupDuration) external whenNotPaused
```

| Parameters        | **Data Type** | Description                                                                                      | Example              |
| ----------------- | ------------- | ------------------------------------------------------------------------------------------------ | -------------------- |
| `_gasTarget`      | `uint256`     | The gas limit value you are voting for (must be + / - 4,000,000 of the current blocks gas limit) | 16500000             |
| `_eglAmount`      | `uint256`     | The amount of EGLs to be locked and used for voting (Must be >=1 EGL)                            | 10000000000000000000 |
| `_lockupDuration` | `uint8`       | The number of weeks your vote will be locked up for (valid values are numbers 1 through 8)       | 6                    |

#### Validations

| Validation **Rule**                                           | Description                                                                                  |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `_eglAmount >= 1 ether`                                       | Amount being voted with must be greater than 10000000000000000000 (1 EGL)                    |
| `_eglAmount <= eglToken.balanceOf(msg.sender)`                | The voting address must have a balance that is at least equal to the amount being voted with |
| `eglToken.allowance(msg.sender, address(this)) >= _eglAmount` | The voting contract must a have an allowance from the voter of at least the voting amount    |

#### Events Emitted&#x20;

* `VotesTallied` (Conditional)&#x20;
* `Transfer`
* `Vote`

#### Web3 Example

```javascript
// Allowance
await eglTokenInstance.increaseAllowance(
    eglContractInstance.address, 
    web3.utils.toWei("5000"), 
    { from: "0x2be650ba..." }
);

// Vote
await eglVotingInstance.vote(
    15500000, 
    web3.utils.toWei("100"), 
    4, 
    { from: "0x2be650ba..."}
)
```

####

### 2. **`reVote()`**

Allows a wallet that already has a vote locked in, to update that existing vote. This function also calculates any rewards that are due to the voter from past weeks (epochs). These rewards are automatically added to the updated vote. It is also possible, but not required, to add additional EGL's to the vote over and above the original vote amount.

{% hint style="warning" %}
Updating a vote with a shorter `_lockupDuration` will not allow locked EGL's to be released sooner. For example, if a vote was entered with an original `_lockupDuration` of 6 weeks, and 1 week later a `reVote()` was entered with a new lockup duration of 2 weeks, the EGL's will still only be unlocked 6 weeks from the original vote date, i.e. the unlock/release date is set to the`max(originalLockupDuration, reVoteLockupDuration)`
{% endhint %}

{% hint style="warning" %}
If an additional amount of EGL's is being voted with, over and above the original amount, it is necessary to ensure the voting contract has a sufficient allowance to spend the required amount of EGL's for the vote from your account.
{% endhint %}

{% hint style="info" %}
The `_eglAmount` parameter *must* be passed in as the wei value, i.e. the EGL token uses 18 decimal places so 1 EGL = 1000000000000000000 wei
{% endhint %}

{% hint style="info" %}
This function will additionally call `tallyVotes()` if the current voting period (epoch) has elapsed and the vote for the previous period has not yet been tallied. See [Tally Votes](https://docs.egl.vote/documentation/tally-votes)
{% endhint %}

```javascript
function reVote(uint _gasTarget, uint _eglAmount, uint8 _lockupDuration) external whenNotPaused
```

| Parameters        | **Data Type** | Description                                                                                       | Example  |
| ----------------- | ------------- | ------------------------------------------------------------------------------------------------- | -------- |
| `_gasTarget`      | `uint256`     | The gas limit value you are voting for (must be + / - 4,000,000 of the current gas limit)         | 16500000 |
| `_eglAmount`      | `uint256`     | The amount of EGLs, over and above the original vote, to be locked and used for voting (Can be 0) | 0        |
| `_lockupDuration` | `uint8`       | The number of weeks your vote will be locked up for (valid values are numbers 1 through 8)        | 6        |

#### Validations

| Validation Rule                                               | Description                                                                                                          |
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `voters[msg.sender].tokensLocked > 0`                         | Voting address must already have a vote locked to use `reVote()`                                                     |
| `_eglAmount >= 1 ether`                                       | If `_eglAmount > 0`, the amount being voted with must be greater than 10000000000000000000 (1 EGL)                   |
| `_eglAmount <= eglToken.balanceOf(msg.sender)`                | if If `_eglAmount > 0`, the voting address must have a balance that is at least equal to the amount being voted with |
| `eglToken.allowance(msg.sender, address(this)) >= _eglAmount` | If `_eglAmount > 0`, the voting contract must a have an allowance from the voter of at least the voting amount       |

#### Events Emitted&#x20;

* `VotesTallied` (Conditional)&#x20;
* `Transfer` (Conditional)
* `Withdraw`
* `Vote`
* `ReVote`

#### Web3 Example

```javascript
await eglVotingInstance.reVote(
    15500000, 
    web3.utils.toWei("100"), 
    4, 
    { from: "0x2be650ba..."}
)
```
