Skip to content

Commit

Permalink
chore: formatting and comments (#166)
Browse files Browse the repository at this point in the history
* chore: formating and comments

* chore: contribution guide

* chore: readme

* fix: caches

* fix: unneeded checks

* chore: comments

* chore: readme updates

* chore: contract descriptions

* fix: waveys grammer fixes
  • Loading branch information
Schlagonia authored Jun 5, 2023
1 parent 6625357 commit 3e51c08
Show file tree
Hide file tree
Showing 5 changed files with 480 additions and 166 deletions.
90 changes: 90 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Contribution guide

If you are new to [Yearn Finance](https://yearn.finance/), you might want to familiarize yourself with its [core concepts and products](https://docs.yearn.finance/). You can also join the [discord channel](https://discord.com/invite/6PNv2nF/) if you have questions or to keep up with updates.

## Setting up your environment

Before proceeding, please set up your environment by following these installation, building and testing [instructions](https://github.com/yearn/yearn-vaults-v3/blob/master/README.md).

## Making your first contribution

Each time you begin a set of changes, ensure that you are working on a new branch that you have created as opposed to the `master` of your local repository. By keeping your changes segregated in this branch, merging your changes into the main repository later will be much simpler for the team.

To create a local branch for `git` to checkout, issue the command:

```bash
git checkout -b feature-in-progress-branch
```

To checkout a branch you have already created:

```bash
git checkout feature-in-progress-branch
```

### Preparing your commit

The official yearn-vaults-v3 repository may have changed since the time you cloned it. To fetch changes to the yearn-vaults-v3 repository since your last session:

```bash
git fetch origin
```

Then synchronize your master branch:

```bash
git pull origin master

```

To stage the changed files that are be committed, issue the command:

```bash
git add -a
```

Once you are ready to make a commit, you can do so with:

```bash
git commit -m “fix: message to explain what the commit covers”
```

**NOTE**: commit message must follow Conventional Commits [standard](https://www.conventionalcommits.org/en/v1.0.0/), otherwise your pull requests (discussed further below below) will not pass validation tests. You can use the [`--amend` flag](https://git-scm.com/docs/git-commit) to effectively change your commit message.

### Handling conflicts

If there are conflicts between your edits and those made by others since you started work Git will ask you to resolve them. To find out which files have conflicts, run:

```bash
git status
```

Open those files, and you will see lines inserted by Git that identify the conflicts:

```text
<<<<<< HEAD
Other developers’ version of the conflicting code
======
Your version of the conflicting code
'>>>>> Your Commit
```

The code from the yearn-vaults-v3 repository is inserted between `<<<` and `===` while the change you have made is inserted between `===` and `>>>>`. Remove everything between `<<<<` and `>>>` and replace it with code that resolves the conflict. Repeat the process for all files listed by Git status to have conflicts.

When you are ready, use git push to move your local copy of the changes to your fork of the repository on Github.

```bash
git push [email protected]:<your_github_username>/yearn-vaults-v3.git feature-in-progress-branch
```

### Opening a pull request

Navigate to your fork of the repository on Github. In the upper left where the current branch is listed, change the branch to your newly created one (feature-in-progress-branch). Open the files that you have worked on and ensure they include your changes.

Navigate to yearn-vaults-v3 [repository](https://github.com/yearn/yearn-vaults-v3/tree/master) and click on the new pull request button. In the “base” box on the left, leave the default selection “base master”, the branch that you want your changes to be applied to. In the “compare” box on the right, select the branch containing the changes you want to apply. You will then be asked to answer a few questions about your pull request. Pull requests should have enough context about what you are working on, how you are solving a problem, and reference all necessary information for your reviewers to help.

After you complete the questionnaire, the pull request will appear in the [list](https://github.com/yearn/yearn-vaults-v3/pulls) of pull requests.

### Following up

Core developers may ask questions and request that you make edits. If you set notifications at the top of the page to “not watching,” you will still be notified by email whenever someone comments on the page of a pull request you have created. If you are asked to modify your pull request, edit your local branch, push up your fixes, then leave a comment to notify the original reviewer that the pull request is ready for further review.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ and test smart contracts with:
ape test
```

### To make a contribution please follow the [guidelines](https://github.com/yearn/yearn-vaults-v3/bloc/master/CONTRIBUTING.md)

See the ApeWorx [documentation](https://docs.apeworx.io/ape/stable/) and [github](https://github.com/ApeWorX/ape) for more information.

You will need hardhat to run the test `yarn`
41 changes: 23 additions & 18 deletions TECH_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
- Queue_Manager: smart contract that can be configured by management to hold the optimal withdrawal queues for each vault

# VaultV3 Specification
The Vault code has been designed as an unopinionated system to distribute funds of depositors into different opportunities (aka Strategies) and manage accounting in a robust way. That's all.
The Vault code has been designed as an non-opinionated system to distribute funds of depositors into different opportunities (aka Strategies) and manage accounting in a robust way. That's all.

The depositors receive shares of the different investments that can then be redeemed or used as yield-bearing tokens.
Depositors receive shares (aka vaults tokens) proportional to their deposit amount. Vault tokens are yield-bearing and can be redeemed at any time to get back deposit plus any yield generated.

The Vault does not have a preference on any of the dimensions that should be considered when operating a vault:
- *Decentralization*: roles can be filled by EOA, smart contract like multisig or governance module
- *Liquidity*: vault can have 0 liquidity or be fully liquid. It will depend on parameters and strategies added
- *Security*: vault managers can choose what strategies to add and how to do that process
- *Automation*: all the required actions to maintain the vault can be called by bots or manually, depending on periphery implementation
- *Decentralization*: Roles can be filled by any address (e.g. EOA, smart contract, multi-sig).
- *Liquidity*: Vault can have 0 liquidity or be fully liquid. It will depend on parameters and strategies added.
- *Security*: Vault managers can choose what strategies to add and how to do that process.
- *Automation*: All the required actions to maintain the vault can be called by bots or manually, depending on periphery implementation.

The compromises will come with the implementation of periphery contracts fulfilling the roles in the Vault.

Expand Down Expand Up @@ -56,7 +56,7 @@ Users can redeem their shares at any point in time if there is liquidity availab

Optionally, a user can specify a list of strategies to withdraw from. If a list of strategies is passed, the vault will try to withdraw from them.

If a user passed array is not defined. The redeem function will check if there is a queue_manager set to get a valid withdraw queue from. If neither happens the vault will check if there are enough idle funds to serve the request. If there are not enough, it will revert.
If a user passed array is not defined, the redeem function will use the default_queue.

If not enough funds have been recovered to honor the full request, the transaction will revert.

Expand Down Expand Up @@ -92,9 +92,9 @@ new_profit_distribution_rate = (locked_profit + new_profit) / new_locking_period

Losses will be offset by locked profit, if possible.

Issue of new shares due to fees will also unlock profit so that pps does not go down.
Issue of new shares due to fees will also unlock profit so that PPS does not go down.

Both of this offsets will prevent frontrunning (as the profit was already earned and was not distributed yet)
Both of this offsets will prevent front running (as the profit was already earned and was not distributed yet)

## Vault Management
Vault management is split into function specific roles. Each permissioned function has its own corresponding Role.
Expand All @@ -109,7 +109,7 @@ These are:
- REVOKE_STRATEGY_MANAGER: role that can remove strategies from the vault
- FORCE_REVOKE_MANAGER: role that can force remove a strategy causing a loss
- ACCOUNTANT_MANAGER: role that can set the accountant that assesses fees
- QUEUE_MANAGER: role that can set the queue_manager
- QUEUE_MANAGER: role that can set the default_queue
- REPORTING_MANAGER: role that calls report for strategies
- DEBT_MANAGER: role that adds and removes debt from strategies
- MAX_DEBT_MANAGER: role that can set the max debt for a strategy
Expand All @@ -119,16 +119,16 @@ These are:
- DEBT_PURCHASER # can purchase bad debt from the vault
- EMERGENCY_MANAGER: role that can shutdown vault in an emergency

Every role can be filled by an EOA, multisig or other smart contracts. Each role can be filled by several accounts.
Every role can be filled by an EOA, multi-sig or other smart contracts. Each role can be filled by several accounts.

The account that manages roles is a single account, set in `role_manager`.

This role_manager can be an EOA, a multisig or a Governance Module that relays calls.
This role_manager can be an EOA, a multi-sig or a Governance Module that relays calls.

### Strategy Management
This responsibility is taken by callers with ADD_STRATEGY_MANAGER, REVOKE_STRATEGY_MANAGER and FORCE_REVOKE_MANAGER roles

A vault can have strategies added, removed oe forcefully removed
A vault can have strategies added, removed or forcefully removed

Added strategies will be eligible to receive funds from the vault, when the max_debt is set to > 0

Expand All @@ -137,9 +137,9 @@ Revoked strategies will return all debt and stop being eligible to receive more.
Force revoking a strategy is only used in cases of a faulty strategy that cannot otherwise have its current_debt reduced to 0. Force revoking a strategy will result in a loss being reported by the vault.

#### Setting the periphery contracts
The accountant and the queue_manager contracts can each be set by the ACCOUNTANT_MANAGER and QUEUE_MANAGER respectfully
The accountant can each be set by the ACCOUNTANT_MANAGER.

The contracts are not needed for the vault to function but are recommended for optimal use
The contract is not needed for the vault to function but are recommended for optimal use.

#### Reporting profits
The REPORTING_MANAGER is in charge of calling process_report() for each strategy in the vault according to its own timeline
Expand All @@ -164,7 +164,7 @@ The MAX_DEBT_MANAGER can set the maximum amount of tokens the vault will allow a

Stored in strategies[strategy].max_debt

When a debt rebalance is triggered, the Vault will cap the new target debt to this number (max_debt)
When a debt re-balance is triggered, the Vault will cap the new target debt to this number (max_debt)

#### Setting the deposit limit
The DEPOSIT_LIMIT_MANAGER is in charge of setting the deposit_limit for the vault
Expand All @@ -183,6 +183,11 @@ The PROFIT_UNLOCK_MANAGER is in charge of updating and setting the profit_max_un

This can be customized based on the vault based on aspects such as number of strategies, TVL, expected returns etc.

### Setting the default queue
The QUEUE_MANAGER has the option to set a custom default_queue if desired. The vault will arrange the default queue automatically based only on the order that strategies were added to the vault. If a different order is desired the queue manager role can set a custom queue.

All strategies in the default queue must have been previously added to the vault.

#### Buying Debt
The DEBT_PURCHASER role can buy debt from the vault in return for the equal amount of `asset`.

Expand Down Expand Up @@ -237,10 +242,10 @@ Shutdown mode does not affect accounting
### Debt rebalance
_Light emergency_: Setting minimumTotalIdle to MAX_UINT256 will result in the vault requesting the debt back from strategies. This would stop new strategies from getting funded too, as the vault prioritizes minimumTotalIdle

_Shutdown mode_: All strategies' maxDebt is set to 0. Strategies will return funds as soon as they can.
_Shutdown mode_: All strategies maxDebt is set to 0. Strategies will return funds as soon as they can.

### Relevant emergency
In the case the current roles stop fulfilling their responsibilities or something else's happens, the EMERGENCY_MANAGER can shutdown the vault.
In the case the current roles stop fulfilling their responsibilities or something else happens, the EMERGENCY_MANAGER can shutdown the vault.

The shutdown mode should be the last option in an emergency as it is irreversible.

Expand Down
52 changes: 41 additions & 11 deletions contracts/VaultFactory.vy
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@
@title Yearn Vault Factory
@license GNU AGPLv3
@author yearn.finance
@notice
This vault Factory can be used by anyone wishing to deploy their own
ERC4626 compliant Vault.
The factory uses the Blueprint (ERC-5202) standard to handle the
deployment of any new vaults off of the immutable address stored
at `VAULT_BLUEPRINT`. This allows the vaults to be deployed and
initialized fully on-chain with their init byte code, thus not
requiring any delegatecall patterns or post deployment initialization.
The deployments are done through create2 with a specific `salt`
that is dereived from a combination of the deployers address,
the underlying asset used, as well as the name and symbol specified.
Meaning a deployer will not be able to deploy the exact same vault
twice and will need to use different name and or symbols for vaults
that use the same other parameters such as `asset`.
The factory also holds the protocol fee configs for each vault and strategy
of its specific `API_VERSION` that determine how much of the fees
charged are designated "protocol fees" and sent to the designated
`fee_recipient`. The protocol fees work through rev share system,
where if the vault or strategy determines to charge X amount of total
fees during a `report` the protocol fees are X * fee_bps / 10_000.
The protocol fees will be sent to the designated fee_recipient and
then (X - protocol_fees) will be sent to the vault/strategy specific
fee recipient.
"""

from vyper.interfaces import ERC20
Expand Down Expand Up @@ -39,14 +65,15 @@ event NewPendingGovernance:
struct PFConfig:
# Percent of protocol's split of fees in Basis Points.
fee_bps: uint16
# Address for protocol fees to get paid to.
# Address the protocol fees get paid to.
fee_recipient: address

# The max amount the protocol fee can be set to.
MAX_FEE_BPS: constant(uint16) = 5_000
# Identifier for this version of the vault.
API_VERSION: constant(String[28]) = "3.0.1-beta"

# The max amount the protocol fee can be set to.
MAX_FEE_BPS: constant(uint16) = 5_000 # 50%

# The address that all newly deployed vaults are based from.
VAULT_BLUEPRINT: immutable(address)

Expand Down Expand Up @@ -83,16 +110,18 @@ def deploy_new_vault(
profit_max_unlock_time: uint256
) -> address:
"""
@notice Deploys a new vault
@param asset The asset to be used for the vault
@param name The name of the vault
@param symbol The symbol of the vault
@param role_manager The address of the role manager
@param profit_max_unlock_time The maximum time that the profit can be locked for
@return The address of the new vault
@notice Deploys a new vault base on the bLueprint.
@param asset The asset to be used for the vault.
@param name The name of the new vault.
@param symbol The symbol of the new vault.
@param role_manager The address of the role manager.
@param profit_max_unlock_time The time over which the profits will unlock.
@return The address of the new vault.
"""
# Make sure the factory is not shutdown.
assert not self.shutdown, "shutdown"

# Deploy the new vault using the blueprint.
vault_address: address = create_from_blueprint(
VAULT_BLUEPRINT,
asset,
Expand Down Expand Up @@ -132,7 +161,7 @@ def protocol_fee_config() -> PFConfig:
@notice Called during vault and strategy reports
to retreive the protocol fee to charge and address
to receive the fees.
@return The protocol fee config for the msg sender
@return The protocol fee config for the msg sender.
"""
# If there is a custom protocol fee set we return it.
if self.use_custom_protocol_fee[msg.sender]:
Expand Down Expand Up @@ -168,6 +197,7 @@ def set_protocol_fee_bps(new_protocol_fee_bps: uint16):
def set_protocol_fee_recipient(new_protocol_fee_recipient: address):
"""
@notice Set the protocol fee recipient
@dev Can never be set to 0 to avoid issuing fees to the 0 addresss.
@param new_protocol_fee_recipient The new protocol fee recipient
"""
assert msg.sender == self.governance, "not governance"
Expand Down
Loading

0 comments on commit 3e51c08

Please sign in to comment.