Giter Site home page Giter Site logo

ve's Introduction

VE

Configuration

  • To keep packages isolated between forge and eth-brownie, there should be TWO Python virtual envs to manage. In most cases, they will be worked on in isolation, but this is something to be careful of. TBD if it is better to unify these into the root virtual env.

Testing

Tests are run using Foundry:

  1. Activate Python environment to make Vyper available: . ve-venv/bin/activate
  2. Run tests: forge test --ffi -vv

Deploy

Deploy scripts are run using Brownie:

  1. Replace Brownie contracts from the forge ./src directory:
    $ make copy
  2. Enter deploy directory (cd deploy)
  3. Create and/or activate Python virtual env
    • Create: python3.9 -m venv ve-venv
    • NOTE: eth-brownie will fail to install on versions >= 3.10. The eth-ape library appears to be its successor but is not yet mature enough to migrate all tooling (Nov 1, 2023).
    • Activate: . ve-venv/bin/activate
    • Dependencies (first run): pip install --upgrade pip && pip install -r requirements.txt
  4. Create an .env file with:
    INSTANCE_ID=primary
    
  5. Populate JSON configurations with contract and multisig addresses
    • Mainnet: ./scripts/inputs/1/primary.json
    • Polygon: ./scripts/inputs/137/primary.json
    • Arbitrum: ./scripts/inputs/42161/primary.json
  6. Run deploy script: brownie run scripts/mainnet/<script-name>.py --network mainnet
    • NOTE: Some scripts depend on only existing (inputs) addresses, others depend on existing (inputs) and deployed (outputs) addresses. Outputs are set by other scripts.
    • Networks: mainnet, polygon-main, arbitrum-main

Deploy (localhost)

To test the deployment, the Brownie scripts are run in conjunction with an anvil localnode using two terminal windows.

  1. Populate JSON configurations with contract and multisig addresses: ./scripts/inputs/31337/primary.json
  2. (Terminal 1) Fork network with anvil: anvil --fork-rpc-url <url> --fork-block-number <num> --chain-id 31337
  3. (Terminal 2) Run brownie script using development privkey: brownie run scripts/mainnet/0_deploy_vedfx.py

All scripts can be run using an Ethereum RPC with the block num 18415000.

For different address configurations, change the chain id to easily use separate config files.

Test Deployments (testnets)

For end-to-end testing of the sidechain contracts:

  1. Replace Brownie contracts from the forge ./src directory:

    $ make copy
  2. Edit ./deploy/.env with test wallet id

    • DEPLOY_WALLET_ID=sepolia-dev
  3. Change dir: cd deploy

  4. Activate Python virtual env: source ve-venv/bin/activate

  5. Deploy fake LPT script: brownie run scripts/testnet/deploy_fake_lpt.py --network sepolia

    • Validate contract manually on https://sepolia.etherscan.io
  6. Edit scripts/testnet/deploy_child_chain_gauge.py with LPT address

  7. Deploy test child chain gauge set script: brownie run scripts/testnet/deploy_child_chain_gauge.py --network sepolia

Documenting

Any contracts that failed to verify or must be verified manually (Vyper contracts) must be done on their respective block explorers (Etherscan, Polygonscan, Arbiscan). After deployment of any contract(s), new addresses are then to be added to the protocol addresses spreadsheet.

ve's People

Contributors

kafitz avatar honestbonsai avatar chanharryhk avatar tommy4241 avatar

Watchers

 avatar Adrian Li avatar  avatar

ve's Issues

Determining VE funding schedule and emission rates

@chanharryhk @honestbonsai @tommy4241

The VE contracts can be tested using brownie test or deployed by scripts to a local node using the instructions from the ReadMe.

Part 1
In brief, the distributor contract will receive lump sum rewards and prorate these rewards weekly to the registered gauges, depending on their latest vote weight. The remaining work is starts with understanding how to set this rate here:

/// @notice Constructor of the contract
/// @param _rewardToken Address of the DFX token
/// @param _controller Address of the GaugeController
/// @param _initialRate Initial DFX emission rate
/// @param _startEpochSupply Amount of DFX tokens already distributed via liquidity mining
/// @param governor Governor address of the contract
/// @param guardian Address of the guardian of this contract
/// @param _delegateGauge Address that will be used to pull rewards for type 2 gauges
/// @dev After this contract is created, the correct amount of DFX tokens should be transferred to the contract
/// @dev The `_delegateGauge` can be the zero address
function initialize(
address _rewardToken,
address _controller,
uint256 _initialRate,
uint256 _startEpochSupply,
address governor,
address guardian,
address _delegateGauge
) external initializer {
require(
_controller != address(0) && _rewardToken != address(0) && guardian != address(0) && governor != address(0),
"0"
);
rewardToken = IERC20(_rewardToken);
controller = IGaugeController(_controller);
startEpochSupply = _startEpochSupply;
miningEpoch = 0;
// Some DFX tokens should be sent to the contract directly after initialization
rate = _initialRate;
delegateGauge = _delegateGauge;
distributionsOn = false;
startEpochTime = block.timestamp;
_setRoleAdmin(GOVERNOR_ROLE, GOVERNOR_ROLE);
_setRoleAdmin(GUARDIAN_ROLE, GOVERNOR_ROLE);
_setupRole(GUARDIAN_ROLE, guardian);
_setupRole(GOVERNOR_ROLE, governor);
_setupRole(GUARDIAN_ROLE, governor);
}

Also described in this contract is a RATE_REDUCTION_TIME (defaults to 1 week) and a RATE_REDUCTION_COEFFICIENT which means the amount the distributed to contracts will follow a curve (decreasing). Both of these seem sensible and standard, so these didn't seem necessary to adjust.

When setting the rate, the most common error received back is a 4 value. This occurs when the rate is too high and would emit faster than the rewards available:

/// @notice Withdraws ERC20 tokens that could accrue on this contract
/// @param tokenAddress Address of the ERC20 token to withdraw
/// @param to Address to transfer to
/// @param amount Amount to transfer
/// @dev Added to support recovering LP Rewards and other mistaken tokens
/// from other systems to be distributed to holders
/// @dev This function could also be used to recover DFX tokens in case the rate got smaller
function recoverERC20(
address tokenAddress,
address to,
uint256 amount
) external onlyRole(GOVERNOR_ROLE) {
// If the token is the DFX token, we need to make sure that governance is not going to withdraw
// too many tokens and that it'll be able to sustain the weekly distribution forever
// This check assumes that `distributeReward` has been called for gauges and that there are no gauges
// which have not received their past week's rewards
if (tokenAddress == address(rewardToken)) {
uint256 currentBalance = rewardToken.balanceOf(address(this));
// The amount distributed till the end is `rate * WEEK / (1 - RATE_REDUCTION_FACTOR)` where
// `RATE_REDUCTION_FACTOR = BASE / RATE_REDUCTION_COEFFICIENT` which translates to:
require(
currentBalance >=
((rate * RATE_REDUCTION_COEFFICIENT) * WEEK) / (RATE_REDUCTION_COEFFICIENT - BASE) + amount,
"4"
);
}
IERC20(tokenAddress).safeTransfer(to, amount);
emit Recovered(tokenAddress, to, amount);
}

By using the equation in this function, I was able to work backwards from 1,000,000 DFX rewards to find a rate of 0.01284240247 which is accepted by the contract and distributes rewards (see spreadsheet). By modeling with one user locking up LPT to a gauge and using the amount of DFX rewards received for the epoch 1, the spreadsheet model matches the amount of rewards received in the subsequent weeks over 4 years (208 weeks). Like in the spreadsheet, however, a total of ~800K out of the 1M total are distributed meaning there's still something to figure out to get total distribution to be the full 1M amount. I believe with only one user in the system, the total amount of rewards should be allocated over this period.

Part 2
With rates figured out, we need to be able to calculate the base APR for users with only LPT staked in the LiquidityGaugeV4 contract compared to users with staked LPT and holding veDFX.

Note
This is a broad overview, happy to elaborate on any details.

Internal peer review of VE code

@adrianmcli @chanharryhk @honestbonsai

Hey everyone, this ve repository is at a place where I think it should be reviewed to suggest any additional tests/anything else it might need.

There is one thing inconsequential to our local development, but should be done before going live which is updating the deploy scripts so everything is behind an upgradeable proxy (#3).

For testing with a local node, I've still had several issues with brownie/anvil which seems to be things that need to be updated within brownie itself. Perhaps there are some workarounds I haven't found. As a result, I launch the hardhat node from frontend-monorepo/packages/ve and then run my tests from this repo as: brownie test -s.

Don't hesitate on any questions or concerns, there were a lot of moving parts to untangle to get this working.

Make all contracts upgradeable

Outside recommendation is all contracts should be upgradeable including VotingEscrow (veDFX).

Currently this requires adjustments to VotingEscrow, GaugeController, and VeBoostProxy.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.