👀

Ve Token

Mar 18, 2023
Pancake
 
  1. Main factos
      • Use for vote-escrowed in DAO governance proposals, Gauges Voting
      • Not transferable
      • To increase veToken, only can do by
        • add more Token Staking
        • extend lock duration
      • Only way to get Ve token is staking
        • It will be fixed-term Staking
        • Can stake
          • min 1 weeks
          • max 4 years
        • The amount of VeToken recieved will be decided by formula
          • maxWeekLocked here = 208 weeks = 4 years
             
            So for example, If we Staking 2 Token in 4 weeks we will reiecve:
            • Week1 , Ve Amount = (2*4)/208 = 0.0380769231
            • Week2 , Ve Amount = (2*3)/208 = 0.0285576923
  1. Benefits
      • Weekly Rewards
        • Revenue Sharing based on how much staking Token. 5% of v3 trading fee revenue
        • Token Pool Rewards ( the emission will decided by gauge emission)
      • Gauges Voting Participation every epoch ( epoch = 2 weeks)
        • To Vote on farms, Reward Pools, Token emission
      • Farm boost. up to 2x
      • Particiate in IFO sales
 
  1. Vetoken Diagram Details explain

Deposit/WithDraw

notion image
  • Deposit:
    • In addition to the createLock function, we also have functions for increasing the token lock amount and adjusting the lock's end time after it has already been created.
    • Increse Lock Amount
    • Increase Time End
    • These functions both require user has locked, but for here we only consider createLock function, increaseLockAmount & IncreaseTimeEnd is almost same
       
      DepositFor Function: this function is called after createLock/Increse Lock Amount / Increase Time End called. This function to perform lock for user
      This function will exec these steps:
      1. increase Lock Balance Of User
      1. Call _checkpoint function that we will explain details below
      1. Update done, transfer token to locked
      1. If Farm Booster is set, update state for Farm Booster as well
       
  • Withdraw:
    • For this we have 2 functions:
    • earlyWithdraw : This function allow us can withdraw before end time lock.
      • *We can config Penalty for early withdraw in the function setEarlyWithdrawConfig
    • withdrawAll : This function only called when lock has expired.
    •  
      _unlock Function: this function is called after earlyWithdraw/withdrawAll called. This function to perform unlock for user
      This function will exec these steps:
      1. update new amount of Lock
      2. call _checkpoint function
       
  • _checkpoint
notion image
This function is used for to update balance Lock, VeToken remain of Specific User Or Update Globally for all user
To store Point (VeToken Balance) of User at that time. Contract use a struct
notion image
 
( 208 here is stands for MAX_LOCK_WEEKS)
 
This function will execute steps:
  1. Update prev balance to Points History (Balance here is amount Ve Token = amountLocked * remainWeekLocked/208)
  1. Increase User Epoch, update new balance
  1. Also update to global variable: Total Supply of Ve Token
 

Get Balance Of User

notion image
 
There are 2 ways to Get Balance:
  • By Time_stamp ( _balanceOf )
    • It’s quite simple here, just apply formula :
      in case, timeStamp < lockStart it will return 0 instead of Negative Number
       
  • By Block_number ( _balanceOfAt )
    • This function allows users to check their balance at a specific block number. It's more complex than GetBalanceByTime because we cannot directly retrieve the timestamp of a past block. Therefore, the solution involves storing historical snapshots of user balances for each block number (this variable is updated whenever the _checkpoint function is called). We can then use binary search to find the closest block number to the desired one and calculate the user's VE amount based on that snapshot.
       
      To do that we will have 3 variables:
      notion image
       
    • userEpoch
      • it’s epoch of User. it will increase incrementally like 1,2,3…,n, this epoch will +1 when _checkpoint is called
    • userPointHistory: mapping(address => Point[]) public userPointHistory;
      • we will use userEpoch to index for the userPointHistory Actually we can reduce number Of Variables by just index by Block_number but i guess $CAKE team use it to save memory used
         
    • globalEpoch; pointHistory:Point[] public pointHistory;
      • Same with User State Data; we have globalEpoch & pointHistory present for state of total users
       
      Then This function will execute steps:
      1. Binary Search to find most recent user Epoch to block Number → Get the State Point Of User
      1. Calculate timestamp of block_number
        1. Can’t get exact number but solution here is we can get the nearly number by formula:
          With :
          To Get BlockTime’ & blockNumber’
          → Binary Search to find most recent Global Epoch to block Number → Get the State Point Of Total User
  1. Apply Formula:
    1.  
 
 

Get Total Supply

notion image
 
Almost same logic with Get Balance ones
 
 
 
Thena
 
PermissionsRegistry.sol : To handle Entities & Roles of all contracts
Entities:
  • thenaMultisig
address public thenaMultisig // Control this contract. This is the main multisig 4/6
  • thenaTeamMultisig
address public thenaTeamMultisig;// This is the thena team multisig 2/2
 
Role:
notion image
 
*Need to add user to correct role first to execute functions
  • VOTER_ADMIN
    • _init Voter V3 Contract : Due to wrong init in V3 contract, after creating Voter V3 contract we need to call this function to update minter & permissionRegistry Address
    • notion image
      → Wrong here: when they assign minter & permissionRegistry Address = owner
    • set vote delay in seconds
    • Set a new Minter
    • Set a new Bribe Factory
    • Set a new PermissionRegistry
    • Set a new bribes for a given gauge
    • Set a new internal bribe for a given gauge
    • Set a new External bribe for a given gauge
    • addFactory/replaceFactory/removeFactory
  • GAUGE_ADMIN
    • BRIBE_ADMIN
      • To control BribeFactoryV3.sol contract :
    • FEE_MANAGER
    • CL_FEES_VAULT_ADMIN
     
    ⇒ Basically, to setup new Gauge, we need add Role BRIBE_ADMIN, VOTER_ADMIN, GOVERNANCE for address
     
    VoterV3.sol :
    _createGauge(address _pool, uint256 _gaugeType)
    notion image
    _vote(uint256 _tokenId, address[] memory _poolVote, uint256[] memory _weights)
    notion image
     
    claimRewards(address[] memory _gauges): claim LP gauge rewards
     
    claimBribes(address[] memory _bribes, address[][] memory _tokens, uint256 _tokenId): claim bribes rewards given a TokenID ( also there’s same function claimBribes(address[] memory _bribes, address[][] memory _tokens) that claim bribes rewards given an address)
     
    claimFees(address[] memory _fees, address[][] memory _tokens, uint256 _tokenId): claim fees rewards given a TokenID ( also there’s same function claimFees(address[] memory _bribes, address[][] memory _tokens) that claim fees rewards given an address
    notion image
     
     
     

    Comparison to BaseX

     
    VoterV3.sol
    • _reset function
    notion image
    Thena
    notion image
    BaseX
     
    • _vote → BaseX seems no need to check isAlive[_gauge], remove usedWeights
    notion image
    notion image
    Thena
    notion image
    notion image
    BaseX
     
    • _createGauge → BaseX remove check isPair, pairFactory
     
    notion image
    Thena
    notion image
    BaseX
     
     
    GaugeV2_CL.sol
    • IRewarder
    notion image
    Thena
    notion image
    Base X
    • Variables
    notion image
    Thena
    notion image
    Base X
     
    • _claimFees: formula to cal fee not same
    notion image
    notion image
    Thena
    notion image
    notion image
    Base X
     
     
     
     
    VotingEscrow.sol : Ok
     
    BribeFactoryV3.sol : Ok
     
    GaugeFactoryV2_CL.sol: Ok
    Â