Vault.vy

Vault.vy

Functions

initialize

Parameters:

initialize

Parameters:

apiVersion

Return Values:

setName

Parameters:

setSymbol

Parameters:

setGovernance

Parameters:

acceptGovernance

setManagement

Parameters:

setGuestList

Parameters:

setRewards

Parameters:

setDepositLimit

Parameters:

setPerformanceFee

Parameters:

setManagementFee

Parameters:

setGuardian

Parameters:

setEmergencyShutdown

Parameters:

setWithdrawalQueue

Parameters:

transfer

Parameters:

Return Values:

transferFrom

Parameters:

Return Values:

approve

Parameters:

increaseAllowance

Parameters:

decreaseAllowance

Parameters:

permit

Parameters:

Return Values:

totalAssets

Return Values:

deposit

Parameters:

Return Values:

deposit

Parameters:

Return Values:

deposit

Parameters:

Return Values:

maxAvailableShares

Return Values:

withdraw

Parameters:

Return Values:

withdraw

Parameters:

Return Values:

withdraw

Parameters:

Return Values:

withdraw

Parameters:

Return Values:

pricePerShare

Return Values:

addStrategy

Parameters:

updateStrategyDebtRatio

Parameters:

updateStrategyRateLimit

Parameters:

updateStrategyPerformanceFee

Parameters:

migrateStrategy

Parameters:

revokeStrategy

Parameters:

revokeStrategy

Parameters:

addStrategyToQueue

Parameters:

removeStrategyFromQueue

Parameters:

debtOutstanding

Parameters:

Return Values:

debtOutstanding

Parameters:

Return Values:

creditAvailable

Parameters:

Return Values:

creditAvailable

Parameters:

Return Values:

expectedReturn

Parameters:

Return Values:

expectedReturn

Parameters:

Return Values:

report

Parameters:

Return Values:

sweep

Parameters:

sweep

Parameters:

Events

# Vault.vy

Yearn Token Vault

Yearn Token Vault. Holds an underlying token, and allows users to interact with the Yearn ecosystem through Strategies connected to the Vault. Vaults are not limited to a single Strategy, they can have as many Strategies as can be designed (however the withdrawal queue is capped at 20.) Deposited funds are moved into the most impactful strategy that has not already reached its limit for assets under management, regardless of which Strategy a user's funds end up in, they receive their portion of yields generated across all Strategies. When a user withdraws, if there are no funds sitting undeployed in the Vault, the Vault withdraws funds from Strategies in the order of least impact. (Funds are taken from the Strategy that will disturb everyone's gains the least, then the next least, etc.) In order to achieve this, the withdrawal queue's order must be properly set and managed by the community (through governance). Vault Strategies are parameterized to pursue the highest risk-adjusted yield. There is an "Emergency Shutdown" mode. When the Vault is put into emergency shutdown, assets will be recalled from the Strategies as quickly as is practical (given on-chain conditions), minimizing loss. Deposits are halted, new Strategies may not be added, and each Strategy exits with the minimum possible damage to position, while opening up deposits to be withdrawn by users. There are no restrictions on withdrawals above what is expected under Normal Operation. For further details, please refer to the specification: https://github.com/iearn-finance/yearn-vaults/blob/master/SPECIFICATION.md

## Functions

### initialize

```
function initialize(address,address,address,string,string)
```

Initializes the Vault, this is called only once, when the contract is deployed. The performance fee is set to 10% of yield, per Strategy. The management fee is set to 2%, per year. The initial deposit limit is set to 0 (deposits disabled); it must be updated after initialization.

If `nameOverride` is not specified, the name will be 'yearn' combined with the name of `token`. If `symbolOverride` is not specified, the symbol will be 'y' combined with the symbol of `token`.

#### Parameters:

NameTypeDescription* token ** ** The token that may be deposited into this Vault. ** governance ** ** The address authorized for governance interactions. ** rewards ** ** The address to distribute rewards to. ** nameOverride ** ** Specify a custom Vault name. Leave empty for default choice. ** symbolOverride ** ** Specify a custom Vault symbol name. Leave empty for default choice. ** guardian ** ** The address authorized for guardian interactions. Defaults to caller. *

### initialize

```
function initialize(address,address,address,string,string,address)
```

If `nameOverride` is not specified, the name will be 'yearn' combined with the name of `token`. If `symbolOverride` is not specified, the symbol will be 'y' combined with the symbol of `token`.

#### Parameters:

NameTypeDescription* token ** ** The token that may be deposited into this Vault. ** governance ** ** The address authorized for governance interactions. ** rewards ** ** The address to distribute rewards to. ** nameOverride ** ** Specify a custom Vault name. Leave empty for default choice. ** symbolOverride ** ** Specify a custom Vault symbol name. Leave empty for default choice. ** guardian ** ** The address authorized for guardian interactions. Defaults to caller. *

### apiVersion

```
function apiVersion()
```

Used to track the deployed version of this contract. In practice you can use this version number to compare with Yearn's GitHub and determine which version of the source matches this deployed contract.

All strategies must have an `apiVersion()` that matches the Vault's `API_VERSION`.

#### Return Values:

Description* API_VERSION which holds the current version of this contract. *

### setName

```
function setName(string)
```

Used to change the value of `name`. This may only be called by governance.

#### Parameters:

NameTypeDescription* name ** ** The new name to use. *

### setSymbol

```
function setSymbol(string)
```

Used to change the value of `symbol`. This may only be called by governance.

#### Parameters:

NameTypeDescription* symbol ** ** The new symbol to use. *

### setGovernance

```
function setGovernance(address)
```

Nominate a new address to use as governance. The change does not go into effect immediately. This function sets a pending change, and the governance address is not updated until the proposed governance address has accepted the responsibility. This may only be called by the current governance address.

#### Parameters:

NameTypeDescription* governance ** ** The address requested to take over Vault governance. *

### acceptGovernance

```
function acceptGovernance()
```

Once a new governance address has been proposed using setGovernance(), this function may be called by the proposed address to accept the responsibility of taking over governance for this contract. This may only be called by the proposed governance address.

setGovernance() should be called by the existing governance address, prior to calling this function.

### setManagement

```
function setManagement(address)
```

Changes the management address. Management is able to make some investment decisions adjusting parameters. This may only be called by governance.

#### Parameters:

NameTypeDescription* management ** ** The address to use for managing. *

### setGuestList

```
function setGuestList(address)
```

Used to set or change `guestList`. A guest list is another contract that dictates who is allowed to participate in a Vault (and transfer shares). This may only be called by governance.

#### Parameters:

NameTypeDescription* guestList ** ** The address of the `GuestList` contract to use. *

### setRewards

```
function setRewards(address)
```

Changes the rewards address. Any distributed rewards will cease flowing to the old address and begin flowing to this address once the change is in effect. This will not change any Strategy reports in progress, only new reports made after this change goes into effect. This may only be called by governance.

#### Parameters:

NameTypeDescription* rewards ** ** The address to use for collecting rewards. *

### setDepositLimit

```
function setDepositLimit(uint256)
```

Changes the maximum amount of tokens that can be deposited in this Vault. Note, this is not how much may be deposited by a single depositor, but the maximum amount that may be deposited across all depositors. This may only be called by governance.

#### Parameters:

NameTypeDescription* limit ** ** The new deposit limit to use. *

### setPerformanceFee

```
function setPerformanceFee(uint256)
```

Used to change the value of `performanceFee`. Should set this value below the maximum strategist performance fee. This may only be called by governance.

#### Parameters:

NameTypeDescription* fee ** ** The new performance fee to use. *

### setManagementFee

```
function setManagementFee(uint256)
```

Used to change the value of `managementFee`. This may only be called by governance.

#### Parameters:

NameTypeDescription* fee ** ** The new management fee to use. *

### setGuardian

```
function setGuardian(address)
```

Used to change the address of `guardian`. This may only be called by governance or the existing guardian.

#### Parameters:

NameTypeDescription* guardian ** ** The new guardian address to use. *

### setEmergencyShutdown

```
function setEmergencyShutdown(bool)
```

Activates or deactivates Vault mode where all Strategies go into full withdrawal. During Emergency Shutdown: 1. No Users may deposit into the Vault (but may withdraw as usual.) 2. Governance may not add new Strategies. 3. Each Strategy must pay back their debt as quickly as reasonable to minimally affect their position. 4. Only Governance may undo Emergency Shutdown. See contract level note for further details. This may only be called by governance or the guardian.

#### Parameters:

NameTypeDescription* active ** ** If true, the Vault goes into Emergency Shutdown. If false, the Vault goes back into Normal Operation. *

### setWithdrawalQueue

```
function setWithdrawalQueue(address[20])
```

Updates the withdrawalQueue to match the addresses and order specified by `queue`. There can be fewer strategies than the maximum, as well as fewer than the total number of strategies active in the vault. `withdrawalQueue` will be updated in a gas-efficient manner, assuming the input is well- ordered with 0x0 only at the end. This may only be called by governance or management.

This is order sensitive, specify the addresses in the order in which funds should be withdrawn (so `queue`[0] is the first Strategy withdrawn from, `queue`[1] is the second, etc.) This means that the least impactful Strategy (the Strategy that will have its core positions impacted the least by having funds removed) should be at `queue`[0], then the next least impactful at `queue`[1], and so on.

#### Parameters:

NameTypeDescription* queue ** ** The array of addresses to use as the new withdrawal queue. This is order sensitive. *

### transfer

```
function transfer(address,uint256)
```

Transfers shares from the caller's address to `receiver`. This function will always return true, unless the user is attempting to transfer shares to this contract's address, or to 0x0.

#### Parameters:

NameTypeDescription* receiver ** ** The address shares are being transferred to. Must not be this contract's address, must not be 0x0. ** amount ** ** The quantity of shares to transfer. *

#### Return Values:

Description* True if transfer is sent to an address other than this contract's or 0x0, otherwise the transaction will fail. *

### transferFrom

```
function transferFrom(address,address,uint256)
```

Transfers `amount` shares from `sender` to `receiver`. This operation will always return true, unless the user is attempting to transfer shares to this contract's address, or to 0x0. Unless the caller has given this contract unlimited approval, transfering shares will decrement the caller's `allowance` by `amount`.

#### Parameters:

NameTypeDescription* sender ** ** The address shares are being transferred from. ** receiver ** ** The address shares are being transferred to. Must not be this contract's address, must not be 0x0. ** amount ** ** The quantity of shares to transfer. *

#### Return Values:

Description* True if transfer is sent to an address other than this contract's or 0x0, otherwise the transaction will fail. *

### approve

```
function approve(address,uint256)
```

Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`. Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

#### Parameters:

NameTypeDescription* spender ** ** The address which will spend the funds. ** amount ** ** The amount of tokens to be spent. *

### increaseAllowance

```
function increaseAllowance(address,uint256)
```

Increase the allowance of the passed address to spend the total amount of tokens on behalf of msg.sender. This method mitigates the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

#### Parameters:

NameTypeDescription* spender ** ** The address which will spend the funds. ** amount ** ** The amount of tokens to increase the allowance by. *

### decreaseAllowance

```
function decreaseAllowance(address,uint256)
```

Decrease the allowance of the passed address to spend the total amount of tokens on behalf of msg.sender. This method mitigates the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. See https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729

#### Parameters:

NameTypeDescription* spender ** ** The address which will spend the funds. ** amount ** ** The amount of tokens to decrease the allowance by. *

### permit

```
function permit(address,address,uint256,uint256,bytes)
```

Approves spender by owner's signature to expend owner's tokens. See https://eips.ethereum.org/EIPS/eip-2612.

#### Parameters:

NameTypeDescription* owner ** ** The address which is a source of funds and has signed the Permit. ** spender ** ** The address which is allowed to spend the funds. ** amount ** ** The amount of tokens to be spent. ** expiry ** ** The timestamp after which the Permit is no longer valid. ** signature ** ** A valid secp256k1 signature of Permit by owner encoded as r, s, v. *

#### Return Values:

Description* True, if transaction completes successfully *

### totalAssets

```
function totalAssets()
```

Returns the total quantity of all assets under control of this Vault, whether they're loaned out to a Strategy, or currently held in the Vault.

#### Return Values:

Description* The total assets under control of this Vault. *

### deposit

```
function deposit()
```

Deposits `_amount` `token`, issuing shares to `recipient`. If the Vault is in Emergency Shutdown, deposits will not be accepted and this call will fail.

Measuring quantity of shares to issues is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On deposit, this means that shares are issued against the total amount that the deposited capital can be given in service of the debt that Strategies assume. If that number were to be lower than the "expected value" at some future point, depositing shares via this method could entitle the depositor to less than the deposited value once the "realized value" is updated from further reports by the Strategies to the Vaults. Care should be taken by integrators to account for this discrepancy, by using the view-only methods of this contract (both off-chain and on-chain) to determine if depositing into the Vault is a "good idea".

#### Parameters:

NameTypeDescription* _amount ** ** The quantity of tokens to deposit, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. *

#### Return Values:

Description* The issued Vault shares. *

### deposit

```
function deposit(uint256)
```

Measuring quantity of shares to issues is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On deposit, this means that shares are issued against the total amount that the deposited capital can be given in service of the debt that Strategies assume. If that number were to be lower than the "expected value" at some future point, depositing shares via this method could entitle the depositor to less than the deposited value once the "realized value" is updated from further reports by the Strategies to the Vaults. Care should be taken by integrators to account for this discrepancy, by using the view-only methods of this contract (both off-chain and on-chain) to determine if depositing into the Vault is a "good idea".

#### Parameters:

NameTypeDescription* _amount ** ** The quantity of tokens to deposit, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. *

#### Return Values:

Description* The issued Vault shares. *

### deposit

```
function deposit(uint256,address)
```

Measuring quantity of shares to issues is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On deposit, this means that shares are issued against the total amount that the deposited capital can be given in service of the debt that Strategies assume. If that number were to be lower than the "expected value" at some future point, depositing shares via this method could entitle the depositor to less than the deposited value once the "realized value" is updated from further reports by the Strategies to the Vaults. Care should be taken by integrators to account for this discrepancy, by using the view-only methods of this contract (both off-chain and on-chain) to determine if depositing into the Vault is a "good idea".

#### Parameters:

NameTypeDescription* _amount ** ** The quantity of tokens to deposit, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. *

#### Return Values:

Description* The issued Vault shares. *

### maxAvailableShares

```
function maxAvailableShares()
```

Determines the maximum quantity of shares this Vault can facilitate a withdrawal for, factoring in assets currently residing in the Vault, as well as those deployed to strategies on the Vault's balance sheet.

Regarding how shares are calculated, see dev note on `deposit`. If you want to calculated the maximum a user could withdraw up to, you want to use this function. Note that the amount provided by this function is the theoretical maximum possible from withdrawing, the real amount depends on the realized losses incurred during withdrawal.

#### Return Values:

Description* The total quantity of shares this Vault can provide. *

### withdraw

```
function withdraw()
```

Withdraws the calling account's tokens from this Vault, redeeming amount `_shares` for an appropriate amount of tokens. See note on `setWithdrawalQueue` for further details of withdrawal ordering and behavior.

Measuring the value of shares is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On withdrawal, this means that shares are redeemed against the total amount that the deposited capital had "realized" since the point it was deposited, up until the point it was withdrawn. If that number were to be higher than the "expected value" at some future point, withdrawing shares via this method could entitle the depositor to more than the expected value once the "realized value" is updated from further reports by the Strategies to the Vaults. Under exceptional scenarios, this could cause earlier withdrawals to earn "more" of the underlying assets than Users might otherwise be entitled to, if the Vault's estimated value were otherwise measured through external means, accounting for whatever exceptional scenarios exist for the Vault (that aren't covered by the Vault's own design.)

#### Parameters:

NameTypeDescription* maxShares ** ** How many shares to try and redeem for tokens, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. ** maxLoss ** ** The maximum acceptable loss to sustain on withdrawal. Defaults to 0.01%. *

#### Return Values:

Description* The quantity of tokens redeemed for `_shares`. *

### withdraw

```
function withdraw(uint256)
```

Measuring the value of shares is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On withdrawal, this means that shares are redeemed against the total amount that the deposited capital had "realized" since the point it was deposited, up until the point it was withdrawn. If that number were to be higher than the "expected value" at some future point, withdrawing shares via this method could entitle the depositor to more than the expected value once the "realized value" is updated from further reports by the Strategies to the Vaults. Under exceptional scenarios, this could cause earlier withdrawals to earn "more" of the underlying assets than Users might otherwise be entitled to, if the Vault's estimated value were otherwise measured through external means, accounting for whatever exceptional scenarios exist for the Vault (that aren't covered by the Vault's own design.)

#### Parameters:

NameTypeDescription* maxShares ** ** How many shares to try and redeem for tokens, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. ** maxLoss ** ** The maximum acceptable loss to sustain on withdrawal. Defaults to 0.01%. *

#### Return Values:

Description* The quantity of tokens redeemed for `_shares`. *

### withdraw

```
function withdraw(uint256,address)
```

Measuring the value of shares is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On withdrawal, this means that shares are redeemed against the total amount that the deposited capital had "realized" since the point it was deposited, up until the point it was withdrawn. If that number were to be higher than the "expected value" at some future point, withdrawing shares via this method could entitle the depositor to more than the expected value once the "realized value" is updated from further reports by the Strategies to the Vaults. Under exceptional scenarios, this could cause earlier withdrawals to earn "more" of the underlying assets than Users might otherwise be entitled to, if the Vault's estimated value were otherwise measured through external means, accounting for whatever exceptional scenarios exist for the Vault (that aren't covered by the Vault's own design.)

#### Parameters:

NameTypeDescription* maxShares ** ** How many shares to try and redeem for tokens, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. ** maxLoss ** ** The maximum acceptable loss to sustain on withdrawal. Defaults to 0.01%. *

#### Return Values:

Description* The quantity of tokens redeemed for `_shares`. *

### withdraw

```
function withdraw(uint256,address,uint256)
```

Measuring the value of shares is based on the total outstanding debt that this contract has ("expected value") instead of the total balance sheet it has ("estimated value") has important security considerations, and is done intentionally. If this value were measured against external systems, it could be purposely manipulated by an attacker to withdraw more assets than they otherwise should be able to claim by redeeming their shares. On withdrawal, this means that shares are redeemed against the total amount that the deposited capital had "realized" since the point it was deposited, up until the point it was withdrawn. If that number were to be higher than the "expected value" at some future point, withdrawing shares via this method could entitle the depositor to more than the expected value once the "realized value" is updated from further reports by the Strategies to the Vaults. Under exceptional scenarios, this could cause earlier withdrawals to earn "more" of the underlying assets than Users might otherwise be entitled to, if the Vault's estimated value were otherwise measured through external means, accounting for whatever exceptional scenarios exist for the Vault (that aren't covered by the Vault's own design.)

#### Parameters:

NameTypeDescription* maxShares ** ** How many shares to try and redeem for tokens, defaults to all. ** recipient ** ** The address to issue the shares in this Vault to. Defaults to the caller's address. ** maxLoss ** ** The maximum acceptable loss to sustain on withdrawal. Defaults to 0.01%. *

#### Return Values:

Description* The quantity of tokens redeemed for `_shares`. *

### pricePerShare

```
function pricePerShare()
```

Gives the price for a single Vault share.

See dev note on `withdraw`.

#### Return Values:

Description* The value of a single share. *

### addStrategy

```
function addStrategy(address,uint256,uint256,uint256)
```

Add a Strategy to the Vault. This may only be called by governance.

The Strategy will be appended to `withdrawalQueue`, call `setWithdrawalQueue` to change the order.

#### Parameters:

NameTypeDescription* strategy ** ** The address of the Strategy to add. ** debtRatio ** ** The share of the total assets in the `vault that the`strategy` has access to. ** rateLimit ** ** Limit on the increase of debt per unit time since last harvest ** performanceFee ** ** The fee the strategist will receive based on this Vault's performance. *

### updateStrategyDebtRatio

```
function updateStrategyDebtRatio(address,uint256)
```

Change the quantity of assets `strategy` may manage. This may be called by governance or management.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to update. ** debtRatio ** ** The quantity of assets `strategy` may now manage. *

### updateStrategyRateLimit

```
function updateStrategyRateLimit(address,uint256)
```

Change the quantity assets per block this Vault may deposit to or withdraw from `strategy`. This may only be called by governance or management.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to update. ** rateLimit ** ** Limit on the increase of debt per unit time since last harvest *

### updateStrategyPerformanceFee

```
function updateStrategyPerformanceFee(address,uint256)
```

Change the fee the strategist will receive based on this Vault's performance. This may only be called by governance.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to update. ** performanceFee ** ** The new fee the strategist will receive. *

### migrateStrategy

```
function migrateStrategy(address,address)
```

Migrates a Strategy, including all assets from `oldVersion` to `newVersion`. This may only be called by governance.

Strategy must successfully migrate all capital and positions to new Strategy, or else this will upset the balance of the Vault. The new Strategy should be "empty" e.g. have no prior commitments to this Vault, otherwise it could have issues.

#### Parameters:

NameTypeDescription* oldVersion ** ** The existing Strategy to migrate from. ** newVersion ** ** The new Strategy to migrate to. *

### revokeStrategy

```
function revokeStrategy()
```

Revoke a Strategy, setting its debt limit to 0 and preventing any future deposits. This function should only be used in the scenario where the Strategy is being retired but no migration of the positions are possible, or in the extreme scenario that the Strategy needs to be put into "Emergency Exit" mode in order for it to exit as quickly as possible. The latter scenario could be for any reason that is considered "critical" that the Strategy exits its position as fast as possible, such as a sudden change in market conditions leading to losses, or an imminent failure in an external dependency. This may only be called by governance, the guardian, or the Strategy itself. Note that a Strategy will only revoke itself during emergency shutdown.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to revoke. *

### revokeStrategy

```
function revokeStrategy(address)
```

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to revoke. *

### addStrategyToQueue

```
function addStrategyToQueue(address)
```

Adds `strategy` to `withdrawalQueue`. This may only be called by governance or management.

The Strategy will be appended to `withdrawalQueue`, call `setWithdrawalQueue` to change the order.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to add. *

### removeStrategyFromQueue

```
function removeStrategyFromQueue(address)
```

Remove `strategy` from `withdrawalQueue`. This may only be called by governance or management.

We don't do this with revokeStrategy because it should still be possible to withdraw from the Strategy if it's unwinding.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to remove. *

### debtOutstanding

```
function debtOutstanding()
```

Determines if `strategy` is past its debt limit and if any tokens should be withdrawn to the Vault.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to check. Defaults to the caller. *

#### Return Values:

Description* The quantity of tokens to withdraw. *

### debtOutstanding

```
function debtOutstanding(address)
```

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to check. Defaults to the caller. *

#### Return Values:

Description* The quantity of tokens to withdraw. *

### creditAvailable

```
function creditAvailable()
```

Amount of tokens in Vault a Strategy has access to as a credit line. This will check the Strategy's debt limit, as well as the tokens available in the Vault, and determine the maximum amount of tokens (if any) the Strategy may draw on. In the rare case the Vault is in emergency shutdown this will return 0.

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to check. Defaults to caller. *

#### Return Values:

Description* The quantity of tokens available for the Strategy to draw on. *

### creditAvailable

```
function creditAvailable(address)
```

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to check. Defaults to caller. *

#### Return Values:

Description* The quantity of tokens available for the Strategy to draw on. *

### expectedReturn

```
function expectedReturn()
```

Provide an accurate expected value for the return this `strategy` would provide to the Vault the next time `report()` is called (since the last time it was called).

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to determine the expected return for. Defaults to caller. *

#### Return Values:

Description* The anticipated amount `strategy` should make on its investment since its last report. *

### expectedReturn

```
function expectedReturn(address)
```

#### Parameters:

NameTypeDescription* strategy ** ** The Strategy to determine the expected return for. Defaults to caller. *

#### Return Values:

Description* The anticipated amount `strategy` should make on its investment since its last report. *

### report

```
function report(uint256,uint256,uint256)
```

Reports the amount of assets the calling Strategy has free (usually in terms of ROI). The performance fee is determined here, off of the strategy's profits (if any), and sent to governance. The strategist's fee is also determined here (off of profits), to be handled according to the strategist on the next harvest. This may only be called by a Strategy managed by this Vault.

For approved strategies, this is the most efficient behavior. The Strategy reports back what it has free, then Vault "decides" whether to take some back or give it more. Note that the most it can take is `gain + _debtPayment`, and the most it can give is all of the remaining reserves. Anything outside of those bounds is abnormal behavior. All approved strategies must have increased diligence around calling this function, as abnormal behavior could become catastrophic.

#### Parameters:

NameTypeDescription* gain ** ** Amount Strategy has realized as a gain on it's investment since its last report, and is free to be given back to Vault as earnings ** loss ** ** Amount Strategy has realized as a loss on it's investment since its last report, and should be accounted for on the Vault's balance sheet ** _debtPayment ** ** Amount Strategy has made available to cover outstanding debt *

#### Return Values:

Description* Amount of debt outstanding (if totalDebt > debtLimit or emergency shutdown). *

### sweep

```
function sweep(address)
```

Removes tokens from this Vault that are not the type of token managed by this Vault. This may be used in case of accidentally sending the wrong kind of token to this Vault. Tokens will be sent to `governance`. This will fail if an attempt is made to sweep the tokens that this Vault manages. This may only be called by governance.

#### Parameters:

NameTypeDescription* token ** ** The token to transfer out of this vault. ** amount ** ** The quantity or tokenId to transfer out. *

### sweep

```
function sweep(address,uint256)
```

#### Parameters:

NameTypeDescription* token ** ** The token to transfer out of this vault. ** amount ** ** The quantity or tokenId to transfer out. *

## Events

Transfer

- `sender` : address, indexed

- `receiver` : address, indexed

- `value` : uint256, notIndexed

Approval

- `owner` : address, indexed

- `spender` : address, indexed

- `value` : uint256, notIndexed

StrategyAdded

- `strategy` : address, indexed

- `debtRatio` : uint256, notIndexed

- `rateLimit` : uint256, notIndexed

- `performanceFee` : uint256, notIndexed

StrategyReported

- `strategy` : address, indexed

- `gain` : uint256, notIndexed

- `loss` : uint256, notIndexed

- `debtPaid` : uint256, notIndexed

- `totalGain` : uint256, notIndexed

- `totalLoss` : uint256, notIndexed

- `totalDebt` : uint256, notIndexed

- `debtAdded` : uint256, notIndexed

- `debtRatio` : uint256, notIndexed

UpdateGovernance

- `governance` : address, notIndexed

UpdateManagement

- `management` : address, notIndexed

UpdateGuestList

- `guestList` : address, notIndexed

UpdateRewards

- `rewards` : address, notIndexed

UpdateDepositLimit

- `depositLimit` : uint256, notIndexed

UpdatePerformanceFee

- `performanceFee` : uint256, notIndexed

UpdateManagementFee

- `managementFee` : uint256, notIndexed

UpdateGuardian

- `guardian` : address, notIndexed

EmergencyShutdown

- `active` : bool, notIndexed

UpdateWithdrawalQueue

- `queue` : address[20], notIndexed

StrategyUpdateDebtRatio

- `strategy` : address, indexed

- `debtRatio` : uint256, notIndexed

StrategyUpdateRateLimit

- `strategy` : address, indexed

- `rateLimit` : uint256, notIndexed

StrategyUpdatePerformanceFee

- `strategy` : address, indexed

- `performanceFee` : uint256, notIndexed

StrategyMigrated

- `oldVersion` : address, indexed

- `newVersion` : address, indexed

StrategyRevoked

- `strategy` : address, indexed

StrategyRemovedFromQueue

- `strategy` : address, indexed

StrategyAddedToQueue

- `strategy` : address, indexed


VaultAPI

VaultAPI

Functions

apiVersion

withdraw

token

strategies

creditAvailable

debtOutstanding

expectedReturn

report

revokeStrategy

governance

# VaultAPI

## Functions

### apiVersion

```
function apiVersion( ) external returns (string)
```

### withdraw

```
function withdraw( ) external returns (uint256)
```

### token

```
function token( ) external returns (address)
```

### strategies

```
function strategies( ) external returns (struct StrategyParams)
```

### creditAvailable

```
function creditAvailable( ) external returns (uint256)
```

View how much the Vault would increase this Strategy's borrow limit,
based on its present performance (since its last report). Can be used to
determine expectedReturn in your Strategy.

### debtOutstanding

```
function debtOutstanding( ) external returns (uint256)
```

View how much the Vault would like to pull back from the Strategy,
based on its present performance (since its last report). Can be used to
determine expectedReturn in your Strategy.

### expectedReturn

```
function expectedReturn( ) external returns (uint256)
```

View how much the Vault expect this Strategy to return at the current
block, based on its present performance (since its last report). Can be
used to determine expectedReturn in your Strategy.

### report

```
function report( ) external returns (uint256)
```

This is the main contact point where the Strategy interacts with the
Vault. It is critical that this call is handled as intended by the
Strategy. Therefore, this function will be called by BaseStrategy to
make sure the integration is correct.

### revokeStrategy

```
function revokeStrategy( ) external
```

This function should only be used in the scenario where the Strategy is
being retired but no migration of the positions are possible, or in the
extreme scenario that the Strategy needs to be put into "Emergency Exit"
mode in order for it to exit as quickly as possible. The latter scenario
could be for any reason that is considered "critical" that the Strategy
exits its position as fast as possible, such as a sudden change in
market conditions leading to losses, or an imminent failure in an
external dependency.

### governance

```
function governance( ) external returns (address)
```

View the governance address of the Vault to assert privileged functions
can only be called by governance. The Strategy serves the Vault, so it
is subject to governance defined by the Vault.


TestStrategy

TestStrategy

Functions

constructor

name

estimatedTotalAssets

prepareReturn

adjustPosition

liquidatePosition

prepareMigration

protectedTokens

# TestStrategy

## Functions

### constructor

```
function constructor( ) public
```

### name

```
function name( ) external returns (string)
```

### _takeFunds

```
function _takeFunds( ) public
```

### _toggleReentrancyExploit

```
function _toggleReentrancyExploit( ) public
```

### estimatedTotalAssets

```
function estimatedTotalAssets( ) public returns (uint256)
```

### prepareReturn

```
function prepareReturn( ) internal returns (uint256 _profit, uint256 _loss, uint256 _debtPayment)
```

### adjustPosition

```
function adjustPosition( ) internal
```

### liquidatePosition

```
function liquidatePosition( ) internal returns (uint256 _liquidatedAmount, uint256 _loss)
```

### prepareMigration

```
function prepareMigration( ) internal
```

### protectedTokens

```
function protectedTokens( ) internal returns (address[])
```


TestGuestList

TestGuestList

Functions

constructor

setGuests

Parameters:

authorized

Parameters:

# TestGuestList

A basic guest list contract for testing.

For a Vyper implementation of this contract containing additional
functionality, see https://github.com/banteg/guest-list/blob/master/contracts/GuestList.vy

## Functions

### constructor

```
function constructor( ) public
```

Create the test guest list, setting the message sender as
`bouncer`.

Note that since this is just for testing, you're unable to change
`bouncer`.

### setGuests

```
function setGuests( address[] _guests, bool[] _invited ) external
```

Invite guests or kick them from the party.

#### Parameters:

NameTypeDescription`_guests`address[]The guests to add or update.`_invited`bool[]A flag for each guest at the matching index, inviting oruninviting the guest.

### authorized

```
function authorized( address _guest, uint256 _amount ) external returns (bool)
```

Check if a guest with a bag of a certain size is allowed into
the party.

Note that `_amount` isn't checked to keep test setup simple, since
from the vault tests' perspective this is a pass/fail call anyway.

#### Parameters:

NameTypeDescription`_guest`addressThe guest's address to check.`_amount`uint256Not used. The amount of tokens the guest is bringing.


Token

Token

Functions

# Token

## Functions

### _setBlocked

```
function _setBlocked( ) public
```

### _beforeTokenTransfer

```
function _beforeTokenTransfer( ) internal
```


v1 Vaults Overview

v1 Vaults Overview

Protocol Contracts

Vaults

Controller

Registry

Strategies

Treasury

Governance

Vault management

Controller management

Strategy management

Protocol Actors

User

Keeper

Strategist

# v1 Vaults Overview

warning

This document describes the original implementation of Yearn's Vault and Governance systems. It gives a good sense of the bones of Yearn and is a place to build your intuition about how things work. These contracts are all mostly deprecated or superseded at this point, so if you are looking for information on actual implementations or to better understand the particulars of the current vaults, please review those specific docs.

This document gives a generalized and high level overview of how the protocol and its actors, smart contracts, and other services interact with each other. The aim is to build intuition about how Yearn products work.

info

All vaults are different. This is not a formal specification. Contracts and components are subject to change without notice.

![yearn-protocol](https://raw.githubusercontent.com/lehnberg/yearn-diagrams/master/yearn-protocol/yearn-protocol-v0.06.svg)

All contracts are open source and available from the /yearn-protocol (https://github.com/yearn/yearn-protocol) GitHub repo.

## Protocol Contracts

### Vaults

Example: yWETH.sol (https://github.com/yearn/yearn-protocol/blob/develop/contracts/vaults/yWETH.sol)

Vaults act as the representation of the user in the system, and is the internal customer for investments. There is one vault per deposit token, and they are agnostic to the strategies they interact with.

Their primary tasks are to:

- process user deposits and withdrawals, minting or burning LP tokens as receipts for these;

- manage disposable funds, ensuring there is enough to satisfy the minimum amount available to handle withdrawals, and issuing withdrawal requests from strategies when more funds need to be added; and

- deposit funds into strategies, when there is a surplus of funds in the vault above what's required to be kept at disposal.

### Controller

Controller.sol (https://github.com/yearn/yearn-protocol/blob/develop/contracts/controllers/Controller.sol)

The Controller act as the gatekeeping interface between vaults and strategies and oversees communication and fund flows. Deposits and withdrawals in and out of strategies flow through the `Controller`. It keeps track of the addresses for the active vaults, strategies, tokens, and strategy rewards destination, acting as a pseudo-registry that verifies the origin and destination of a transaction. The `Controller` also handles strategy migration, moving funds from an old strategy to a new one.

### Registry

YRegistry.sol (https://github.com/yearn/yearn-protocol/blob/develop/contracts/registries/YRegistry.sol)

The registry is a wrapper of the controller that contains additional meta-data about active addresses. Its functionality is currently being expanded.

### Strategies

Example: CurveYCRVVoter.sol (https://github.com/yearn/yearn-protocol/blob/develop/contracts/strategies/CurveYCRVVoter.sol)

Strategies are investment instruction sets, written by a `Strategist`. They are agnostic to the vaults that use them.

Strategies execute step-by-step functions with the objective to generate yield. They do so by interacting with:

- other Yearn services, such as vaults, lending, and insurance; and

- external 3rd party services, such as Aave, Curve, Chainlink and Maker.

Rewards are claimed and re-invested into the strategies, with deductions for Management fees and for compensating the `Strategist`.

### Treasury

The `Treasury` contract accumulates all the Management fees sent from the strategies. It's an intermediate contract that can convert between different tokens, currently normalizing all rewards into yCRV. It calls two functions:

- `toVoters()`, sending part of the fees to the governance voters, as a reward for their participation; and

- `toGovernance()`, sending part of the fees to the multi-sig to cover gas costs and other expenses.

### Governance

StrategyYFIGovernance.sol (https://github.com/yearn/yearn-protocol/blob/develop/contracts/strategies/StrategyYFIGovernance.sol)

Yearn Governance is a combination of the YFI staking contract to participate in Governance voting, and the 6-of-9 multi-sig that executes the decisions by the YFI holders.

Governance manages the `Vaults`, `Controller`, and `Strategies` by calling functions on these contracts.

#### Vault management

- Set governing address, through `setGovernance()`, in order to upgrade governance contracts.

- Set controller for the vault, through `setController()`, in order to upgrade controllers.

- Set amount of disposable funds at hand in vault, through `setMin()`, in order to manage how large withdrawal amounts require a Vault to issue a withdrawal request to a Strategy, via the Controller.

#### Controller management

- Set governing address, through `setGovernance()`, in order to upgrade governance contracts.

- Add vaults for the Controller to manage, through `setVault()`, in order to introduce new vaults.

- Set address to receive management fees, through `setRewards()` in order to upgrade the Treasury.

#### Strategy management

- Set Strategist address, through `setStrategist()`, in order for Strategists to receive their rewards and to interact with the system.

- Add an approved Strategy, through `approveStrategy()` on the Controller, in order for Strategists to be able to activate the Strategy in question.

- Remove an approved Strategy, through `revokeStrategy()` on the Controller, in order to prevent Strategists from being able to activate the Strategy in question.

## Protocol Actors

### User

A Yearn end-user.

- Deposits funds into vaults, to receive LP tokens, through calling `deposit()`;

- Withdraws funds from vaults, by depositing (effectively burning) LP tokens into vaults and receiving the corresponding deposit token amount back in return, through calling `withdraw()`. If the vault does not have enough funds to handle the withdrawal, this triggers a cascading `withdraw()` call via the `Controller` to the Strategy to liquidate enough funds to process the withdrawal.

### Keeper

Automated bot that calls contract functions. It queries the Registry to get the appropriate Vault and Strategy addresses and then calls:

- `earn()` on the Vault, which checks for funds available to be deposited into a Strategy and then deposits those.

- `harvest()` on the Strategy, which triggers the Strategy claim any rewards, pay management and Strategist fees, and re-invest the remainder into itself again.

### Strategist

Creates and manages Strategies.

- Interacts with the Controller to set the active strategy, through `setStrategy()`. Only Strategies approved by Governance can be set.

- Is paid the Strategist management fee directly from the Strategy.


v1 yVault Interfaces

v1 yVault Interfaces

IStrategy

function want()

function deposit()

function withdraw(address)

function withdraw(uint256)

function skim()

function withdrawAll()

function balanceOf()

IVault

function token()

function underlying()

function name()

function symbol()

function decimals()

func controller()

function governance()

function getPricePerFullShare()

function deposit()

function depositAll()

function withdraw()

function withdrawAll()

IController

function withdraw()

function balanceOf()

function earn()

function want()

function rewards()

function vaults()

function strategies()

# v1 yVault Interfaces

## IStrategy

Source code: yearn-protocol/develop/interfaces/yearn/IStrategy.sol (https://github.com/yearn/yearn-protocol/blob/develop/interfaces/yearn/IStrategy.sol)

### function want()

Returns the address of the unwrapped token that the Strategy takes as deposit.

```
function want() external view returns (address);
```

typedescOutput0addressAddress of the token the Strategy takes as deposit

### function deposit()

Deposits token (same as `want()` returns) into a smart contact specified by the Strategy.

```
function deposit() external;
```

### function withdraw(address)

Dust collecting function to create additional rewards out of tokens that were incorrectly sent to the Strategy.

Takes an ERC20 token address and should send the full amount of any such tokens in the Strategy to the Controller.

This function should have access control enforcing the Controller only to be its allowed caller, and checks in place to ensure that the token types to withdraw are not those used by the Strategy.

```
function withdraw(address) external;
```

typedescInput0addressERC-20 token to be drained

### function withdraw(uint256)

Partially withdraws funds (denominated in `want()` token) from the Strategy, and should always only be sending these to the Vault. In case the Strategy implements `harvest()`, a withdrawal fee may be applied. This function should have access control enforcing the Controller only to be its allowed caller.

```
function withdraw(uint256) external;
```

typedescInput0uintAmount to be withdrawn

### function skim()

Used to obtain the remaining amount that can be borrowed from the lending platform. Relevant when the Strategy implements a lending platform, such as Aave.

```
function skim() external;
```

### function withdrawAll()

Withdraws the entire amount of `want()` tokens available, and should always only be sending these to the Vault. This function should have access control enforcing the Controller only to be its allowed caller. Typically used when migrating strategies.

The function typically uses `withdraw()` and performs a set of sequential function calls depending on the Strategy.

If the Strategy implements liquidity pools or lending platforms, then withdrawal from these platforms should be performed until the Vault’s unwrapped token is delivered back to the vault.

Returns a `uint256` of the total amount withdrawn.

```
function withdrawAll() external returns (uint256);
```

typedescOutput0uint256The amount withdrawn

### function balanceOf()

Returns the Strategy's current `want()` token balance.

```
function balanceOf() external view returns (uint256);
```

typedescOutput0uint256Strategy's `want()` token balance

## IVault

Source code: yearn-protocol/develop/interfaces/yearn/IVault.sol (https://github.com/yearn/yearn-protocol/blob/develop/interfaces/yearn/IVault.sol)

### function token()

Returns the unwrapped native token address that the Vault takes as deposit.

```
function token() external view returns (address);
```

typedescOutput0addressVault’s unwrapped native token address

### function underlying()

Returns the native underlying token address in Delegated Vaults. For example, in case of aLINK delegated vault, `underlying()` returns the address of the LINK token.

```
// This is only implemented in Delegated Vaults.function underlying() external view returns (address);
```

typedescOutput0addressDelegated Vault’s underlying native token address

### function name()

Returns the vault’s wrapped token name as a string, e.g. “yearn Dai Stablecoin".

```
function name() external view returns (string memory);
```

typedescOutput0stringVault’s wrapped token name

### function symbol()

Returns the vault’s wrapped token symbol as a string, e.g. “yDai”.

```
function symbol() external view returns (string memory);
```

typedescOutput0stringVault’s wrapped token symbol

### function decimals()

Returns the amount of decimals for this vault’s wrapped token as a `uint8`.

```
function decimals() external view returns (uint8);
```

typedescOutput0uint8No of decimals of the vault's wrapped token.

### func controller()

Returns the address of the Vault's Controller.

```
function controller() external view returns (address);
```

typedescOutput0addressVault’s Controller contract

### function governance()

Returns the address of the Vault’s governance contract.

```
function governance() external view returns (address);
```

typedescOutput0addressVault’s Governance contract

### function getPricePerFullShare()

Returns the price of the Vault’s wrapped token, denominated in the unwrapped native token.

The calculation is:

nativeTokenBalanceyTokenTotalSupply\frac{nativeTokenBalance}{yTokenTotalSupply}yTokenTotalSupplynativeTokenBalance
Where nativeTokenBalance is the current balance of native token (e.g. DAI) in the Vault, Controller and Strategy contracts. And yTokenTotalSupply is the total supply of the Vault's wrapped Token (e.g. yDAI).

```
function getPricePerFullShare() external view returns (uint256);
```

typedescOutput0uint256Price of the Vault’s wrapped token denominated in the unwrapped native token

### function deposit()

Deposits the specified amount of the native unwrapped token (same as token() returns) into the Vault.

```
function deposit(uint256) external;
```

typedescInput0uint256Amount to deposit into the Vault.

### function depositAll()

Deposits the maximum available amount of the native unwrapped token (same as token() returns) into the Vault.

```
function depositAll() external;
```

### function withdraw()

Withdraws the specified amount of the native unwrapped token (same as token() returns) from the Vault.

```
function withdraw(uint256) external;
```

typedescInput0uint256Amount to withdraw from the Vault.

### function withdrawAll()

Withdraws the maximum available amount of the native unwrapped token (same as token() returns) from the Vault.

```
function withdrawAll() external;
```

## IController

Source code: yearn-protocol/develop/interfaces/yearn/IController.sol

### function withdraw()

Calls `Strategy.withdraw()` function for the amount defined in `unit256` in the Strategy of the specified address. This function should have access control enforcing the Vault to be its only allowed caller.

```
function withdraw(address, uint256) external;
```

typedescInput0addressAddress of the Strategy to withdraw fromInput1uint256Amount to withdraw

### function balanceOf()

Returns the Strategy's balance of the specified token.

```
function balanceOf(address) external view returns (uint256);
```

typedescInput0addressToken that is used in the StrategyOutput0uint256Balance of the specified token

### function earn()

Transfers the profits earned from the yield generating activities of the Strategy to the Vault. Takes an address of a token to withdraw and an amount.

```
function earn(address, uint256) external;
```

typedescInput0addressToken to be withdrawn to the Vault from the StrategyInput1uint256Amount to be withdrawn

### function want()

Not used by the currently deployed controller. Please refer to Strategy.want() (https://docs.yearn.fi/developers/smart-contracts/deprecated/V1/interfaces#function-want) instead.

```
function want(address) external view returns (address);
```

### function rewards()

Returns the address of the Treasury which is where the system reward fees go.

```
function rewards() external view returns (address);
```

typedescOutput0addressTreasury contract

### function vaults()

Takes a token address and returns the corresponding Vault address.

```
function vaults(address) external view returns (address);
```

typedescInput0addressToken to find a Vault address forOutput0addressVault address that is associated with the specified token

### function strategies()

Takes a token address and returns the corresponding Strategy address.

```
function strategies(address) external view returns (address);
```

typedescInput0addressToken to find a Strategy address forOutput0addressStrategy address that is associated with the specified token


Security Home

Security Home

Vulnerability disclosure process

Third-party audits

Security assumption

# Security Home

Information about Yearn's security processes, team members, disclosures, PGP keys and more can be found in the /yearn-security (https://github.com/yearn/yearn-security) repo on GitHub.

## Vulnerability disclosure process

Potential vulnerabilities are welcome to be disclosed following the guidelines established in /yearn-security/SECURITY.md (https://github.com/yearn/yearn-security/blob/master/SECURITY.md). Valid vulnerabilities may be eligible for bounty rewards.

## Third-party audits

The V3 core contracts used in V3 vaults, found at yearn-vaults-v3 (https://github.com/yearn/yearn-vaults-v3) repository have been audited by multiple independent third-party firms:

- StateMind (https://statemind.io/) has audited v3.0.0, public report available here (https://github.com/yearn/yearn-security/tree/master/audits/20240502_Statemind_Yearn_V3)

- ChainSecurity (https://www.chainsecurity.com/) has audited v3.0.0, public report available here (https://github.com/yearn/yearn-security/tree/master/audits/20240504_ChainSecurity_Yearn_V3)

- yAudit (https://yaudit.dev/) has audited v3.0.1, public report available here (https://github.com/yearn/yearn-security/tree/master/audits/20240601_YAcademy_Yearn_V3)

The legacy core contracts used in V2 vaults and the Factory Vaults, found at yearn-vaults (https://github.com/yearn/yearn-vaults/) repository have been audited by multiple independent third-party firms:

- MixBytes (https://mixbytes.io/) has audited v0.2.1, public report available here (https://github.com/yearn/yearn-security/tree/master/audits/202012_MixBytes_yearn-vaults)

- ChainSecurity (https://chainsecurity.com/) has audited v0.3.5, public report unavailable

- Trail of Bits (https://www.trailofbits.com/) has audited v0.4.2, public report available here (https://github.com/yearn/yearn-security/tree/master/audits/20210719_ToB_yearn_vaultsv2)

Yearn is much bigger than its core, the DAO has a rigorous review process for its contracts, and retains independent auditors which review Strategies and other protocol components.

Other public reports can be found under yearn-security/audits (https://github.com/yearn/yearn-security/tree/master/audits).

## Security assumption

Yearn as a protocol hinges on the critical assumption that the `Governance` role is honest. This role is currently controlled by a 6 of 9 Gnosis Safe multisig (https://gov.yearn.fi/t/yip-62-change-two-multisig-signers/10758).

A compromised or malicious Governance can cause catastrophic damage across the entire protocol.

It is a conscious design decision that this role is not behind a time lock. Priority is given to the ability to rapidly update and iterate on live vaults, strategies, and other components. Both so as not to advertise new investment strategies in advance, but also to rapidly improve our existing components without interruption. It also avoids downtimes whenever there is a bug or security vulnerability that needs to be fixed.

Trusting `Governance` to be honest is a prerequisite to trusting Yearn's vaults.

Modifications to these design decisions can be proposed in the forum through Yearn's governance process (https://gov.yearn.fi/t/yip-61-governance-2-0/10460).


Testing

Testing

Best Practices

General Resources

Fuzzing and Invariant Test Resources

# Testing

It is best practice for smart contracts planned to be deployed to production to be thoroughly tested. This is especially true for smart contracts that handle user funds. A good functioning test suite is highly encouraged before sending your smart contract for security review or audits.

## Best Practices

- Test coverage of 100% is not required, but it is encouraged. The more coverage, the more confidence in the code.

- Unit tests should be written for all state-changing functions, view functions, and modifiers. Using mocks and stubs is recommended for faster testing.

- Integration tests should be written for all functions interacting with other contracts and main use cases covering the user interactions with the smart contract. Should include tests for all possible failure scenarios.

- It is recommended to have complete testing coverage on the failure scenarios of your smart contracts. As a rule of thumb the failure scenarios should have more tests than the happy paths.

- Fuzz tests should be written for all functions that handle user funds. Fuzz tests should be run on a fork of mainnet to ensure the smart contract behaves as expected in a production environment with as many inputs and states.

- Invariant tests or property tests are recommended to document and write down the important invariants your smart contract should hold in all states and validate the contract handles as expected.

- A good CI pipeline is recommended to run all tests on every commit and pull request. This ensures the code is always tested and no new code is merged without passing all tests.

## General Resources

- Testing Smart Contracts (https://ethereum.org/en/developers/docs/smart-contracts/testing)

- Writing Tests in Foundry (https://book.getfoundry.sh/forge/writing-tests)

- Foundry cheat codes (https://book.getfoundry.sh/forge/cheatcodes)

- Foundry Fork Testing (https://book.getfoundry.sh/forge/fork-testing)

- Testing with ape framework (https://docs.apeworx.io/ape/stable/userguides/testing.html)

## Fuzzing and Invariant Test Resources

Links:

- You’re Writing Require Statements Wrong (https://www.nascent.xyz/idea/youre-writing-require-statements-wrong)

- Invariant Testing Solidity (https://www.rareskills.io/post/invariant-testing-solidity)

- Exploiting Precision Loss via Fuzz Testing (https://dacian.me/exploiting-precision-loss-via-fuzz-testing)

- Foundry Fuzzing (https://book.getfoundry.sh/forge/fuzz-testing)

- Foundry Invariant Testing (https://book.getfoundry.sh/forge/invariant-testing)

Videos:

- Intro to Fuzz and Invariant Testing (https://www.youtube.com/watch?v=juyY-CTolac&t=300s)

- Invariant Testing Workshop (https://www.youtube.com/watch?v=YAF79t_Sfiw)

- TOB Playlist on Echidna (https://www.youtube.com/watch?v=QofNQxW_K08&list=PLciHOL_J7Iwqdja9UH4ZzE8dP1IxtsBXI) (helps think about testing invariants and also fuzzing)


Understanding The Risks

Understanding The Risks

Making Money Requires Risk

Rug Risk

Bug Risk

Yield Stack Risk

The Bottom Line

# Understanding The Risks

info

The Yearn smart contracts, interfaces, and products are offered as-is. Yearn contributors and YFI token holders provide no guarantee of safety of funds in ANY vault or strategy built on top of the core contracts and will not compensate users for any critical failure or loss of funds resulting from usage of the system.

Hello anon. You've made it this far and now it's time to have a little chat about risk. Understanding risk is the most important element in not getting Rekt. If you are new to cryptocurrency, hopefully this page will help you better understand the space and how things can go wrong. And if you are a grizzled degen, well... a refresher never hurts.

If you are investing money (even imaginary internet money) then it is important to understand what could go wrong. We aren't going to talk about personal security or how to secure private keys, but instead talk about how you can lose money even if you do everything right, and how Yearn tries to mitigate these risks. The later pages in this section go into the specifics, but we will start broad.

## Making Money Requires Risk

To "beat the market" you must take some risk. This is why the term risk-free rate exists. A risk-free rate is the safest return you can get on your capital, and even so the term is a misnomer. It is just the consensus lowest risk investment that you can find. Any time you see a juicy yield there is some risk! This may be price risk, smart contract risk, liquidation risk, etc. Yearn is built to minimize that risk and maximize convenience and returns. But minimize and eliminate are not the same thing. So let's explore these risks.

## Rug Risk

This is the risk that you get scammed and the money you invested is stolen or re-appropriated. Think FTX. This is where Yearn (and DeFi) really shines. Yearn Vaults are built in a way such that only you have access to the funds you deployed in a vault. The vaults collect yield and re-deposit it permissionlessly. The Yearn Multisig (https://docs.yearn.fi/developers/security/multisig) does have the power to pause or withdraw funds from strategies to protect depositors, but the funds cannot be removed. When you deposit, you get shares of the vault that you can always use to get a proportional amount of vault assets back. Yearn or its contributors have no ability to mint new shares other than by depositing their own funds. Yearn operates not on a principle of "don't be evil", but of "can't be evil".

## Bug Risk

Eliminating rug risk doesn't remove the risk that something, somewhere isn’t implemented right and leads to an exploit. Yearn takes security very seriously and strives to be as safe as possible with audits and best practices. Yearn is seen as a leader in security practices and the auditing firm yAUDIT spun out of Yearn. But even if all of Yearn's vaults are totally safe, they are only as safe as the strategies and protocols that they deposit into.

## Yield Stack Risk

Yearn Vaults are a tool to optimize yield and auto-compound it, so they inherit the risk of the underlying protocols they earn yield from. On top of creating safe smart contract code, Yearn contributors work to evaluate the risks of the different protocols and strategies used in vaults. You can explore Yearn's risk scores and how different vaults rate by visiting their respective pages on yearn.fi (https://yearn.fi). Strategies are chosen and approved based on available information, and that information isn't always complete. Sometimes shit happens. A freak event may cause a stablecoin to depeg. A protocol may have an incredible and safe codebase, but due to a physical security or process breach, suffer an exploit.

Yearn has developed, and continually works on improving, monitoring and risk analysis tools to prevent any losses.

## The Bottom Line

Yearn is a tool that makes earning yield on your assets easy. It has risks but, for the most part, those are the same risks you would take on if you did the same farming on your own. By depositing in Yearn vaults, you are relying on the creator of the strategies/vaults to manage that risk and provide that service to you. Any losses or gains within a vault are socialized across all depositors in that vault. The strategists and contributors at Yearn use the vaults too and so we have every incentive to make them as safe and profitable as possible.

In the end, you have to make this decision yourself. No one can decide for you whether something is safe enough. The next pages in this section may be useful in better understanding these risks and making the best decision for you.


Vault Risks

Vault Risks

# Vault Risks

Yearn’s vaults can be exposed to multiple strategies. Each additional strategy increases diversification but also increases the probability that a strategy could lead to capital losses.

RiskDescriptionGovernanceMulti-sig approves a strategy that leads to lossesTechnologicalSmart contract risks increase with the number of strategies and protocolsMarketLiquidation of leveraged strategies due to sudden price fallsLower token prices lead to lower yields in naked liquidity mining strategiesHigh gas fees to deposit or withdraw adversely impact yieldHigh gas fees cause yield on strategies to be less than expectedDeposits too low to benefit from multiple strategiesOperationalOptimal mix of strategies not maintainedLiquidations because debt positions were managed incorrectlyYearn Security Team interprets code incorrectly in new yield farmOracleIncorrect price feed leads to liquidation in leveraged strategy


Strategy Risks

Strategy Risks

Lending

Liquidity Mining

Trading Fees

Leverage

# Strategy Risks

Yearn earns income from lending, liquidity mining and trading fees. This income is often increased using leverage.

## Lending

Collateralized lending is when an asset is lent in return for a yield paid by the borrower. The borrower has to lock up a greater amount of collateral than the value of the loan to incentivize the repayment of the loan.

RiskDescriptionGovernanceAdmin key holders change lending protocol adversely, e.g. change the interest rate model in such a way that discourages borrowingTechnologicalSmart contract risk of interacting with lending protocolsMarketLow demand for borrowing the asset causes low lending yieldsCollateral price falls causing the lending protocol to become undercollateralizedLent assets become unavailable to withdraw because the utilization ratio becomes too highOperationalDelays or inability to withdraw assets from the lending protocol in an emergency

## Liquidity Mining

Liquidity mining involves interacting with a protocol to earn the protocol’s native tokens.

RiskDescriptionGovernanceAdmin key holders change protocol adversely, e.g. introduce penalties for withdrawalsTechnologicalSmart contract risk of rewards contractSmart contract risk of AMM used to exchange the liquidity mined token for the Want tokenMarketFall in price of token being farmedLiquidity of liquidity mined token on AMM is reduced or removedOperational RiskDelays or inability to withdraw liquidity in an emergency

## Trading Fees

Trading fees are earned in Automated Market Makers (AMMs) by providing liquidity.

RiskDescriptionGovernanceAdmin key holders change protocol adversely, e.g. reduce rewards paid to liquidity providersTechnologicalSmart contract risk of AMM (e.g. Curve Finance, Sushiswap or Uniswap)MarketTrading volumes reduce leading to lower feesImpermanent lossImpermanent loss (https://academy.binance.com/en/articles/impermanent-loss-explained) due to the pool’s token prices changing relative to each otherOperational RiskDelays or inability to withdraw liquidity from the AMM in an emergency

## Leverage

RiskDescriptionGovernanceAdmin key holders change the lending protocol adverselyTechnologicalSmart contract risk of lending protocol (Aave, Compound Finance, Maker, Unit protocol)MarketRisk that the debt is liquidated due to a price fallRisk that income is lower than the cost of the flash loanOracleIncorrect price feedliquidation penaltiesOperational RiskOperational risk of managing debt positions

These factors are all taken into account by the Yearn Security Team when scoring strategies using the Risk Score Framework (https://docs.yearn.fi/developers/security/risks/risk-score).


Risk Scores

Risk Scores

Strategy Risk Score

Audit

Code Review

Complexity

Longevity

Protocol Safety

Team Knowledge

Testing Score

TVL Impact

Vault Risk Score Proposal

Overall Risk Score Proposal

# Risk Scores

Yearn works with risk scores to quantify and assess the amount of risk of each strategy and vault. This document outlines how we measure risk vectors and use them to find the optimal balance of security and innovation.

- Strategy Risk Score (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#strategy-risk-score) defines each dimension of risk for a strategy and how we quantify them

- Vault Risk Score Proposal (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#vault-risk-score-proposal) aggregates all strategy scores for a vault, averaging by TVL (this is in draft stage)

- Overall Risk Score Proposal (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#overall-risk-score-proposal) aggregates strategy/vault scores into overall scores (this is in draft stage)

Different risk scores for all V2 vaults can be viewed on the Seafood (https://seafood.yearn.watch/risk) Dashboard.

## Strategy Risk Score

Risk for different strategies is quantified using a 1-5 point system developed by Yearn's strategy deployment process. The higher the risk score number, the more risky the strategy is. The risk assessment evaluates eight dimensions:

- Audit (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#audit)

- Code Review (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#code-review)

- Complexity (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#complexity)

- Longevity (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#longevity)

- Protocol Safety (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#protocol-safety)

- Team Knowledge (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#team-knowledge)

- Testing Score (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#testing-score)

- TVL Impact (https://docs.yearn.fi/developers/security/risks/risk-score-legacy#tvl-impact)

This risk framework is an ongoing process to ensure the security of Yearn strategies. Yearn recognized that, due to its unique approach to deploying strategies, it could not rely on a traditional waterfall process (heavy analysis and design, testing, multiple audits before release, etc.) to deploy contracts. Strategies are deployed and capped by their risk score. As we reduce the risk in any of the eight dimensions, the strategy can grow its TVL. This system allows Yearn to compare the risk score of two strategies and prioritize risk mitigation and preventive actions, such as forming a committee to spread knowledge on the code, getting more audits, migrating current code to improved versions of the strategy, etc.

The current version of the risk score system works for Yearn's current needs, but we are always looking to improve and expand it to the vaults. We want to provide our users with a better understanding of what is happening behind the scenes in the vaults. The development of vault risk scoring is still in progress!

### Audit

Auditing is a process that an audit firm or external security researcher reviews code for any potential vulnerabilities and present a report for mitigation. Audits take longer than an internal security review and are not immediately available due to the high demand for audits in the space. As such, most strategies are sent to production without an audit (leading to a high risk score) in order to limit their Total Value Locked (TVL). This approach allows for strategies to be validated in production while still managing risk, and the risk score helps determine which strategies should get an audit first, based on impact and other scoring criteria. The table below outlines the scoring criteria associated with audits.

ScoreAudit5No audit by a trusted firm or security researcher.4Audit by trusted firm or security researcher conducted more than 6 months ago.3Audit by trusted firm or security researcher conducted more than 3 months ago.2Audit conducted less than 3 months ago by an independent trusted firm.1Audit conducted less than 3 months ago by 3 or more independent trusted firms.

### Code Review

This is the process that reviews strategy code going to production. It is done in two major phases:

Phase 1: Two internal peers (strategists) review the strategy for any potential issues regarding handling accounts, profits, losses, etc. After this phase is completed, the strategy can go to ape.tax for live testing and validation.

Phase 2: An internal security reviewer from Yearn will review the code focusing on security concerns. Once phase 2 is completed, the strategy gets a risk score in all dimensions and is usually deemed enough for a strategy to go to production with limited TVL based on scoring.

After these steps a recurring review is scheduled, where either a second either internal or external security reviewer will have another look at the code:

ScoreCode Review50 - 1 reviewer of the code only or most recent was done 6 months+ ago42 reviewers of the code, the most recent of which was done 3+ months ago33 reviewers of the code, the most recent of which was done 3+ months ago (1 of the reviewers is an internal security dev)24 reviewers of the code (2 peers and 2 internal security devs)15 reviewers of the code, (2 strategists peers and 2 security reviewers and either external protocol devs reviewed or external security researchers reviewed)

### Complexity

This is how the strategy earns its returns: is it a simple strategy like a masterchef staking or does it have complex mechanics such as leverage, risk of liquidation, and involvement with multiple protocols? The more components it needs will require a higher complexity score. This score is essential in an emergency to evaluate how difficult it is to mitigate a live issue:

ScoreComplexity5Strategy is highly complex, uses leverage or debt, and is not easy to unwind. No health check available4Uses leverage or debt, and is not easy to unwind. No health check available3Has potential for losses, withdrawal fees, or requires detailed queue management to prevent losses. No health check available2Strategy is relatively simple, and is easy to migrate/unwind. Has a health check1Strategy is easy to understand, and can be migrated/unwound easily. No leverage and no publicly accessible methods. Highly unlikely to incur losses.

### Longevity

How long the strategy has been running live on yearn.fi:

ScoreLongevity5Code is new and did not go to ape tax before going live on yearn.fi4Code has been running for less than one month3Code has been running between 1-4 months2Code has been running for 4+ months1Code has been running for 8+ months with no critical issues and no changes in code base

### Protocol Safety

Protocol Safety evaluates the resilience of the protocol the strategy uses. It takes into account the safety measures given the current DeFi security standards, based on our internal assessments and due diligence compared to the top projects in DeFi. This includes multisig health, decentralization, bounty programs, audits, etc.

We hope to improve this dimension with the help of the DeFi community to potentially use a standard scoring system that is widely accepted in the ecosystem to replace our current scoring table:

ScoreProtocol Safety5No due diligence (DD) document for this strategy. The protocol contracts used are very recent and not audited/verified. An EOA (externally owned account) owns the contracts and can upgrade them. 4DD took place. Protocol contracts audited/verified. A multisig is required or contracts are upgradable. Multisig has a low threshold of signers. No bounty program.3DD took place. Protocol contracts are audited/verified by at least one reputable audit firm. A multisig with an appropriate threshold is required and/or contracts are immutable. Has a good bounty program.2DD took place. Protocol contracts are audited/verified by at least two reputable audit firms. A multisig with an appropriate threshold is required and/or contracts are immutable. Has a good bounty program.1Protocols involved in contracts are trusted blue chip protocols with a good track record of security. For example: Maker, Uniswap, Curve, AAVE, and Compound. These protocols meet all the criteria specified in item 2 and more.

### Team Knowledge

Measures the amount of expertise on a strategy that is shared amongst Yearn contributors. How many contributors can manage the strategy and respond in an emergency? The fewer people who can manage and respond during an emergency the riskier the strategy assessment in this dimension:

ScoreTeam Knowledge51 person in the team is the only one that has in-depth knowledge of the strategy code41 strategist has in-depth knowledge, and 1 strategist is somewhat familiar with the strategy code.32 strategists have in-depth knowledge of the strategy code.22 strategists have in-depth knowledge, and 1 strategist is somewhat familiar with the strategy code.1A team of 3+ strategists are very familiar with the strategy code and the protocol the strategy is utilising.

### Testing Score

Testing score is a metric of how much of the codebase for the strategy has been tested. It uses the test coverage number as a reference, higher coverage means the developer/strategist took time to test most of the operations of the strategy in a unit test or fork environment. This score assumes that a less tested strategy entails more risk since we know less about what is expected from the code:

ScoreTesting Score5Less than 20% coverage in testing4Less than 40% coverage in testing340% to 80% coverage2Over 80% coverage1Over 90% coverage in testing. Second developer validated and added tests and also added new ones for uncovered cases while reviewing. You can pull the repository and the tests are currently passing

### TVL Impact

The TVL (total value locked) metric measures how to allocate to new riskier strategies without having a catastrophic event in case of a hack or issue. The lower the impact, the more likely Yearn’s treasury can recover from an incident. The TVL is measured in USD and grows dynamically based on strategies allocations onchain. Through seafood (https://seafood.yearn.watch/risk) we keep track of the TVL and risk score to make fund allocation decisions and mitigations if a strategy group has fallen into the “red” high-risk zone:

ScoreTVL Impact5Extreme: greater than USD 100 MM4Very high: less than USD 100 MM3High: less than USD 50 MM2Medium: less than USD 10 MM1Low: less than USD 1 MM

## Vault Risk Score Proposal

A vault is a contract that holds funds for up to 20 strategies, the vault risk score is a TVL weighted average for each active strategy, for example:

Strategy X has 5000∗∗fundsdeposited∗∗StrategyY∗∗has∗∗1000** funds deposited
**Strategy Y** has **1000∗∗fundsdeposited∗∗StrategyY∗∗has∗∗1000 funds deposited

This vault's risk score would be calculated as follows:

```
( (Strategy X risk) * 5000 + (Strategy Y risk) * 1000)÷6000
```

## Overall Risk Score Proposal

Risks on some projects may have more relevance than others, so before calculating the overall score we first define the weight for the context we want to apply the framework on, and then we do a weighted average between all risk dimensions and risk profiles:

Risk Profile = Weighted table of which risk dimension is more important given the current context
Risk Score = Weighted average of all 8 dimensions using the risk profile weights

A project may have many risk profiles, so for each profile the score is calculated and the final list that remains is then used with medians to reach the final result.

The projects overall risk score will be presented in 3 variables:

- high: profile score for a risk-averse user

- low: profile score for a risk-seeking user

- median: profile score for a median representative user

Where each one of these use the final list median:

- high: median + 1.5 IQR

- low: median - 1.5 IQR

- median: the median value from the distribution

Where IQR stands for the interquartile range of the distribution

Here is what the final result looks like:

```
{ 'overallScore': { 'high': 3.37675585284281, 'low': 2.5463210702341135, 'median': 2.9615384615384617, },}
```


Yearn Risk Score Framework

Yearn Risk Score Framework

Overall riskLevel

Strategy Related Scores

review

testing

complexity

riskExposure

centralisationRisk

protocolIntegration

External Protocol Related Scores

externalProtocolAuditing

externalProtocolCentralisation

externalProtocolTvl

externalProtocolLongevity

externalProtocolType

comment

Defining risk scores for the strategy

# Yearn Risk Score Framework

Risk scores are separated into two categories: strategy-related and external protocol-related.

Strategy-related scores are intended to focus solely on the strategy implementation. While there may be indirect exposure to external protocols when evaluating these scores, the primary focus is on the strategy implementation itself.

External protocol-related scores directly target external protocols. While the strategy-related scores indirectly reference the external protocol, the responses are not directly related to the external protocol itself. Conversely, these scores fully concentrate on the external protocol.

In the case of multiple external protocols integrated with a strategy, each external protocol should be evaluated according to the risk scores, and the average will be the final score. For example, if a strategy involves depositing DAI to CurveLP and staking it in Convex, then both Convex and Curve should be evaluated accordingly.

All scores are intended to be filled objectively, so the metrics are chosen as objectively as possible. However, due to the uncertainty of potential strategies and external protocols, the Yearn security team can make exceptions and assign scores that do not strictly adhere to the scoring framework. In such cases, every score type has an optional text box, which the Yearn security team fills out to justify why the score is given as it is.

To assign scores, certain information is required, such as testing coverage and external protocol audits. This information should be initially provided by the strategist who writes the strategy, and then the Yearn security team will double-check whether the supplied information is correct or missing.

## Overall riskLevel

`riskLevel` is used to define the final risk score of the strategy. The `riskLevel` for the strategy is calculated by summing all risk scores below and check the following table:

- 10-20 -> 1

- 21-30 -> 2

- 31-40 -> 3

- 41+ -> 4

Yearn V3 vaults can be single-strategy or multi-strategy vaults. The risk score for the vault will be calculated as follows:

- single-strategy (https://github.com/yearn/ydaemon/blob/6797a0246ba13ac3e8b78f8b9a54b12e8500d603/data/meta/vaults/1.json#L13374): riskScore is used to define final riskLevel

- multi-strategy (https://github.com/yearn/ydaemon/blob/6797a0246ba13ac3e8b78f8b9a54b12e8500d603/data/meta/vaults/1.json#L2606): riskLevel is defined by the highest riskLevel value of all strategies in the vault. Typically, vaults are constructed to only allow strategies at or below a specific risk level. So the USDC-2 vault could only have -2 or -1 level strategies attached to it, while the USDC-1 vault could only have -1 strategies attached to it.

## Strategy Related Scores

### review

To have a unified reviewScore for both internal and external strategies, we assume that the strategist writer itself is either a Source of Trust (internal) or not (external). So all internal strategies always includes that 1 additional source of trust in addition.
Together with all other Sources of Trust (SoTs) in this list:

- internal strategist wrote the strategy

- peer reviews

- expert peer reviews

- Yearn security team security reviews

- Yearn security team recurring security review

each item accounts for 1 SoT point, and any combinations of these gives the number of SoTs a strategy has and thus gives the associated review score:

- 5 -> 1 SoT

- 4 -> 2 SoT

- 3 -> 3 SoT

- 2 -> 4 SoT

- 1 -> 5 SoT

### testing

The testing coverage of the strategy being evaluated. Note that there are no intermediate scores for this score. The reason is to incentivise strategists to aim for at least 80% testing coverage.

- 1 -> 95%+

- 2 -> 90%+

- 3 -> 80%+

- 4 -> 70%+

- 5 -> below 70%

### complexity

The sLOC count of the strategy being evaluated. Note that the strategy can be complex regardless of the sLOC. In such cases, the Yearn security team will provide the justification reason for the score by text if needed.

- 5 -> 600+ sLOC

- 4 -> 450-600 sLOC

- 3 -> 300-450 sLOC

- 2 -> 150-300 sLOC

- 1 -> 0-150 sLOC

### riskExposure

This score aims to find out how much and how often a strategy can be subject to losses. Due to the nature of evaluating such hard metrics, the Yearn security team will provide the justification reason for the score by text if needed.

- 5 -> Loss of funds or non recoverable funds 30%+ (Example, Leveraging cross assets and got liquidated, adding liquidity to volatile pairs single sided)

- 4 -> Loss of funds or non recoverable funds 10-30% (Example, adding liquidity to single sided curve stable pools)

- 3 -> Loss of funds or non recoverable funds 3-10% (Example, Protocol specific IL exposure, very high deposit/withdrawal fees)

- 2 -> Loss of funds or non recoverable funds 0-3% (Example, deposit/withdrawal fees or anything protocol specific)

- 1 -> Strategy has no lossable cases, only gains, up only.

### centralisationRisk

The centralization score of the strategy that is being evaluated. Measures the strategy's reliance on privileged roles that are defined in strategy.

- 5 -> Strategy heavily relies on off-chain management, potentially exposing user funds to rug possibilities by admins.

- 4 -> Strategy frequently depends on off-chain management but has safeguards against rug possibilities by admins.

- 3 -> Strategy involves privileged roles but less frequently and with less risk of rug possibilities.

- 2 -> Strategy has privileged roles but they are not vital for operations and pose minimal risk of rug possibilities.

- 1 -> Strategy operates without dependency on any privileged roles, ensuring full permissionlessness.

### protocolIntegration

The protocols that are integrated into the strategy that is being evaluated.
For example:
If the strategy's underlying asset is DAI and deposits it to Curve LP and stakes the LP in Convex, then there are 2 external protocols integrated.
Note:
Protocols used only in swapping or getting reference value that are not critical to how the strategy works are not added here. For example: UniswapV3Swapper is not counted as an external protocol.

- 5 -> Strategy interacts with 5 external protocols

- 4 -> Strategy interacts with 4 external protocols

- 3 -> Strategy interacts with 3 external protocols

- 2 -> Strategy interacts with 2 external protocols

- 1 -> Strategy interacts with 1 external protocol

## External Protocol Related Scores

In case there are multiple external protocols integrated with strategy, then each external protocol should be evaluated according to the risk scores and the average will be the final score. For example: If strategy is depositing DAI to CurveLP and stakes it in Convex, then both Convex and Curve should be evaluated accordingly.

### externalProtocolAuditing

The public audits count of the external protocols.

- 5 -> No audit conducted by a trusted firm or security researcher.

- 4 -> Audit conducted by 1 trusted firm or security researcher conducted

- 3 -> Audit conducted by 2 trusted firm or security researcher conducted

- 2 -> Audit conducted by 3 trusted firm or security researcher conducted

- 1 -> Audit conducted by 4 or more trusted firm or security researcher conducted

### externalProtocolCentralisation

Measurement of the centralization score of the external protocols.

- 5 -> Contracts owner is an EOA or a multisig with less than 4 members `OR` Contracts are not verified `OR` Contracts owner can harm our strategy completely

- 4 -> Contracts owner is a multisig but the addresses are not known/hidden `OR` Contracts owner can harm our strategy by setting parameters in external protocol contracts up to some degree

- 3 -> Contracts owner is a multisig with known people but multisig threshold is very low.

- 2 -> Contracts owner is a multisig with known trusted people

- 1 -> Contracts owner is a multisig with known trusted people with Timelock `OR` Contracts are governanceless, immutable `OR` Contracts owner can't do any harm to our strategy by setting parameters in external protocol contracts

### externalProtocolTvl

The active TVL that the external protocol holds:

- 5 -> TVL of $10M or less

- 4 -> TVL between 10Mand10M and 10Mand40M
3 -> TVL between 40Mand40M and 40Mand120M
2 -> TVL between 120Mand120M and 120Mand480M
1 -> TVL of $480M or more

### externalProtocolLongevity

How long the external protocol contracts in scope have been deployed alive

5 -> Less than 6 months
4 -> Between 6 and 12 months
3 -> Between 12 and 18 months
2 -> Between 18 and 24 months
1 -> 24 months or more

### externalProtocolType

What does the external protocol do? Note that this is a rough estimate of evaluating a protocol's purpose. In some cases, the Yearn security team can score regardless of the criteria; in such cases, the reasoning will be provided in the text box as usual with all scores.

5 -> The main expertise of the protocol lies in off-chain operations, such as RWA protocols.
4 -> Cross-chain applications, like cross-chain bridges, cross-chain yield aggregators, and cross-chain lending/borrowing protocols
3 -> AMM lending/borrowing protocols that are not forks of blue-chip protocols, leveraged farming protocols, as well as newly conceptualized protocols
2 -> Slightly modified forked blue-chip protocols.
1 -> Blue-chip protocols such as AAVE, Compound, Uniswap, Curve, Convex, and Balancer.

### comment

Comment is used by the Yearn security team to provide additional information about the score given. It can be used to justify the score given or provide additional information about the potential problems or loses.

## Defining risk scores for the strategy

This is how the risk scores will be attached to the strategy:

```
{ "review": 2, "testing": 3, "complexity": 1, "riskExposure": 3, "protocolIntegration": 1, "centralizationRisk": 1, "externalProtocolAudit": 4, "externalProtocolCentralisation": 3, "externalProtocolTvl": 2, "externalProtocolLongevity": 1, "externalProtocolType": 4, "comment": ""}
```

For more info on how to attach the risk scores to the strategy see yDaemon schema. Example of the strategy yPT-uniETH Yearn Auto-Rolling Pendle PT (https://github.com/yearn/ydaemon/blob/6797a0246ba13ac3e8b78f8b9a54b12e8500d603/data/meta/vaults/1.json#L62-L75).