# Voting Escrow dForce Token
[TOC]
---
## Overview
veDF is a fork of 'COMP' token, non-transferrable, stands for voting escrow [sDF](https://hackmd.io/@Triumph/B1ekPIHCO). They are your sDF locked for voting, when users vote lock their sDF, they get voting power and staking rewards. The longer you lock your sDF for, the more voting power you have. You can vote lock 1,000 sDF for a year to have a 250 veDF weight, get more voting power by locking your sDF for a longer period of time. In the meantime, more voting power represets more staking reward rate, your staking reward rate will be 4 times when you vote lock 1,000 sDF for four years against only for one year.
Your veDF voting power still stands after your escrowed tokens approach their lock expiry, unless you exit the lock and get your sDF token back. But the staking reward rate will decreases to 0 when locker expired.
## Architecture

## Audit Scope
* sDF: [link](https://hackmd.io/@Triumph/B1ekPIHCO)
* veDF
* veDFCore
* veDFMangement
## Modules & Algorithm
### veDF
veDF non-transferrable voting escrow of sDF, each locker represents one vote-lock position of user and only one actived locker allows to exit for one user at the same time. An authorised minter can create, refill, extend, refresh or withdraw upon a locker, the only authorised minter of veDF is veDFManager for now.
#### 1. create a locker
user can lock their sDF, get voting power and participate in reward distribution program
* exchange rate: locker_period_in_seconds / 4Year_in_seconds, for example: 100 sDF lock for 1 year will get: 100 * 1/4 = 25 veDF
* one user can hold one actived (not expired) locker
* locker period is up to 4 year

#### 2. add to an activated locker
* the locker must **NOT** be expired
* received veDF amount depends on the left lockup period, for example: add 100 sDF to a 1 year locker, 0.5 year lockup period left, then vDF balance will increase: 100 * 0.5/4 = 12.5 veDF

#### 3. extend period to an activeated locker
* the locker must **NOT** be expired
* received veDF amount depends on the extended lockup period, for example, extend 1.5 year to a 1 year locker with 100 sDF locked, then vDF balance will increase: 100 * 1.5/4 = 37.5 veDF
* the new period after extending is up to 4 year

#### 4. exit an expired locker
* the locker must be expired
* get locked sDF back, all veDF of user will be burned
#### 5. recreate locker upon the expired one
* the locker must be expired
* lock the new sDF amount with new lockup period
### veDFManager
It acts as a general staking pool, users can stake their veDF token and get reward in weight of veDF balance, also acts as veDF authorised minter, provides portal to create, refill, extend, refresh or withdraw upon their locker for users.
In order to simplify the complexity of calculating expired balance of lockers, only due time stands in the integer times of MIN_STEP plus startTime considers as valid, the MIN_STEP is week in seconds, so there is only 4*52=208 valid due time points.
***`Important: when locker expired, the escrowed voting power is still available until users withdraw their sDF and exit the vote lock. Meanwhile, the reward rate will decrease to 0 if the locker expired until they rejoin the vote lock.`***
#### 1. staking start
* start time for reward distributing, also start time to calculate valid due time of locker.
#### 2. valid due time
* only due time in the integer times of MIN_STEP plus startTime considers as valid due time, for example: startTime = 1644199200(Feb 07 2022 10:00:00 GMT+0800), MIN_STEP = 604800, the valid due time sits in: 1644199200+1 * 604800, 1644199200+2 * 604800, 1644199200+3 * 604800, ..., 1644199200+n * 604800, and 1644199200+n * 604800 should less than current time stamp + 4Year_in_seconds (maximal lockup period should less than 4 years).

#### 3. valid staking veDF balance
* only actived (not expired) locker considers having valid veDF balance for staking, if locker expired(due time < current timestamp) the veDF balance of user considers as 0.
#### 4. distribute in weight of valid staking veDF balance
##### 4.1 Node
* Node records expired veDF balance in the timestamp, when the timestamp passed, this Node should be settled and rewardPerTokenSettled will record in the Node time, any action should trigger settlement of overdue Nodes at first.
*
* Node with smaller timestamp always settled earlier than one with bigger timestamp.
* If no actived locker after the Node(total staked veDF balance = 0), reward distribution stops no matter what rewardRate is.
* The maximal number of unsettled Nodes should less than 208.
##### 4.2 lastSettledTime & lastUpdateTime & accSettledBalance
* lastSettledTime records the next Node time to settle
* lastUpdateTime records the latest action's time which triggered reward update
* accSettledBalance records total balance of veDF in settled Nodes.
##### 4.3 rewardPerTokenSettled VS rewardPerTokenStored
* rewardPerTokenSettled records the rewardPertoken value in **the** settled Node time.
* rewardPerTokenStored records the rewardPertoken value in the last action time which triggered reward update
##### 4.4 How to settle Node?

##### 4.5 How to caculate reward?
* every user has a local rewardPerToken value named userRewardPerTokenPaid, user's reward is calculated according to if the user's locker is expired,

## Terminology
##### locker
position where users lock their sDF, record locked sDF amount, period and expired time.
##### duration
locked period of locker in seconds.
##### dueTime
due time of locker in seconds.
##### Node
space to record veDF amount of lockers who will be expired.
##### startTime
time for staking start.
##### rewardToken
token in distribution.
##### rewardRate
token amount distributes in one second.
##### MIN_STEP
minimal step of valid due time from startTime, means that dueTime must be the integer times of MIN_STEP plus startTime.
##### rewardDistributor
where reward token comes from.