owned this note
owned this note
Published
Linked with GitHub
# Prime Pools
## Overview
System goals:
- Create a coordination mechanism for D2D and BAL holders to maximise profit from Balancer liquidity mining rewards program
- Allow users to stake BAL whilst remaining liquid
System elements:
- Balancer v2 liquidity pools
- Balancer ve contracts
- PrimePools contract
- d2dRewards contract
- d2dBAL ERC20 token
## Tech specification
This is a tech spec, describing the architecture of the Prime Pools project, requirements for which are written in this [document](https://primedao.notion.site/Prime-Pools-Breakdown-8318579e5b054e128cc98cc4d6de8803). Requirements state that the Prime Pools should be organised like [Convex Finance](https://www.convexfinance.com/stake). Then, based on this requirements we can deduct that 5 contracts are required for the complete functioning of the system,which are:
- WETH/BAL LP ERC20 token contract.
- d2dBAL ERC20 token contract.
- Deposit contract.
- Rewards contract.
- Controller contract.
- VoterProxy contract.
Specific ERC20 tokens doesn't play major role in the system, and they will be used only during the deployment of the contract, so in the process of the development they can be mocked with some local test ERC20 tokens. The part which is major for the system(based on the Convex architecure) are Deposit, Controller and Rewards contract, they are going to be described below, as well as changes which will be needed to satisfy the requirements.
**D2D BAL SHOULD BE DISTRIBUTED AS A REWARD**
## Deposit contract
Deposit contract for Prime Pools is based on the convex [contract](https://etherscan.io/address/0x8014595F2AB54cD7c604B00E9fb932176fDc86Ae), `crvDepositor.sol`. This contract is needed to deposit WETH/Bal ERC20 token, which will afterwards produce d2dBal. Mostly the logic of this contract stays the same. The only important things are that:
- All of the minted D2DBal instantly gets locked in the rewards contract.
- All of the WETH/Bal received gets sent to the [veBal](https://etherscan.io/address/0xc128a9954e6c874ea3d62ce62b468ba073093f25) contract, with the deposit_for function or transfer to voterProxy and increase_amount function call from there. VoterProxy will be the owner of distributed veBal tokens.
Here are changes that will be required to implement this contract for our specific goal.
### State variables
These are the variables/constants we'll need to add/change for the proper work of the contract:
- `balWeth`. Immutable address of the 80BAL/20WETH token instead of `crv`, sent in the constructor.
- `minter`. Will be set up by constructor, we'll need to use the address of d2dBAL token.
- `veBal`. Immutable address of the veBal token instead of `escrow` recieved in the constructor.
- `staker`. Immutable address of the `voterProxy` contract recieved in the constructor.
### Functions
- `_lockCurve` -> `_lockToken` should transfer tokens to the staker / `voterProxy` contract, and then lock those tokens in the veBal conract. `VoterProxy` should be the owner of this locked tokens(deposit_for).
- `deposit`. In the deposit we will automatically provide Reward address as `_stakeAddress`. All of the minted d2dBal will be automatically staked to the `Rewards` contract.
## Rewards contract
Rewards contract for Prime Pools is based on the convex [contract](https://etherscan.io/address/0x3Fe65692bfCD0e6CF84cB1E7d24108E434A7587e), `BaseRewardPool.sol`. This contract is needed to stake `d2dBAL` tokens and generate rewards based on the defined token, also it works as rewards contract for all of the LPs, provides reward in BAL for specific tokens. Each LP has it's own rewards contract. In the default implementation it's CRV token, in our case rewards are generated in BAL. There are few changes in logic, which are:
- Rewards are distributed in Bal instead of CRV.
### State variables
This is the variables/constants we'll need to add/change for the propper work of the contract:
- `stakingToken` - Staking token provided will be a d2dBAL, minted in the Deposit contract.
- `rewardToken` - reward contract is going to be BAL, which will be received from BAL ve model.
### Controller contract
Controller contract for Prime Pools is based on the convex [contract](https://etherscan.io/address/0xf403c135812408bfbe8713b5a23a04b3d48aae31#tokentxns), `Booster.sol`. But there is a list of important changes that we'll need to make, for this contract to satisfy our needs.This contract is needed to manage the reward flow, which is received from 2 points:
1) the veBal staking rewards.
2) Rewards tokens minted by balancer for the liquidity providers.
After receiving rewards, contract then takes 12,5% fee from **profits**, 10% are staked back to the veBal, to increase the profits for liquidity providers, 2,5% going to the Prime Foundation to fund the further development(into GnosisSafe). Everything else is getting distributed between the users, both for staking and liquidity rewards.
Changes to the original booster:
- Most of this functionality except for the Fees distribution is already implemented.
- Single possible difference is that we maybe will use Snapshot vote, instead of vote used in the application.
**This contract is going to be a receiver of the revards from the`BAL` staking to the veBAL contract from the Deposit.**
### Constants
- `crv` - instead of `crv` we need to use `Bal` contract, because it's the main rewards generator in our case.
- `treasury` - it is going to be the company's Gnosis safe
- `PoolToken` - it is a token being minted for the liquidity providing, it will be minted to the Reward contracts and will be unwithdrawable.
### Functionality
- `earmarkRewards` should send rewards to lockRewards and and
- `constructor` should create lock in the BAL/WETH contract for a max interval(a year), also need to add fee in the constructor.
- `deposit` & `withdraw` remain the same
- `setFees` we need only `platformFee` and one new fee `profitFee`, all other fees should be removed
## VoterProxy
[VoterProxy](https://etherscan.io/address/0x989aeb4d175e16225e39e87d0d97a3360524ad80#code) contract is contract that owns all of the veBAL tokens, through which happens liquidity provision to the pools, veBAL voting, rewards distribution. This contract doesn't require big changes(except for exchanging Curve interactions with Balancer ones).
Contract changes:
- VoterProxy owner will be a GnosisSafe, owned by Prime.
- Votes will call this [contract](https://etherscan.io/address/0xC128468b7Ce63eA702C1f104D55A2566b13D3ABD) function, called vote_for_gauged weights.
- There will be a function vote_for_multiple_gauges, which will allow to distribute all veBal in a single call.
- Receive and distribute rewards from veBal contract(rewards can be distributed on function call) to the rewards contract.
- Withdraw provided liquidity.
- Add functionality to restake/withdraw Bal in the veBAL via GnosisSafe owner(PrimeDAO).
## Vote
Current proposal is for users to vote for their preferred pool directly, using d2dBAL they own. They'll call vote function in the controller, with the amount d2dBal, they want to vote with, amount of veBAL according to the d2dBAL will be sent [here](https://etherscan.io/address/0xC128468b7Ce63eA702C1f104D55A2566b13D3ABD#code) Vote_for_gauge_weights function will be called.
There is also a possibility to organise vote through Snapshot, it will be more difficult to implement + it will be less decentralised, but on the other side it will save users' funds and it will be cheaper.
# Appendices
## Controller functionality
Controller contract should support this functionality:
- Receive and distribute pool rewards to people, based on what pool they chose to put their veBal in(based on the d2dBal vote).
- Provide liquididty through contract to the balancer, with all of the liquidity info saved in the contract(so the reward distribution is fair).
- Generate fees from the pool rewards.(12,5% tax on the profits, from which 10% is staked to veBal, to improve the conditions).
- Control and deposit funds to the pools.(We can use `deposit` function in the Booster)
- Control the staked veBal fund.(This is the same thing as `deposit` and `withdraw`, because veBal is just another LP) with staked d2dBAL via voting.
- Being governed by the Multisig(Possibly voting mechanism for d2dBal owners)
- Airdrops? Maybe a function that allows to just manually send some personal funds to someone.
- Withdraw provided liquidity.
- User votes for some pool using d2dBAL, we, using snapshot or smth call the function, which will distribute veBAL owned by controller contract between the pools.
- Add functionality to restake/withdraw Bal in the veBAL via GnosisSafe owner(PrimeDAO).