# Welcome to Blueberry Protocol

Introduction to Blueberry

### Concept Summary

Blueberry provides next-gen tools for DeFi yield strategists to enjoy new on-chain capabilities and access more capital. Blueberry's innovative "position NFTs" combine a user's collateral, debt, and deployment into one position, allowing borrowing of 20x the collateral value or more while maintaining a healthy system. Positions are sent to liquidation at a -85% or -90% PnL depending on the collateral supplied, protecting lender capital.

### Blueberry Docs

In the documentation, we will guide you through an overview of Blueberry, its core features, and functionalities; including leveraged yield farming and lending, as well as a guide to using the protocol.

If you still have any questions after reading the documentation, please see the FAQs section or hop into our discord server.

### Why Build Blueberry?

DeFi is hamstrung by a lack of on-chain hedging and leverage capabilities, forcing users to rely on centralized solutions with counterparty risk. Blueberry seeks to bring as much capability as possible on-chain with an improved user experience. The protocol also seeks to level the playing field for liquidity provision, allowing anyone with a Web 3 wallet to perform sophisticated Liquidity Provision strategies like a market maker.

Read more about Blueberry's "Why's" on our official medium: <https://medium.com/@blueberryprotocol>

### For developers:

We also provided Web3.0 builders/developers that are looking to integrate with Blueberry with the documentation needed in the developer guides section.&#x20;

See more details below:

{% content-ref url="/pages/O3iRu1rM4rY9bK0kq01M" %}
[Contracts](/developer-guides/contracts)
{% endcontent-ref %}


# What is Blueberry?

Quick deep-dives on Blueberry

Blueberry Protocol is a decentralized lending market built on the Ethereum blockchain. It aims to revolutionize the DeFi (Decentralized Finance) lending space by offering users the ability to engage in leveraged borrowing and lending, with leverage possibilities extending up to 20x the collateral value. This level of leverage is facilitated through a variety of integrated strategies available within the protocol, positioning Blueberry as a pioneer in providing decentralized access to generalized leverage on the Ethereum network.

### Key Features

**Leveraged Borrowing and Lending**

Blueberry enables users to borrow amounts exceeding their collateral value by up to 20 times. This feature is designed for users seeking to maximize their capital efficiency and deploy leveraged positions across a range of strategies.

**Integrated Strategies**

The protocol's flexible and modular architecture supports an expanding array of strategies over time, ensuring adaptability and growth within the Ethereum ecosystem. Current integrations include, but are not limited to Leverage Trading, Yield Farming, Yield Arbitraging, and Uniswap v3 automated vaults. These integrations offer users diverse opportunities for leveraging their loans effectively.

**Position NFTs**

A novel aspect of Blueberry is the use of Position NFTs (Non-Fungible Tokens), which encapsulate the details of the borrower's leveraged position, including the collateral asset, borrowed asset, and the specific strategy employed. These NFTs play a crucial role in managing the protocol's risk and enabling the customization of leverage strategies.

<br>

**Safety and Governance**

The safety of lenders and the integrity of the protocol are of utmost importance. The Blueberry DAO (Decentralized Autonomous Organization) determines which assets and strategies are whitelisted in the protocol, ensuring only vetted and secure options are available to users. This governance mechanism enhances the protocol's security and fosters trust within the community.

### &#x20;Roles within the Protocol

**Lenders**

Lenders have the opportunity to provide assets to the protocol at competitive interest rates. The appeal of lending on Blueberry is enhanced by the protocol's leveraged borrowing feature, which can offer higher returns compared to other decentralized lending platforms. Furthermore, lenders are incentivized with bdBLB tokens that can be vested over 1 year and mature into BLB governance tokens, allowing them to participate in the protocol's decision-making process.

**Strategists (Borrowers)**

Strategists, also known as borrowers, can leverage their collateral up to 20 times to engage in various strategies permitted by the protocol. This role is designed for users looking to amplify their market exposure and capitalize on the diverse strategies supported by Blueberry. By leveraging their positions, strategists can potentially maximize their returns while managing the associated risks.

**Liquidators**

Liquidators play a crucial role in maintaining the protocol's stability by liquidating positions that fall into negative profit and loss. This mechanism ensures that lenders are protected and the protocol remains solvent. Liquidators are rewarded for their contributions with liquidation incentives, creating a system that encourages active participation in maintaining the health of the platform.

### Getting Started

For users interested in exploring Blueberry's offerings, participating in the lending market, or employing leveraged strategies, the protocol is currently live. The best starting points for engagement are through Blueberry's Discord or Twitter channels, where updates, discussions, and support are readily available. Visit[ app.blueberry.garden](http://app.blueberry.garden/) to begin exploring the possibilities with Blueberry.

Learn more about Blueberry here

{% embed url="<https://www.youtube.com/watch?v=Gply0RJq6hE>" %}


# Concept Overview

The Next Evolution of On-Chain Money Markets

<figure><img src="/files/85GS7m2uz2QZ8Zhg633J" alt=""><figcaption><p>Simplified Architecture Map</p></figcaption></figure>

*Currently, the on-chain landscape for lending and leverage is lacking in both accessibility and wide support of assets and strategies.*

**Blueberry’s Key Components and Actors:**

**Lender**: Individuals or entities who provide assets (such as ETH or USDC) to the Blueberry Bank. In exchange, they receive yield-bearing tokens called ibTokens, representing their share in the lending pool.

**Blueberry Bank**: The central hub where lending and borrowing occur. Lenders deposit assets into the bank, while borrowers (Traders or Yield Strategists) interact with it to obtain loans by providing collateral.

**Trader or Yield Strategist:** Borrowers who deposit collateral and select a position to borrow funds. They employ various strategies to generate returns using the borrowed capital. Upon borrowing, they receive a Position NFT representing their specific position, including the collateral and borrowed amount.

**DAO (Decentralized Autonomous Organization):** The governance body overseeing the Blueberry Protocol. It establishes risk parameters (e.g., LTV ratios) and determines the whitelisted assets and approved strategies within the protocol.

**Position NFTs:** Unique tokens representing a borrower's position, encompassing the collateral, borrowed assets, and chosen strategy. The Blueberry Bank mints and holds these NFTs. Borrowers can redeem their Position NFTs to claim the realized profit or loss when closing their positions.

**Liquidation Bots:** Automated systems monitoring borrowers' positions. If a position becomes undercollateralized and breaches the predefined risk thresholds, the liquidation bots are triggered to liquidate the position, ensuring the lenders' funds remain protected.

**Protocol Flow:**

1. Lenders deposit assets into the Blueberry Bank, receiving ibTokens proportional to their contribution.
2. Borrowers provide collateral and select a borrowing strategy, receiving a Position NFT unique to their position.
3. The DAO regularly reviews and adjusts risk parameters, whitelists assets, and approves strategies for use within the protocol.
4. Liquidation bots continuously monitor borrowers' positions. If a position becomes too risky, breaching the collateralization requirements, the bots automatically liquidate the position to safeguard the lenders' assets.
5. Borrowers can redeem their Position NFTs to claim the realized profit or loss when they choose to close their positions.

The Blueberry Protocol aims to create a secure, decentralized lending platform that optimizes capital efficiency and accommodates various borrowing strategies. The DAO's governance ensures the protocol remains robust and responsive to market conditions, while the liquidation bots act as an automated risk management system, protecting the interests of lenders.

<br>


# Front End

Front end by Composable Corp: app.blueberry.garden

\
There are 3 main sections within the Blueberry dApp:

1. [Lockdrop](/tokenomics/lockdrop)
2. [Lend](/lending-protocol/overview)
3. [Rewards](/tokenomics/usdbdblb)
4. [Earn](/earn/leveraged-strategies)

### 1. Lockdrop

The Lockdrop section provides information and functionality related to the initial 60-day liquidity bootstrapping event. During this period, users can deposit assets and receive boosted $bdBLB (Bonded Blueberry) reward emissions in exchange for providing liquidity. A 1% withdrawal fee is applied to any assets withdrawn during the Lockdrop.

### 2. Lend

The Lend page allows users with idle assets to earn interest by lending them to borrowers taking out leveraged positions. When a user enters a leveraged yield position, their collateral is also deposited to the Lend page so that it can earn interest while serving as collateral for the position.

### 3. Rewards

The Rewards section displays the $bdBLB rewards a user has earned and information about the vesting schedule. $bdBLB is the protocol's vested rewards token that unlocks on a yearly linear schedule to be redeemable 1:1 for the $BLB governance token. Users can view their claimable $bdBLB balance as well as details on early unlocking penalties if they choose to redeem before the full vest.

### 4. Earn

The Earn page displays all available strategies and the respective details for those strategies, as well as the expected yields with various leverage levels. Users can view the expected APRs for each strategy at different leverage levels. This section provides the functionality to open, adjust, and close leveraged yield farming positions.


# Leveraged Strategies

Using leverage is extremely risky, and the additional yield-bearing derivatives  each carry additional risk. Make sure you are qualified and have studied all associated risks before using.

There are many reasons why one might want to employ leverage in DeFi through a permissionless system like Blueberry. Let's walk through some of the use cases in detail for different types of users.

**1: Yield Arbitrage**

A common occurrence in DeFi is coming across one lending market with a different interest rate than you could deploy the borrowed asset elsewhere. This leads to a delta neutral opportunity for yield arbitrage. Blueberry allows users to borrow with leverage on Blueberry, then use borrowed funds in another protocol paying a higher yield.&#x20;

Easy example: Deposit stETH collateral, borrow 6x ETH, swap to 6x stETH

Your price exposure would still be 1x ETH, while you would earn 6x the spread between the ETH borrow rate and stETH yield.

**2: Trading**

There are many reasons to use leverage when trading, whether you are attempting to mitigate your custodial risk of keeping funds on an exchange, or just trying to multiply your exposure.

Blueberry brings a unique leverage trading strategy on chain, allowing the user to earn yield on their collateral and sometimes also on the leveraged position.&#x20;

Easy example: Deposit ETH Collateral, borrow 6x USDC, swap to 6x stETH

By swapping to stETH instead of regular ETH, you earn yield to offset the borrowing costs of USDC. If USDC borrowing costs are less than stETH yield, this would mean being paid yield to hold a leveraged long position on ETH.

**3: Leveraged Farming**

Leveraged farming allows you to borrow more assets than you have to earn a yield. Leverage farming is categorized differently than yield arbitrage because these strategies hold leverage exposure to the assets in the strategy, sometimes with unique mechanics like Liquidity pools, which do not carry 1:1 exposure to the assets within.&#x20;

If you are new to the concept of leveraged yield farming, you should first read an intro article on the topic and avoid deploying capital into things you do not understand.

Easy Example: Deposit ETH Collateral, borrow 3x ETH, deploy into CVX+ETH Convex LP

By doing this with leverage, you earn 3x the rewards. However, if the CVX+ETH LP underperforms ETH significantly, this could lead to liquidation.

**4: Uniswap v3 - Blueberry Vaults**

Providing liquidity on Uniswap v3 has become a huge hassle for users due to complexity, necessity of active management, and high rebalancing costs.

Blueberry Vaults leverage the additional capital efficiency features of concentrated liquidity by creating openly accessible pools that use automated algorithms to outpeform passive liquidity and lower pro rate rebalancing costs. Additionally, Blueberry Vaults work to provide single-asset oriented returns. This mitigates IL risk and simplifies the system when combined with leverage.

Easy Example: Deposit ETH collateral, borrow 3x ETH, Deposit to ETH Sided ETH-USDC Blueberry vault.

If the vault works as intended, this turns providing liquidity on Uni v3 into a much simpler basis trade--borrow asset with x% interest, deploy asset earning y% APR, earn (y-x)\*leverage.

The Blueberry vaults have been thoroughly tested in production environments, however, they are still experimental and carry considerable risks like the rest of the protocol. Do your research and do not invest funds you cannot afford to lose, as always.

**What's next?**

**Start a conversation about a new integration at discord.gg/blueberry**


# Liquidation Process on Blueberry

Liquidation is a crucial aspect of the Blueberry protocol, designed to protect lenders and maintain the stability of the platform. This document provides an in-depth explanation of the liquidation pro

## The Risk of Liquidation

When you open a leveraged position, borrowing up to 6x the funds you add, the protocol needs to make sure you'll be able to pay back that loan. So the amount you add from your funds acts as collateral, which grows as you accumulate yields (minus borrowing interest).\
\
That collateral has to remain above the amount you owe (plus a margin of safety to account for potentially quick price movements or high gas) or the protocol may close your position to pay back lenders, which is called **Liquidation**. You want to avoid liquidation because at that time, depending on the collateral asset supplied your remaining position value would be paid to the liquidator bot as a reward for closing your position and ensuring lenders were paid back.\
\
Liquidation risks can be mitigated by using low/no leverage, or by using delta neutral and yield arbitrage strategies that attempt to maintain fully neutral price exposure.

Easily track your liquidation risk for an open position using the **Position Health** bar on the interface.


# The Concept of Liquidation

When opening a leveraged position on Blueberry, users borrow funds up to 6 times the value of their initial capital, which serves as collateral. As yields accumulate (minus borrowing interest), the collateral is expected to grow. However, the collateral value must always exceed the borrowed amount plus a safety margin to account for potential price fluctuations or high transaction fees (gas).

If the collateral falls below the required threshold, the protocol initiates a liquidation process to close the position and repay the loan to the lenders. Liquidation results in the remaining value of the position being awarded to the liquidator, compensating them for ensuring lenders are reimbursed.<br>


# Liquidations on Blueberry

On Blueberry, liquidation is triggered based on the Net PnL (Profit and Loss) of the Position NFT, which includes:

\- The collateral

\- The debt

\- The deployed strategy

The concept is similar to the mechanics of leverage trading, but for DeFi strategies.&#x20;

A liquidation occurs when the Net PnL of the position NFT is equal to the Liquidation Threshold for the collateral supplied. A user can see how close they are to liquidation through the position health bar on the Home page.

The liquidation thresholds exist so that the lenders and protocol do not experience bad debt. A 10 or 15% margin is enough to guarantee that the liquidator can receive full repayment by liquidating assets after repaying the loan. It is recommended that users monitor their positions and close a position before it comes to liquidation, in order to maximize the value received back.

Anyone can perform a liquidation for a position that meets the threshold. As a safety mechanism, the Blueberry DAO will have a bot in place to immediately liquidate any position that meets the threshold using flash loans.

**Liquidation Thresholds**

Volatile Asset Threshold: -85% PnL

Stable Asset Threshold: -90% PnL

<br>


# Role of Bots in the Liquidation Process

Blueberry is supported by automated mechanisms, known as liquidation bots, which are programmed to execute liquidations instantaneously when positions meet the liquidation criteria. These bots utilize flash loans—a feature in DeFi that allows for borrowing without collateral, provided that the liquidity is returned within the same transaction—to efficiently liquidate at-risk positions.

### Liquidation Incentives

To encourage participation and prompt execution of liquidations, the protocol provides incentives, usually in the form of a percentage of the liquidated assets. These rewards compensate liquidators for contributing to the health and stability of the protocol by ensuring that lenders' funds are protected.


# Mitigating Liquidation Risk

To minimize the risk of liquidation when using leveraged trading platforms, users can employ the following strategies:

1. Low or No Leverage: Opt for trading strategies that involve little to no leverage to reduce the likelihood of liquidation.
2. Delta-Neutral and Yield Arbitrage: Engage in trading strategies that aim to maintain a neutral exposure to price movements, such as delta-neutral positions and yield arbitrage opportunities.
3. Position Health Monitoring: Utilize the Position Health indicator provided in the user interface to closely monitor the health of open positions and their proximity to the liquidation threshold.

**Monitoring Liquidation Risk**

The Position Health indicator allows users to track how close their positions are to the liquidation threshold. These thresholds are strategically set to protect the protocol and lenders from potential bad debt. Make sure to maintain the margin to ensure liquidators have sufficient room to cover loan repayments and liquidate assets profitably.

**Proactive Position Management**

To maximize the value of their investments, users should proactively manage their positions. It is advisable to consider closing positions before reaching the liquidation threshold to minimize losses and retain as much value as possible.

By implementing these risk management strategies and closely monitoring position health, users can effectively navigate the risks associated with leveraged trading and make informed decisions to protect their investments.


# Earn Token Listing

The requirements for a token to be listed on the protocol

Blueberry DAO is very careful about adding new collateral assets as this is a common cause of exploits. However, the protocol is able to support more exotic collaterals safely because it can isolate possible deployments and usages of the assets.&#x20;

In general, Blueberry DAO only supports highly liquid collateral assets to be borrowed against in amounts that can be liquidity against locked or verified external liquidity sources. This is a very case-by-case situation.&#x20;

Regardless of the asset, the DAO will first perform a thorough review with its security partners to account for any risks and the value add to the system. As a general rule of thumb, Blueberry can support longer tail assets in lending markets and be utilized for deployments, but not as a collateral option.

**Listing Standards as evaluated by DAO contributors:**

* All tokens should adhere to a maximum of 18 decimals places and tokens that can not be directly upgraded.
* Sufficient Locked/burned liquidity on-chain&#x20;
  * This is having liquidity locked into a trading venue to make sure trades can always occur that are locked either through a contract or through code.&#x20;
* Team
  * Who created the project
* Backers
  * Who is supporting the project&#x20;
* Treasury and Assets supporting the project&#x20;
* Trading activity
  * That this token isn't fully dormant and has no volume
* Oracle support
  * This should be supported by Chainlink price feeds.
* Isn't a newly launched token&#x20;

These are the beginning process to see if a token can be whitelisted in the protocol and see the level of utilization that it can get.&#x20;

<br>


# Earn Token Delisting

**Delist Standard**

if a token meets **ANY** condition below in the past 30 days, it is considered to available to be delisted:

* **Low supply**: less than $50k USD value
* **Low collateral value and borrowing**: Less than $50k collateral and $50k borrowing in USD value
* **Security issue**

These standards are targeting tokens that are:&#x20;

1. Low supply and low liquidity that users can hardly leverage
2. High liquidity but low usage that no one wants to leverage or borrow against

### Delist Procedure

#### Phase 1&#x20;

(Execution in the following order)

* Announcement of delisting
* Pause Supply & Pause Borrow
* Reserve Factor 100% & Change IRM to raise borrow rate

#### Phase 2&#x20;

* Announcement of the collateral factor change
* Collateral Factor 0%&#x20;
* Move to the deprecated category on the UI


# Strategy Listing and Delisting

The requirements for a token to be listed on the protocol

Blueberry DAO is very careful about adding new strategy integrations as this is a common cause of exploits. However, the protocol is able to support more exotic strategies safely because it can determine appropriate risk parameters such as max strategy borrow, max position size, and max LTV.&#x20;

At the beginning, core contributors have used their best judgement to launch the protocol with integrations that are widely used already. When the token is released and governance goes live, the DAO will propose and vote on new integrations. There will also be further guidance released on parameters for listing and delisting standards through a third party risk management provider Gauntlet.

<br>


# Fee Structure

The following is the typical fee structure, this can change pending governance decisions. This is what Blueberry Protocol takes there might be additional fees that are paid to the underlying strategies being deployed (I.e. Uniswap fees/curve fees/ etc)

<table><thead><tr><th width="205">function</th><th width="75" data-type="number">bps</th><th width="56" data-type="number">%</th><th>Description</th></tr></thead><tbody><tr><td>doCutRewardsFee</td><td>1000</td><td>10</td><td>Cut performance fee from the rewards generated from the leverage position</td></tr><tr><td>Reserve Factor</td><td>2000</td><td>20</td><td>Is the percentage of interest paid to the Blueberry Money Market (Compound fork)</td></tr></tbody></table>


# Earn Error Codes

BlueberryError.sol - Technical Documentation

| Error                                                        | Description                                                                   | Type of Error |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------- | ------------- |
| ZERO\_AMOUNT                                                 | Thrown when the amount is zero                                                | Common        |
| ZERO\_ADDRESS                                                | Thrown when the address is zero                                               | Common        |
| INPUT\_ARRAY\_MISMATCH                                       | Thrown when the array input has a mismatch for token length                   | Common        |
| TOO\_LONG\_DELAY(uint256 delayTime)                          | Thrown when the delay time is too long                                        | Oracle        |
| NO\_MAX\_DELAY(address token)                                | Thrown when there is no maximum delay set for the token                       | Oracle        |
| PRICE\_OUTDATED(address token)                               | Thrown when the price is larger than the maximum delay                        | Oracle        |
| NO\_SYM\_MAPPING(address token)                              | Thrown when there is no                                                       | Oracle        |
| OUT\_OF\_DEVIATION\_CAP(uint256 deviation)                   | Thrown when the deviation is greater than the cap.                            | Oracle        |
| EXCEED\_SOURCE\_LENGTH(uint256 length)                       | Thrown when the source length is too long                                     | Oracle        |
| NO\_PRIMARY\_SOURCE(address token)                           | Thrown when there is no primary price feed for the token                      | Oracle        |
| NO\_VALID\_SOURCE(address token)                             | Thrown when the input for a token is not valid                                | Oracle        |
| EXCEED\_DEVIATION()                                          | Thrown when the amount of deviation is greater than the cap                   | Oracle        |
| TOW\_LOW\_MEAN(uint256 mean)                                 | Thrown when the mean is below the required                                    | Oracle        |
| NO\_MEAN(address token)                                      | Thrown when there is no mean price for a token                                | Oracle        |
| NO\_STABLEPOOL(address token)                                | Thrown when there is no stable pool for a token                               | Oracle        |
| PRICE\_FAILED(address token)                                 | Thrown when unable to get a price for a token                                 | Oracle        |
| LIQ\_THRESHOLD\_TOO\_HIGH(uint256 threshold)                 | Thrown when the input is too large for the liquidation threshold              | Oracle        |
| LIQ\_THRESHOLD\_TOO\_LOW(uint256 threshold)                  | Thrown when the input is too small for the liquidation threshold              | Oracle        |
| ORACLE\_NOT\_SUPPORT(address token)                          | Thrown when a token does not have oracle support                              | Oracle        |
| ORACLE\_NOT\_SUPPORT\_LP(address lp)                         | Thrown when a LP token does not have oracle support                           | Oracle        |
| ORACLE\_NOT\_SUPPORT\_WTOKEN(address wToken)                 | Thrown when a wtoken does not have oracle support                             | Oracle        |
| ERC1155\_NOT\_WHITELISTED(address collToken)                 | Thrown when an invalid ERC1155 is provided as input as it is not whitelisted  | Oracle        |
| NO\_ORACLE\_ROUTE(address token)                             | Thrown when the token does not have a set oracle routing                      | Oracle        |
| NOT\_BANK(address caller)                                    | Thrown when a caller is not the bank address                                  | Spell         |
| REFUND\_ETH\_FAILED(uint256 balance)                         | Thrown when unable to refund the balance in ETH                               | Spell         |
| NOT\_FROM\_WETH(address from)                                | Thrown when an invalid WETH address is provided                               | Spell         |
| LP\_NOT\_WHITELISTED(address lp)                             | Thrown when an invalid LP address is provided as input                        | Spell         |
| COLLATERAL\_NOT\_EXIST(uint256 strategyId, address colToken) | Thrown when an invalid Collateral token is provided as input for a strategy   | Spell         |
| STRATEGY\_NOT\_EXIST(address spell, uint256 strategyId)      | Thrown when attempting to enter a non-supported strategy                      | Spell         |
| EXCEED\_MAX\_POS\_SIZE(uint256 strategyId)                   | Thrown when attempting to make a position larger than cap                     | Spell         |
| EXCEED\_MAX\_LTV()                                           | Thrown when attempting to make a position larger than the supplied collateral | Spell         |
| INCORRECT\_LP(address lpToken)                               | Thrown when an invalid LP address is provided as input                        | Ichi Spell    |
| INCORRECT\_PID(uint256 pid)                                  | Thrown when an invalid pool ID is provided as input                           | Ichi Spell    |
| INCORRECT\_COLTOKEN(address colToken)                        | Thrown when the collateral token is not the appropriate one                   | Ichi Spell    |
| INCORRECT\_UNDERLUING(address uToken)                        | Thrown when the underlying token is not the appropriate one                   | Ichi Spell    |
| NOT\_FROM\_UNIV3(address sender)                             | Thrown when the sender address is not a Uniswap V3 address                    | Ichi Spell    |
| BORROW\_FAILED(uint256 amount)                               | Thrown when borrowing has failed                                              | Vault         |
| REPAY\_FAILED(uint256 amount)                                | Thrown when repaying debt has failed                                          | Vault         |
| LEND\_FAILED(uint256 amount)                                 | Thrown when lending has failed                                                | Vault         |
| REDEEM\_FAILED(uint256 amount)                               | Thrown when redeeming has failed                                              | Vault         |
| INVALID\_TOKEN\_ID(uint256 tokenId)                          | Thrown when an invalid token ID is provided as input                          | Wrapper       |
| BAD\_PID(uint256 pid)                                        | Thrown if supplied an invalid pool ID                                         | Wrapper       |
| BAD\_REWARD\_PER\_SHARE(uint256 rewardPerShare)              | Thrown if there is a mismatch in rewards per share of a vault                 | Wrapper       |
| FEE\_TOO\_HIGH(uint256 feeBps)                               | Thrown if supplied value is too large for feeBps                              | Bank          |
| NOT\_UNDER\_EXECUTION()                                      | Thrown if attempting use function during execution                            | Bank          |
| BANK\_NOT\_LISTED(address token)                             | Thrown if the supplied token address is not supported by that bank            | Bank          |
| BANK\_ALREADY\_LISTED()                                      | Thrown if the Bank address is already supported in the protocol               | Bank          |
| BANK\_LIMIT()                                                | Thrown if the amount of banks has reached its limit                           | Bank          |
| CTOKEN\_ALREADY\_ADDED()                                     | Thrown if the cToken is already supported in the protocol                     | Bank          |
| NOT\_EOA(address from)                                       | Thrown if the address is not an externally owned account (EOA)                | Bank          |
| LOCKED()                                                     | Thrown if the `_IN_EXEC_LOCK` variable is not equal to `_NOT_ENTERED`         | Bank          |
| NOT\_FROM\_SPELL(address from)                               | Thrown if the sender is not the spell address                                 | Bank          |
| NOT\_FROM\_OWNER(uint256 positionId, address sender)         | Thrown when the sender is not the owner of a position                         | Bank          |
| NOT\_IN\_EXEC()                                              | Thrown when the function is called outside of execution.                      | Bank          |
| ANOTHER\_COL\_EXIST(address collToken)                       | Thrown when the collToken already exists in the protocol                      | Bank          |
| NOT\_LIQUIDATABLE(uint256 positionID)                        | Thrown when a position is still healthy                                       | Bank          |
| BAD\_POSISTION(uint256 posId)                                | Thrown when the position Id provided is not supported                         | Bank          |
| BAD\_COLLATERAL(uint256 positionId)                          | Thrown when the supplied collateral address is not supported                  | Bank          |
| INSUFFICIENT\_COLLATERAL()                                   | Thrown when the collateral required is too small.                             | Bank          |
| SPELL\_NOT\_WHITELISTED(address spell)                       | Thrown when the Spell address is not whitelisted                              | Bank          |
| TOKEN\_NOT\_WHITELISTED(address token)                       | Thrown when the Token address is not whitelisted                              | Bank          |
| REPAY\_EXCEEDS\_DEBIT(uint256 repay, uint256 debt)           | Thrown when repay value is larger than debt value                             | Bank          |
| LEND\_NOT\_ALLOWED()                                         | Thrown when lending is turned off                                             | Bank          |
| BORROW\_NOT\_ALLOWED()                                       | Thrown when borrowing is turned off                                           | Bank          |
| INVALID\_UTOKEN(address uToken)                              | Thrown when the uToken provided is not approved                               | Bank          |
| INVALID\_FEE\_DISTRIBUTION()                                 | Thrown when the fee distribution is not set                                   | Config        |
| NO\_TREASURY\_SET()                                          | Thrown when there is no treasury set                                          | Config        |


# Overview

Blueberry Lend is a decentralized lending platform focused on capital efficiency allowing protocols and individuals to borrow mroe than 100% LTV to use in leveraged strategies. Capital efficiency for borrowers should lead to leading market rates for lenders.&#x20;

Whitelisted Strategies that go through the listing process are enabled to borrow with pre-set LTVs from the lending markets.

The Blueberry Money Market is a fork of Compound Protocol V2 with a list of changes made to it which can be viewed [Change Log](/lending-protocol/change-log).

Blueberry Money Market "Lend" harnesses smart contract automation to offer protocol-to-protocol lending via whitelisting with undercollateralized and uncollateralized lending. Partners include Blueberry V1. While it targets protocol to use, non-protocol users can also supply and borrow from Blueberry Money Market.

For more information, visit [Blueberry.garden](https://www.blueberrybank.garden/)

### Protocol Contract

| Contract            | Upgradability | Address |
| ------------------- | ------------- | ------- |
| Unitroller          | Yes           |         |
| Admin Multisig      | No            |         |
| Lens                | No            |         |
| BTokenAdmin         | No            |         |
| Timelock            | No            |         |
| CreditLimitTimelock | No            |         |
| ReserveManager      | No            |         |
| Guardian            | No            |         |


# Governance

### Admin Function

Admin Multisig&#x20;

#### Timelock

2-day timelock

* support a new market
* delist a market
* collateral factor change
* price oracle change
* supply unpause
* borrow unpause
* set credit limit
* set implementation
* upgrade comptroller admin

#### No Timelock

* supply pause
* borrow pause
* reserve factor change
* collateral cap change
* reduce reserve
* set interest rate model

### BTokenAdmin

* Set bToken implementation with a 2-day timelock
* Set bToken admin with a 2-day timelock

### Guardian

In case of emergency, Guardian has part of admin functions without timelock. Guardian is a multisig controlled by the same signers as admin multisig, but it needs only 1 signature to execute the following functions:

* Pause supply of a specific market
* Pause borrow of a specific market
* Pause Flash Loan of a specific market
* Pause liquidate borrow (seize) of all markets&#x20;
* Pause transfer of all bTokens
* Set supply cap of a specific market
* Set borrow cap of a specific market
* Reduce credit limit to $1 for a specific account, preventing it to borrow further without making it a non-credit-limit account
* Enable / disable on-chain oracle references&#x20;

(Withdraw and repay of any market cannot be paused)


# Flash Loans

**Blueberry Lend** is bringing Flash Loans to our money markets.

Flash Loans allow developers access to undercollateralized loans, provided that the borrowed amount (and fee) is returned within one transaction block.

Flash Loans offer a wide range of use cases, including democratized liquidations, arbitrage, collateral swapping and interest rate swapping.

1. Using Flash Loans devs **interact with BToken contract,** instead of the lending pool.
2. Flash Loan fee is 0.03%

Our markets comply to EIP-3156 interfaces natively. Users should call flashloan on specific market with the following interface:

```
// 
/**
    * @notice Flash loan funds to a given account.
    * @param receiver The receiver address for the funds
    * @param token The loan currency. Must match the address of this contract's underlying 
    * @param amount The amount of the funders to be loaned
    * @param data The other data
    * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details)
    */
   function flashLoan(
       ERC3156FlashBorrowerInterface receiver,
       address token,
       uint256 amount,
       bytes calldata data
   ) external returns (bool);
    
```

{% hint style="info" %}
Not all makets have Flash Loans. Check out bToken page
{% endhint %}


# Delist

### Delist Standard

If a token meets **ANY** condition below in the past 30 days, it is considered to be delisted:

* **Low supply**: less than $50k USD value
* **Low collateral value and borrowing**: Less than $50k collateral and $50k borrowing in USD value
* **Security issue**

These standards are targeting tokens which are:&#x20;

1. Low supply and low liquidity that user can hardly leverage
2. High liquidity but low usage that no one wants to leverage or borrow against

### Delist Procedure

#### Phase 1&#x20;

(Execution in the following order)

* Announcement of delisting
* Pause Supply & Pause Borrow
* Reserve Factor 100% & Change IRM to raise borrow rate

#### Phase 2&#x20;

* Announcement of the collateral factor change
* Collateral Factor 0%&#x20;
* Move to deprecated category on UI


# bToken Introduction

## Introduction

Each asset supported by Blueberry Bank is integrated through a bToken contract, which is an EIP-20 compliant representation of balances supplied to the protocol. By minting bTokens, users (1) earn interest through the bToken's exchange rate, which increases in value relative to the underlying asset, and (2) gain the ability to use bTokens as collateral.

bTokens are the primary means of interaction with Blueberry Bank; when user mints, redeems, borrows, repays a borrow, liquidates a borrow, or transfers bTokens, they will do so using the bToken Contract.

Blueberry Bank GitHHub Organization: <https://github.com/blueberryfi>

All mentions of BErc20 refer to <https://github.com/blueberryfi/compound-protocol/blob/eth/contracts/BCollateralCapErc20.sol>

### Mint

The mint function transfers an asset into the protocol, which begins accumulating interest based on the current Supply Rate for the asset. The user receives a quantity of bTokens equal to the underlying tokens supplied, divided by the current Exchange Rate.

#### BErc20

```
// funcation mint(uint mintAmount) returns (uint)
```


# bToken Address

{% hint style="info" %}
All bTokens are upgradable via BTokenAdmin under 2 day timelock.
{% endhint %}

### Active Markets

| Contract | Address                                    | Flash Loans |
| -------- | ------------------------------------------ | ----------- |
| bWETH    | 0x643d448CEa0D3616F0b32E3718F563b164e7eDd2 | Yes         |
| bDAI     | 0x23388Cca2BdFC994D75999667E09cc0F5fF1cc88 | Yes         |
| bWBTC    | 0xE61ad5B0E40c856E6C193120Bd3fa28A432911B6 | Yes         |
| bUSDC    | 0x649127D0800a8c68290129F091564aD2F1D62De1 | Yes         |
| bALCX    | 0xc5435051ccc67b4BB8DB8D27f9641C3309b320CC | Yes         |
| bBAL     | 0x864aDa7223542Ec6eF92789ae524263D7fE9fD96 | Yes         |
| bCRV     | 0xdeBd5D482C2B0feeA5527f9B832F7F894c8303eB | Yes         |
| bCrvUSD  | 0x9BdeCce77c6351b1941a827e25b5FdC73d69b622 | Yes         |
| bFRAX    | 0xA51406abFc4658c542b69c2f5a8BAbe61e21B416 | Yes         |
| bLINK    | 0x65cf55f03e2040D214883f6039FC65fd224E6A47 | Yes         |
| bOHM     | 0x08830038A6097C10f4A814274d5A68E64648d91c | Yes         |
| bUSDC    | 0x649127D0800a8c68290129F091564aD2F1D62De1 | Yes         |


# Interest Rate Model

## APY Function

The parameters below are borrowing major coins

## Borrow APY&#x20;

`= {1 + [BaseRatePerSecond + MultiplierPerSecond * min(UtilizationRate, Kink1) + max(JumpMultiplierPerSecond1 * UtilizationRate - Kink2,0) * JumpMultiplierPerSecond2] / SecondsPerYear } ^ SecondsPerYear - 1`

Where:

* UtilizationRate = Borrows / (Cash + Borrows - Reserves)
* SecondsPerYear = 31,557,600 (accounting for leap years)

## Supply APY&#x20;

`= Distribute (Interest Paid by Borrowers Per Second - Reserve) to all suppliers, and convert it into APY`&#x20;

\= Distribute \[(1 + Borrow APY) ^ (1 / SecondsPerYear) - 1] \* Total Borrow \* (1 - Reserve Factor) to all suppliers, and convert it into APY&#x20;

\= {\[(1 + Borrow APY) ^ (1 / SecondsPerYear) - 1] \* Total Borrow \* (1 - Reserve Factor) / Total Supply}, and convert it into APY&#x20;

\= {1 + \[(1 + Borrow APY) ^ (1 / SecondsPerYear) - 1] \* Total Borrow \* (1 - Reserve Factor) / Total Supply} ^ SecondsPerYear - 1&#x20;

\= {1+\[(1+Borrow APY)^(1/SecondsPerYear)-1]\*(1-Reserve Factor)\*Utilization Rate}^SecondsPerYear-1

Where:

* BorrowRate = BaseRatePerSecond + MultiplierPerSecond \* UtilizationRate (if UtilizationRate <= Kink1) or BaseRatePerSecond + JumpMultiplierPerSecond1 \* UtilizationRate (if UtilizationRate > Kink1 and UtilizationRate <= Kink2) or BaseRatePerSecond + JumpMultiplierPerSecond1 \* Kink2 + (UtilizationRate - Kink2) \* JumpMultiplierPerSecond2 (if UtilizationRate > Kink2)
* UtilizationRate = Borrows / (Cash + Borrows - Reserves)
* ReserveFactor = Reserve Factor Mantissa

### Parameter&#x20;

#### Major

| Parameter        | Value                                        |
| ---------------- | -------------------------------------------- |
| Token            | USDC, WETH, WBTC, FRAX, CRVUSD, DAI          |
| Base             | 0%                                           |
| Multiplier       | 9e16                                         |
| JumpMultiplier1  | 9.8e16                                       |
| JumpMultiplier2  | 1.1e18                                       |
| Kink 1           | 55%                                          |
| Kink 2           | 89.5%                                        |
| Contract Address | `0xC82151fc8C8f4c8042beea293FeAb8764221d7fD` |

<figure><img src="/files/VL2pvbWhgZBgncDcvMBq" alt=""><figcaption></figcaption></figure>

| Utilization | Borrow Rate |
| ----------- | ----------- |
| 0           | 0%          |
| 5%          | 0.48%       |
| 10%         | 0.95%       |
| 20%         | 1.90%       |
| 30%         | 2.85%       |
| 40%         | 3.80%       |
| 50%         | 4.75%       |
| 60%         | 5.88%       |
| 70%         | 6.86%       |
| 80%         | 7.84%       |
| 85%         | 8.33%       |
| 90%         | 9.05        |
| 95%         | 14.55%      |
| 100%        | 20.05%      |


# Price Oracle

{% hint style="info" %}
Currently, we use Chainlink Oracle for all active markets on Blueberry Bank
{% endhint %}

Blueberry Lend uses Chainlink Oracle to provide price feeds for each lending market where USD is quoted. Blueberry Lend updates the token price whenever Chainlink has a new price written on-chain, and the update mechanism also follows Chainlink's trigger parameter. Each market has its own parameters.

For example, ETH/USD has a 0.5% Deviation Threshold and 3,600 seconds Heartbeats, which means a new trusted price is written when Chainlink's off-chain data moves more than the 0.5% deviation threshold or 3,600 seconds have passed since the last price was written on-chain.

### Oracle Latency

Using Chainlink Oracle helps us to avoid price manipulation within a block, but there are still chances that Chainlink Oracle has a price difference from the global price, depending on trigger parameters. In some cases, it leads users to borrow more than they are allowed if the borrowing limit is calculated by global price.

However, Blueberry Bank is an optimally collateralized lending protocol in that users can borrow assets no more than a certain ratio of collateral value, This is defined by the Collateral Factor of each market. Thus, while we keep monitoring significant price differences between Chainlink Oracle and global price, such Oracle latency has little effect on the protocol.

### Oracle Fallback

We use Chainlink for all active markets on Blueberry Bank by default.

While we believe in Chainlink providing accurate token prices, it is still important to monitor the price difference between our Oracle and global prices. If we were to find Chainlink's oracle price significantly different from the global price, we could toggle protocol price oracle from using Chainlink to other on-chain alternatives with the Guardian.

Only when Chainlink provides a stale price will we toggle Oracle by Guardian.

In some cases, we will use custom oracles when an Oracle solution is not supported by Chainlink.

### Price Oracle Address

| Contract            | Address                                    |
| ------------------- | ------------------------------------------ |
| PriceOracleProxyUSD | 0xc29C188E81A0Dede959Beeb1dB181c121f19476D |
| Core Oracle         | 0xdfe469ACe05C3d0D4461439e6cF5d0f46F33Ec56 |


# Error Code

Here are the articles in this section:

{% content-ref url="/pages/cR87o4Jpg0fYBEybY054" %}
[bToken Error Code](/lending-protocol/error-code/btoken-error-code)
{% endcontent-ref %}

{% content-ref url="/pages/JgU4v5HT4cNeMHS8bB99" %}
[Comptroller Error Code](/lending-protocol/error-code/comptroller-error-code)
{% endcontent-ref %}


# Key Events

## bTokens

| Event                                                                                                                | Description                                |
| -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
| Mint(address minter, uint mintAmount, uint mintTokens)                                                               | Emitted upon a successful Mint             |
| Redeem(address redeemer, uint redeemAmount, uint redeemTokens)                                                       | Emitted upon a successful Redeem           |
| Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows)                                  | Emitted upon a successful Borrow           |
| RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows)               | Emitted upon a successful Repay Borrow     |
| LiquidateBorrow(address liquidator, address borrower, uint repayAmount, address crTokenCollateral, uint seizeTokens) | Emitted upon a successful Liquidate Borrow |


# bToken Error Code

### Error codes

<table><thead><tr><th width="149">Code</th><th width="335">Name</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>NO_ERROR</td><td>Not a failure.</td></tr><tr><td>1</td><td>UNAUTHORIZED</td><td>The sender is not authorized to perform this action.</td></tr><tr><td>2</td><td>BAD_INPUT</td><td>An invalid argument was supplied by the caller.</td></tr><tr><td>3</td><td>COMPTROLLER_REJECTION</td><td>The action would violate the comptroller policy.</td></tr><tr><td>4</td><td>COMPTROLLER_CALCULATION_ERROR</td><td>An internal calculation has failed in the comptroller.</td></tr><tr><td>5</td><td>INTEREST_RATE_MODEL_ERROR</td><td>The interest rate model returned an invalid value.</td></tr><tr><td>6</td><td>INVALID_ACCOUNT_PAIR</td><td>The specified combination of accounts is invalid.</td></tr><tr><td>7</td><td>INVALID_CLOSE_AMOUNT_REQUESTED</td><td>The amount to liquidate is invalid.</td></tr><tr><td>8</td><td>INVALID_COLLATERAL_FACTOR</td><td>The collateral factor is invalid.</td></tr><tr><td>9</td><td>MATH_ERROR</td><td>A math calculation error occurred.</td></tr><tr><td>10</td><td>MARKET_NOT_FRESH</td><td>Interest has not been properly accrued.</td></tr><tr><td>11</td><td>MARKET_NOT_LISTED</td><td>The market is not currently listed by its comptroller.</td></tr><tr><td>12</td><td>TOKEN_INSUFFICIENT_ALLOWANCE</td><td>ERC-20 contract must allow Money Market contract to call transferFrom. The current allowance is either 0 or less than the requested supply, repayBorrow or liquidate amount.</td></tr><tr><td>13</td><td>TOKEN_INSUFFICIENT_BALANCE</td><td>Caller does not have sufficient balance in the ERC-20 contract to complete the desired action.</td></tr><tr><td>14</td><td>TOKEN_INSUFFICIENT_CASH</td><td>The market does not have a sufficient cash balance to complete the transaction. You may attempt this transaction again later.</td></tr><tr><td>15</td><td>TOKEN_TRANSFER_IN_FAILED</td><td>Failure in ERC-20 when transfering token into the market.</td></tr><tr><td>16</td><td>TOKEN_TRANSFER_OUT_FAILED</td><td>Failure in ERC-20 when transfering token out of the market.<br></td></tr></tbody></table>

### Failure Information

<table><thead><tr><th width="150">Code</th><th>Name</th></tr></thead><tbody><tr><td>0</td><td>ACCEPT_ADMIN_PENDING_ADMIN_CHECK</td></tr><tr><td>1</td><td>ACCRUE_INTEREST_ACCUMULATED_INTEREST_CALCULATION_FAILED</td></tr><tr><td>2</td><td>ACCRUE_INTEREST_BORROW_RATE_CALCULATION_FAILED</td></tr><tr><td>3</td><td>ACCRUE_INTEREST_NEW_BORROW_INDEX_CALCULATION_FAILED</td></tr><tr><td>4</td><td>ACCRUE_INTEREST_NEW_TOTAL_BORROWS_CALCULATION_FAILED</td></tr><tr><td>5</td><td>ACCRUE_INTEREST_NEW_TOTAL_RESERVES_CALCULATION_FAILED</td></tr><tr><td>6</td><td>ACCRUE_INTEREST_SIMPLE_INTEREST_FACTOR_CALCULATION_FAILED</td></tr><tr><td>7</td><td>BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED</td></tr><tr><td>8</td><td>BORROW_ACCRUE_INTEREST_FAILED</td></tr><tr><td>9</td><td>BORROW_CASH_NOT_AVAILABLE</td></tr><tr><td>10</td><td>BORROW_FRESHNESS_CHECK</td></tr><tr><td>11</td><td>BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED</td></tr><tr><td>12</td><td>BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED</td></tr><tr><td>13</td><td>BORROW_MARKET_NOT_LISTED</td></tr><tr><td>14</td><td>BORROW_COMPTROLLER_REJECTION</td></tr><tr><td>15</td><td>LIQUIDATE_ACCRUE_BORROW_INTEREST_FAILED</td></tr><tr><td>16</td><td>LIQUIDATE_ACCRUE_COLLATERAL_INTEREST_FAILED</td></tr><tr><td>17</td><td>LIQUIDATE_COLLATERAL_FRESHNESS_CHECK</td></tr><tr><td>18</td><td>LIQUIDATE_COMPTROLLER_REJECTION</td></tr><tr><td>19</td><td>LIQUIDATE_COMPTROLLER_CALCULATE_AMOUNT_SEIZE_FAILED</td></tr><tr><td>20</td><td>LIQUIDATE_CLOSE_AMOUNT_IS_UINT_MAX</td></tr><tr><td>21</td><td>LIQUIDATE_CLOSE_AMOUNT_IS_ZERO</td></tr><tr><td>22</td><td>LIQUIDATE_FRESHNESS_CHECK</td></tr><tr><td>23</td><td>LIQUIDATE_LIQUIDATOR_IS_BORROWER</td></tr><tr><td>24</td><td>LIQUIDATE_REPAY_BORROW_FRESH_FAILED</td></tr><tr><td>25</td><td>LIQUIDATE_SEIZE_BALANCE_INCREMENT_FAILED</td></tr><tr><td>26</td><td>LIQUIDATE_SEIZE_BALANCE_DECREMENT_FAILED</td></tr><tr><td>27</td><td>LIQUIDATE_SEIZE_COMPTROLLER_REJECTION</td></tr><tr><td>28</td><td>LIQUIDATE_SEIZE_LIQUIDATOR_IS_BORROWER</td></tr><tr><td>29</td><td>LIQUIDATE_SEIZE_TOO_MUCH</td></tr><tr><td>30</td><td>MINT_ACCRUE_INTEREST_FAILED</td></tr><tr><td>31</td><td>MINT_COMPTROLLER_REJECTION</td></tr><tr><td>32</td><td>MINT_EXCHANGE_CALCULATION_FAILED</td></tr><tr><td>33</td><td>MINT_EXCHANGE_RATE_READ_FAILED</td></tr><tr><td>34</td><td>MINT_FRESHNESS_CHECK</td></tr><tr><td>35</td><td>MINT_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED</td></tr><tr><td>36</td><td>MINT_NEW_TOTAL_SUPPLY_CALCULATION_FAILED</td></tr><tr><td>37</td><td>MINT_TRANSFER_IN_FAILED</td></tr><tr><td>38</td><td>MINT_TRANSFER_IN_NOT_POSSIBLE</td></tr><tr><td>39</td><td>REDEEM_ACCRUE_INTEREST_FAILED</td></tr><tr><td>40</td><td>REDEEM_COMPTROLLER_REJECTION</td></tr><tr><td>41</td><td>REDEEM_EXCHANGE_TOKENS_CALCULATION_FAILED</td></tr><tr><td>42</td><td>REDEEM_EXCHANGE_AMOUNT_CALCULATION_FAILED</td></tr><tr><td>43</td><td>REDEEM_EXCHANGE_RATE_READ_FAILED</td></tr><tr><td>44</td><td>REDEEM_FRESHNESS_CHECK</td></tr><tr><td>45</td><td>REDEEM_NEW_ACCOUNT_BALANCE_CALCULATION_FAILED</td></tr><tr><td>46</td><td>REDEEM_NEW_TOTAL_SUPPLY_CALCULATION_FAILED</td></tr><tr><td>47</td><td>REDEEM_TRANSFER_OUT_NOT_POSSIBLE</td></tr><tr><td>48</td><td>REDUCE_RESERVES_ACCRUE_INTEREST_FAILED</td></tr><tr><td>49</td><td>REDUCE_RESERVES_ADMIN_CHECK</td></tr><tr><td>50</td><td>REDUCE_RESERVES_CASH_NOT_AVAILABLE</td></tr><tr><td>51</td><td>REDUCE_RESERVES_FRESH_CHECK</td></tr><tr><td>52</td><td>REDUCE_RESERVES_VALIDATION</td></tr><tr><td>53</td><td>REPAY_BEHALF_ACCRUE_INTEREST_FAILED</td></tr><tr><td>54</td><td>REPAY_BORROW_ACCRUE_INTEREST_FAILED</td></tr><tr><td>55</td><td>REPAY_BORROW_ACCUMULATED_BALANCE_CALCULATION_FAILED</td></tr><tr><td>56</td><td>REPAY_BORROW_COMPTROLLER_REJECTION</td></tr><tr><td>57</td><td>REPAY_BORROW_FRESHNESS_CHECK</td></tr><tr><td>58</td><td>REPAY_BORROW_NEW_ACCOUNT_BORROW_BALANCE_CALCULATION_FAILED</td></tr><tr><td>59</td><td>REPAY_BORROW_NEW_TOTAL_BALANCE_CALCULATION_FAILED</td></tr><tr><td>60</td><td>REPAY_BORROW_TRANSFER_IN_NOT_POSSIBLE</td></tr><tr><td>61</td><td>SET_COLLATERAL_FACTOR_OWNER_CHECK</td></tr><tr><td>62</td><td>SET_COLLATERAL_FACTOR_VALIDATION</td></tr><tr><td>63</td><td>SET_COMPTROLLER_OWNER_CHECK</td></tr><tr><td>64</td><td>SET_INTEREST_RATE_MODEL_ACCRUE_INTEREST_FAILED</td></tr><tr><td>65</td><td>SET_INTEREST_RATE_MODEL_FRESH_CHECK</td></tr><tr><td>66</td><td>SET_INTEREST_RATE_MODEL_OWNER_CHECK</td></tr><tr><td>67</td><td>SET_MAX_ASSETS_OWNER_CHECK</td></tr><tr><td>68</td><td>SET_ORACLE_MARKET_NOT_LISTED</td></tr><tr><td>69</td><td>SET_PENDING_ADMIN_OWNER_CHECK</td></tr><tr><td>70</td><td>SET_RESERVE_FACTOR_ACCRUE_INTEREST_FAILED</td></tr><tr><td>71</td><td>SET_RESERVE_FACTOR_ADMIN_CHECK</td></tr><tr><td>72</td><td>SET_RESERVE_FACTOR_FRESH_CHECK</td></tr><tr><td>73</td><td>SET_RESERVE_FACTOR_BOUNDS_CHECK</td></tr><tr><td>74</td><td>TRANSFER_COMPTROLLER_REJECTION</td></tr><tr><td>75</td><td>TRANSFER_NOT_ALLOWED</td></tr><tr><td>76</td><td>TRANSFER_NOT_ENOUGH</td></tr><tr><td>77</td><td>TRANSFER_TOO_MUCH</td></tr></tbody></table>


# Comptroller Error Code

### Error Codes

<table><thead><tr><th width="144">Code</th><th>Name</th><th>Description</th></tr></thead><tbody><tr><td>0</td><td>NO_ERROR</td><td>Not a failure.</td></tr><tr><td>1</td><td>UNAUTHORIZED</td><td>The sender is not authorized to perform this action.</td></tr><tr><td>2</td><td>COMPTROLLER_MISMATCH</td><td>Liquidation cannot be performed in markets with different comptrollers.</td></tr><tr><td>3</td><td>INSUFFICIENT_SHORTFALL</td><td>The account does not have sufficient shortfall to perform this action.</td></tr><tr><td>4</td><td>INSUFFICIENT_LIQUIDITY</td><td>The account does not have sufficient liquidity to perform this action.</td></tr><tr><td>5</td><td>INVALID_CLOSE_FACTOR</td><td>The close factor is not valid.</td></tr><tr><td>6</td><td>INVALID_COLLATERAL_FACTOR</td><td>The collateral factor is not valid.</td></tr><tr><td>7</td><td>INVALID_LIQUIDATION_INCENTIVE</td><td>The liquidation incentive is invalid.</td></tr><tr><td>8</td><td>MARKET_NOT_ENTERED</td><td>The market has not been entered by the account.</td></tr><tr><td>9</td><td>MARKET_NOT_LISTED</td><td>The market is not currently listed by the comptroller.</td></tr><tr><td>10</td><td>MARKET_ALREADY_LISTED</td><td>An admin tried to list the same market more than once.</td></tr><tr><td>11</td><td>MATH_ERROR</td><td>A math calculation error occurred.</td></tr><tr><td>12</td><td>NONZERO_BORROW_BALANCE</td><td>The action cannot be performed since the account carries a borrow balance.</td></tr><tr><td>13</td><td>PRICE_ERROR</td><td>The comptroller could not obtain a required price of an asset.</td></tr><tr><td>14</td><td>REJECTION</td><td>The comptroller rejects the action requested by the market.</td></tr><tr><td>15</td><td>SNAPSHOT_ERROR</td><td>The comptroller could not get the account borrows and exchange rate from the market.</td></tr><tr><td>16</td><td>TOO_MANY_ASSETS</td><td>Attempted to enter more markets than are currently supported.</td></tr><tr><td>17</td><td>TOO_MUCH_REPAY</td><td>Attempted to repay more than is allowed by the protocol.</td></tr></tbody></table>

### Failure Information

<table><thead><tr><th width="143">Code</th><th>Name</th></tr></thead><tbody><tr><td>0</td><td>ACCEPT_ADMIN_PENDING_ADMIN_CHECK</td></tr><tr><td>1</td><td>ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK</td></tr><tr><td>2</td><td>EXIT_MARKET_BALANCE_OWED</td></tr><tr><td>3</td><td>EXIT_MARKET_REJECTION</td></tr><tr><td>4</td><td>SET_CLOSE_FACTOR_OWNER_CHECK</td></tr><tr><td>5</td><td>SET_CLOSE_FACTOR_VALIDATION</td></tr><tr><td>6</td><td>SET_COLLATERAL_FACTOR_OWNER_CHECK</td></tr><tr><td>7</td><td>SET_COLLATERAL_FACTOR_NO_EXISTS</td></tr><tr><td>8</td><td>SET_COLLATERAL_FACTOR_VALIDATION</td></tr><tr><td>9</td><td>SET_COLLATERAL_FACTOR_WITHOUT_PRICE</td></tr><tr><td>10</td><td>SET_IMPLEMENTATION_OWNER_CHECK</td></tr><tr><td>11</td><td>SET_LIQUIDATION_INCENTIVE_OWNER_CHECK</td></tr><tr><td>12</td><td>SET_LIQUIDATION_INCENTIVE_VALIDATION</td></tr><tr><td>13</td><td>SET_MAX_ASSETS_OWNER_CHECK</td></tr><tr><td>14</td><td>SET_PENDING_ADMIN_OWNER_CHECK</td></tr><tr><td>15</td><td>SET_PENDING_IMPLEMENTATION_OWNER_CHECK</td></tr><tr><td>16</td><td>SET_PRICE_ORACLE_OWNER_CHECK</td></tr><tr><td>17</td><td>SUPPORT_MARKET_EXISTS</td></tr><tr><td>18</td><td>SUPPORT_MARKET_OWNER_CHECK</td></tr></tbody></table>


# Change Log

The Following changes have been made to Compound Protocol V2 to allow for additional flexibility while also increasing stability.  The fork also allows for additional lines of business to be created once the protocol matures more.&#x20;

Add borrow cap feature, this feature is cherry-picked from Compound Finance compound-finance/compound-protocol#65

Add a borrow cap check in Comptroller's borrowAllowed hook, disallow further borrowing if a market's totalBorrows reaches its borrow cap Add supply cap feature, implemented in Comptroller.sol, BCapableErc20.sol

Add a supply cap check in Comptroller's mintAllowed hook, disallow further minting (supplying) if a market's cash + totalBorrows reaches its supply cap BCapableErc20 tracks cash by itself instead of using balanceOf of the underlying token. This avoids direct transferring to bToken to manipulate cash. Add collateral cap feature, implemented in Comptroller.sol, BCollateralCapErc20.sol

Add a collateral cap to determine the maximum balance to be considered as collateral. If the cap is reached, users could still supply the asset but it can't be used as collateral. The maximum borrow power of this kind of asset is roughly collateralCap \* collateralFactor. Add BWrappedNative to replace old BEther

BWrappedNative could support both the native token and the wrapped native token. Users could choose the native token or the wrapped native token when supplying / borrowing / redeeming / repaying. Support protocol to protocol borrowing without collateral, this gives whitelisted protocol borrows up to credit limit without collateral.

Add credit limit in Comptroller.sol When setting up a credit limit, it also needs to specify the borrowing markets. This can also assist in the Protocol not reaching 100% utilization as a line of credit can be lower than the total TVL inside of the protocol. Support flash loan feature to offer a wide range of use cases, including democratized liquidations, arbitrage, collateral swapping, and interest rate swapping.

Blueberry Bank flash loan complies with EIP-3156 standard. Not every market supports flash loans.


# BLB Governance Token

Blueberry token is a utility and governance token for the Blueberry Protocol

## What is the Blueberry Token used for?

BLB is a governance token, used to vote on new integrations, deployments of $bdBLB reward tokens, and anything else related to the DAO.

Revenue from the protocol is partially used to buy back BLB tokens and make liquidity, creating healthier market growth over time.

[Read more here](https://medium.com/@blueberryprotocol/blueberry-tokenomics-and-token-generation-event-lockdrop-airdrop-1ac267d30092)<br>


# ibTokens

## What are ibTokens?

* When a user supplies their assets to Blueberry Protocol's Earn strategies, ibTokens (interest-bearing Tokens) are used to keep track of the funds they have deposited as well as any interest earned in addition to the NFT representation of their position.
* Each time a user supplies funds to the earn strategy, they are issued a corresponding balance in ibTokens, this is held in the Blueberry Bank contract. This balance of the ibTokens is directly proportional to the stake they have in the earn strategy, which accrues interest every block.
* Each Earn strategy asset has its own ibToken; for example, if a user deposits BTC to the specific earn strategy, they will receive a corresponding balance of ibBTC.
* When a user supplies assets to Blueberry Protocol's lend they receive ibTokens, which can be staked to earn bdBLB.&#x20;


# $bdBLB

Vested Rewards and Governance

**All about $bdBLB**

$BLB is the native token of the Blueberry protocol. Every two weeks, newly issued $BLB tokens are distributed as vested rewards called $bdBLB (Bonded Blueberry) to those providing liquidity by holding bTokens.

$bdBLB can be redeemed 1:1 for $BLB after a one-year vesting period. However, users have the option to unlock their $bdBLB sooner by paying an "early unlock penalty" consisting of two parts:

**Redistribution Penalty** - A percentage of the $BLB tokens is deducted, with the deducted amount redistributed to remaining $bdBLB holders. This penalty starts at 25% and decreases linearly to 0% over the year.

**Acceleration Fee** - A percentage of the initial $BLB value is paid in USDC to the protocol treasury to provide liquidity for $BLB. Like the redistribution penalty, this fee starts at 25% and decreases to 0% over the year.

The percentage penalties are designed to incentivize long-term participation while still allowing liquidity for those who want to exit early. Higher $BLB prices mean lower effective fees for early unlocks.

In the first 60 days after launch, there is a "Lockdrop" period where liquidity providers can earn boosted $bdBLB rewards subject to a 1% withdrawal fee. This helps bootstrap liquidity in a fair and decentralized manner aligned with the long-term growth of the protocol.

<br>


# Lockdrop

#### Introducing the Lockdrop

The lockdrop represents an innovative token distribution event tailored to bolster liquidity and foster a committed community. It is a key phase in the protocol’s lifecycle, designed to transition Blueberry from its initial development phase into a fully-fledged, community-driven protocol.

#### Functionality and Incentives

For the first 60 days following the protocol's launch, the lockdrop will distribute over 5% of $BLB's total supply to participating lenders. These lenders are vital in providing the liquidity necessary for Blueberry's leveraged market operations. To encourage their contribution, they will be granted $bdBLB tokens with a heightened emission rate during this early stage, balanced with a nominal withdrawal fee to promote long-term engagement.

#### Strategic Vesting for Value Alignment

The Token Generation Event (TGE) marks the start of a strategic vesting period, during which the accrued $bdBLB tokens will be locked for one year. The locking mechanism is designed to reward early participants, with a lower initial $BLB value, thus incentivizing early contributions and alignment with the protocol’s growth trajectory.


# Token Distribution

With a total supply of 1 billion $BLB tokens, the distribution strategy aims to create a diverse and engaged ecosystem of stakeholders, aligning their interests with the protocol's growth and sustainability.&#x20;

Central to the token distribution plan is the innovative lockdrop mechanism, designed to boost liquidity and encourage long-term commitment from lenders. Participants in the lockdrop event will receive $bdBLB tokens, which function as both vested rewards and governance tokens. These tokens will be unlockable after a year, incentivizing early adopters to contribute to the protocol's success and promoting the stability and growth of the platform.

Token Breakdown

Available at TGE (100% unlocked)&#x20;

* 1% Fjord&#x20;
* 1% Dex MM&#x20;
* 10% Airdrop recipients  (Early Adopters, Zealy, Lock-drop, Lenders, and Borrowers Pre-TGE)

Tokens Locked (2-year vest including a 1-year Cliff)

* 21.09% Team&#x20;
* 7.00% Advisors
* 24.82% Private Sale

DAO Treasury for Emissions through $bdBLB&#x20;

* 35.09%&#x20;

Total 1 Billion tokens


# Contracts

Blueberry Bank Components

## Blueberry Bank Components

### Blueberry Bank product is mainly composed of 5 components:

1. [**Blueberry Bank Contract:**](/developer-guides/contracts/blueberry-bank/introduction) the main contract that stores users\` positions and tracks the borrowing of tokens.
2. [**Blueberry Oracle Contracts**](/developer-guides/contracts/oracle)**:** The contracts that identify position values and token prices.
3. [**Blueberry Spell Contract**](/developer-guides/contracts/spell)**:** the contracts which define the specific deployment of the strategy in the spell. E.g. The contract interacts with DEXes and wrapper contracts to open/close users' positions.
4. [**Blueberry Vault Contracts**](/developer-guides/contracts/vault)**:**&#x20;
   1. [**Blueberry SoftVault Contracts**](/developer-guides/contracts/vault/softvault)**:** The contracts that allow users to lend tokens (ERC20) and earn lending interest (interest rate is reflected from how much users borrow the token (Active utilization rate)). This is using the underlying Blueberry Money Market (Compound Fork) [Lending Protocol](/lending-protocol/overview)
   2. [**Blueberry HardVault Contracts**](/developer-guides/contracts/vault/hardvault)**:** The contracts that allow users to lock LP (ERC1155) tokens as collateral.
5. [**Blueberry Wrapper Contracts**](/developer-guides/contracts/wrapper)**:** the contracts that handle the farming process (i.e. deposit into Masterchef contract) and wrap/unwrap user's collateral and forward wrapped tokens to bank/spells.

{% content-ref url="/pages/oqpdT3035GOpUSFNi1js" %}
[Deployed Contracts](/developer-guides/deployed-contracts)
{% endcontent-ref %}


# Blueberry Bank


# Introduction

These are the main contracts of Blueberry, responsible for being a record of storage, setting fees, and deployments.&#x20;

[BlueberryBank.sol](/developer-guides/contracts/blueberry-bank/blueberry-bank-contract) is the main contract that users interact with. It is important as it stores the user's positions and tracks the borrowing of tokens.&#x20;

* [Fee Manager](/developer-guides/contracts/blueberry-bank/fee-manager): Defines the types of fees taken in the protocol.
* [ProtocolConfig](/developer-guides/contracts/blueberry-bank/protocolconfig): Defines all configurable states of the protocol.


# Blueberry Bank Contract

about`BlueberryBank.sol` is a smart contract that implements a bank in which users can borrow and lend different tokens, as well as keep track of their positions. The contract includes the following functionalities:

* Allowing borrowing, lending, and repaying different tokens
* Tracking the state of each position and storing position data
* Implement a borrowing limit for each user's position
* Use an oracle to determine token prices
* Implement a fee system for borrowing, lending, and deployment inside of the protocol

{% content-ref url="/pages/Twxt08r8nQz04EEv4v8n" %}
[Variables](/developer-guides/contracts/blueberry-bank/blueberry-bank-contract/variables)
{% endcontent-ref %}

{% content-ref url="/pages/GUe9En7y0DiptLls68rX" %}
[Modifiers](/developer-guides/contracts/blueberry-bank/blueberry-bank-contract/modifiers)
{% endcontent-ref %}

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(ICoreOracle oracle_, IProtocolConfig config_) external initializer 
```

{% endcode %}

This function initializes the bank smart contract by setting the Oracle smart contract, the Protocol config address, and the Fee manager address. It also initializes some internal state variables. The function can only be called by the contract owner.

**Parameters:**

<table><thead><tr><th width="232">Name</th><th width="120.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>oracle</code></td><td>address</td><td>The oracle smart contract address</td></tr><tr><td><code>config_</code></td><td>address</td><td>The Protocol config smart contract adress</td></tr></tbody></table>

#### EXECUTOR

```solidity
function EXECUTOR() external view override returns (address) 
```

This function returns the current executor of the smart contract, which is the owner of the current position. If there is no position under execution, it reverts with an error.

**Parameters:**

* `address` - the address of the current position owner

#### setAllowContractCalls

{% code overflow="wrap" %}

```solidity
function setAllowContractCalls(bool ok) external onlyOwner 
```

{% endcode %}

This function sets the `allowContractCalls` flag to allow or disallow contract calls. If `allowContractCalls` is set to `true`, then only externally-owned accounts (EOAs) can call the contract. This function can only be called by the contract owner.

**Parameters**

* `ok` - The status to set `allowContractCalls` to. If `false`, only EOA can call the contract.

#### whitelistContract

{% code overflow="wrap" %}

```solidity
whitelistContracts(address[] calldata contracts, bool[] calldata statuses) external onlyOwner
```

{% endcode %}

This function sets the status of the given contracts in the whitelist. The function can only be called by the contract owner.

**Parameters:**

<table><thead><tr><th width="192">Name</th><th width="92.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>contracts</code></td><td>Array</td><td>An array of contract addresses to change the status of.</td></tr><tr><td><code>statuses</code></td><td>Array</td><td>An array of boolean values to change the status of the corresponding contract address in <code>contracts</code>.</td></tr></tbody></table>

#### whitelistSpells

{% code overflow="wrap" %}

```solidity
whitelistSpells(address[] calldata spells, bool[] calldata statuses) external onlyOwner
```

{% endcode %}

This function sets the status of the given spells in the whitelist. The function can only be called by the contract owner.

**Parameters:**

<table><thead><tr><th width="192">Name</th><th width="92.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>spells</code></td><td>Array</td><td>An array of contract addresses to change the status of.</td></tr><tr><td><code>statuses</code></td><td>Array</td><td>An array of boolean values to change the status of the corresponding contract address in <code>spells</code>.</td></tr></tbody></table>

#### whitelistTokens

{% code overflow="wrap" %}

```solidity
whitelistTokens(address[] calldata tokens, bool[] calldata statuses) external onlyOwner
```

{% endcode %}

This function sets the status of the given tokens in the whitelist. It also checks whether the given tokens are supported by the Oracle smart contract. The function can only be called by the contract owner.

**Parameters:**

<table><thead><tr><th width="192">Name</th><th width="92.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokens</code></td><td>Array</td><td>An array of contract addresses to change the status of.</td></tr><tr><td><code>statuses</code></td><td>Array</td><td>An array of boolean values to change the status of the corresponding contract address in <code>tokens</code>.</td></tr></tbody></table>

#### whitelistERC1155

```solidity
whitelistERC1155(address[] memory tokens, bool ok) external onlyOwner
```

This function sets the status of the given ERC1155(wrapped tokens) in the whitelist. The function can only be called by the contract owner.

**Parameters:**

<table><thead><tr><th width="192">Name</th><th width="92.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokens</code></td><td>Array</td><td>An array of contract addresses to change the status of.</td></tr><tr><td><code>ok</code></td><td>bool</td><td>The status of the corresponding whitelisted wrapped tokens in <code>tokens</code>.</td></tr></tbody></table>

#### **addBank**

{% code overflow="wrap" %}

```solidity
addBank(address token, address softVault, address hardVault, uint256 liqThreshold) external onlyOwner onlyWhitelistedToken(token)
```

{% endcode %}

This function adds a new bank to the ecosystem. It creates a new `Bank` struct and sets its properties, such as the underlying token for the bank and the address of the soft and hard vaults. It also checks whether the `bToken` for the soft vault has already been added to any other bank. If the `bToken` has already been added to a bank, it reverts with an error. The function can only be called by the contract owner.

**Parameters:**

<table><thead><tr><th width="172.33333333333331">Name</th><th width="165">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>Address</td><td>The address of the underlying token for the bank</td></tr><tr><td><code>softvault</code></td><td>Address</td><td>The address of the soft vault for the bank</td></tr><tr><td><code>hardvault</code></td><td>Address</td><td>The address of the hard vault for the bank</td></tr><tr><td><code>liqThreshold</code></td><td>uint256</td><td>The numerical value for liquidation threshold for the bank</td></tr></tbody></table>

#### setBankStatus

{% code overflow="wrap" %}

```solidity
setBankStatus(uint256 _bankStatus) external onlyOwner
```

{% endcode %}

This function is used to set the bank status to a new value. Only callable by the owner

**Parameters:**

| Name          | Type    | Description                      |
| ------------- | ------- | -------------------------------- |
| `_bankStatus` | uint256 | The new bank status value to set |

**Modifiers**

* `onlyOwner` : Only the contract owner can call this function

**Return**

* None

#### isBorrowerAllowed

{% code overflow="wrap" %}

```solidity
function isBorrowAllowed() public view returns (bool) 
```

{% endcode %}

This function is used to check whether borrowing is allowed for the bank or not

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

* bool: Returns true if borrowing is allowed, false otherwise.

#### isRepayAllowed

{% code overflow="wrap" %}

```solidity
function isRepayAllowed() public view returns (bool) 
```

{% endcode %}

This function is used to check whether repaying is allowed for the bank or not

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

* bool: Returns true if repaying is allowed, false otherwise.

#### isLendAllowed

{% code overflow="wrap" %}

```solidity
function isLendAllowed() public view returns (bool) 
```

{% endcode %}

This function is used to check whether lending is allowed for the bank or not

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

* bool: Returns true if lending is allowed, false otherwise.

#### isWithdrawLendAllowed

{% code overflow="wrap" %}

```solidity
function isWithdrawLendAllowed() public view returns (bool) 
```

{% endcode %}

This function is used to check whether withdrawing lending is allowed for the bank or not

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

* bool: Returns true if withdrawing lend is allowed, false otherwise.

#### accrue

{% code overflow="wrap" %}

```solidity
function accrue(address token) public override 
```

{% endcode %}

This function is used to trigger interest accrual for the given bank.

**Parameters:**

<table><thead><tr><th width="146.33333333333331">Name</th><th width="171">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The underlying token for which interest accrual needs to be triggered</td></tr></tbody></table>

#### accrueAll

{% code overflow="wrap" %}

```solidity
function accrueAll(address[] memory token) external 
```

{% endcode %}

This function is used to trigger interest accrual for a list of banks.

**Parameters:**

<table><thead><tr><th width="146.33333333333331">Name</th><th width="171">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokens</code></td><td>array</td><td>The list of underlying tokens for which interest accrual needs to be triggered.</td></tr></tbody></table>

**Modifiers:**

* None

**Return:**

* None

#### \_borrowBalanceStored

{% code overflow="wrap" %}

```solidity
function _borrowBalanceStored(address token) internal view returns (uint256)
```

{% endcode %}

This internal function is used to get the stored borrow balance for the given token

**Parameters:**

<table><thead><tr><th width="146.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The underlying token for which the stored borrow balance needs to be retrieved</td></tr></tbody></table>

**Modifiers:**

* None

**Return:**

* uint256: The stored borrow balance for the given token.

#### currentPositionDebt

{% code overflow="wrap" %}

```solidity
function currentPositionDebt(uint256 positionId) public view returns (uint256 debt)
```

{% endcode %}

This function returns the debt of a given position considering the debt interest stored. &#x20;

**Parameters**:

<table><thead><tr><th width="158.33333333333331">Name</th><th width="166">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The ID of the position to query for the debt balance</td></tr></tbody></table>

**Return:**

* `debt` uint256: The current debt balance of the specified position.

#### getPositionDebt

{% code overflow="wrap" %}

```solidity
function getPositionDebt(uint256 positionId) public view returns (uint256 debt)
```

{% endcode %}

This function returns the debt of the specified position considering the debt interest stored. The function should be called after calling the `accrue` function to get the current debt.

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="161">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The ID of the position to query for the debt balance</td></tr></tbody></table>

**Modifiers:**

* None

**Returns:**

* `debt` (uint256): The debt balance of the specified position.

#### getBankInfo

{% code overflow="wrap" %}

```solidity
function getBankInfo(address token) external view override returns (bool isListed, address bToken, uint256 totalShare)
```

{% endcode %}

This function returns the bank information for the specified token.

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The token address to find the specific bank information</td></tr></tbody></table>

**Modifiers:**

* None

**Returns:**

* `isListed` (bool): True if the specified token is listed in the banks, otherwise false
* `bToken` (address): The address of the associated bToken contract for the specified token
* `totalShare` (uin256): The total share of the specified token in the bank

#### getPositionInfo

{% code overflow="wrap" %}

```solidity
function getPositionInfo(uint256 positionId) external view override returns (Position memory)
```

{% endcode %}

This function returns the information of the specified position.

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for position information</td></tr></tbody></table>

**Modifiers:**

* None

**Returns:**

* `Position` (struct): The information about the specified position

#### getCurrentPositionInfo

{% code overflow="wrap" %}

```solidity
function getCurrenPositionInfo() external view override returns (Position memory)
```

{% endcode %}

This function returns the information about the current position

**Returns:**

* `Position` (struct): The information about the current position

**Modifiers:**

* `if (POSITION_ID == _NO_ID)`: MODIFIES THE FUNCTION TO CHECK IF `POSITION_ID` is not equal to `_NO_ID` before executing the function.

#### getPositionValue

{% code overflow="wrap" %}

```solidity
function getPositionValue(uint256 positionId) public view override returns (uint256 positionValue)
```

{% endcode %}

This function returns the USD value of the total collateral of the specified position considering yields generated from the collaterals.

**Parameters**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for position value information</td></tr></tbody></table>

**Return:**

* `positionValue` (uin256): The USD value of the total collateral of the specified position.

#### getDebtValue

{% code overflow="wrap" %}

```solidity
function getDebtValue(uint256 positionId) public view override returns (uint256 debtValue)
```

{% endcode %}

This function should be called to get the current USD value of a position's debt. This function should be called after calling `accrue()` to get the current debt balance.

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for position debt value information</td></tr></tbody></table>

**Return:**

* `debtValue` (uint256): The USD value of the position's debt

#### getIsolatedCollateralValue

{% code overflow="wrap" %}

```solidity
function getIsolatedCollateralValue(uint256 positionId) public view override returns (uint256 icollValue)
```

{% endcode %}

This function returns the USD value of the isolated collateral of a given position. It takes into consideration the stored lending interest in the position. This function should be called after calling `accrue()` to get the current debt.

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for position's isolated collateral value information</td></tr></tbody></table>

**Return:**

* `icollValue` (uint256): The USD value of the position's collateral.&#x20;

#### getPositionRisk

{% code overflow="wrap" %}

```solidity
function getPositionRisk(uint256 positionId) public view returns (uint256 risk)
```

{% endcode %}

This function calculates the risk ratio of a given position, which represents the degree of risk associated with the position. The higher the risk ratio, the higher the risk. By taking into consideration the following factors:

* `pv` (uint256): The position value
* `ov` (uint256): The debt value
* `cv` (uint256): The isolated collateral value

If the position is closed or overcollateralized, the risk is set to 0.  If there is no isolated collateral or there is an error with the isolated underlying token, the risk is set to the maximum value of `Constants.DENOMINATOR`. Otherwise, the risk is calculated as `(ov - pv) * Constants.DENOMINATOR / cv`

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for the position's risk</td></tr></tbody></table>

**Returns:**

* `risk` (uint256): The calculated risk ratio

#### isLiquidatable

{% code overflow="wrap" %}

```solidity
function isLiquidatable(uint256 positionId) public view returns (bool)
```

{% endcode %}

This function checks whether a given position can be liquidated by first calculating its risk ratio using the `getPositionRisk` function. It then compares the risk ratio to the liquidation threshold defined in the oracle for the underlying token of the position. If the risk ratio is higher than or equal to the liquidation threshold, the position is considered liquidatable and the function returns `true`. Otherwise, the function returns `false`.

**Parameters:**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="184">Type </th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for the position's liquidation status.</td></tr></tbody></table>

**Returns:**

* &#x20;bool: A boolean value indicating whether the position is liquidatable or not.

#### liquidate

{% code overflow="wrap" %}

```solidity
function liquidate(uint256 positionId, address debtToken, uint256 amountCall) external override lock poke(debtToken) 
```

{% endcode %}

This function liquidates a position, paying off its debt for the original owner and taking the collateral of the position.

**Parameters:**

<table><thead><tr><th width="162.33333333333331">Name</th><th width="111">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The ID of the position to liquidate</td></tr><tr><td><code>debtToken</code></td><td>address</td><td>The debt token to repay</td></tr><tr><td><code>amountCall</code></td><td>uint256</td><td>The amount ot repay when doing <code>transferFrom</code> call</td></tr></tbody></table>

**Details:**

1. Check if the repay operation is allowed
2. Check if the `amountCall` parameter is non-zero
3. Check if the position is liquidatable using the `isLiquidatable` function
4. Retrieve the position and bank information
5. Calculate the amount paid and the share of the debt to repay using the `_repay` function
6. Calculate the liquidation size and the share of the underlying vault using the `oldShare` value, the `collateralSize`, and the `underlyingValueShare` fields of this position
7. Update the `collateralSize` and `underlyingVaultShare` fields of the position
8. Transfer the position (wrapped LP tokens) to the liquidator using the `safeTransferFrom` function of the ERC1155 token
9. Transfer the underlying collateral (vault share tokens) to the liquidator using the `safeTransfer` function of the ERC20 token for a soft vault or the `safeTransferFrom` function of the ERC1155 token for a hard vault.
10. Emit the `positionId` of the position liquidated, `msg.sender` the address of the liquidator, `debtToken` The token address that got repaid, `amountPaid` How much did the liquidator pay to the bank, `share` the share of the vault tokens, `liqSize` how large the liquidation was, and `uVaultShare` the underlying vault token share.

#### execute

{% code overflow="wrap" %}

```solidity
function execute(uint256 positionId, address spell, bytes memory data) external lock onlyEOAEx returns (uint256)
```

{% endcode %}

This function allows the called to execute a spell with supplied data. The spell must be whitelisted before execution. If the positionID is zero, a new position will be created. If it is not zero, the function will check if the position exists, and is owned by the caller, and if not, it will revert. The function will set the global variables `POSITION_ID` and `SPELL` to the supplied `positionID` and `spell`, respectively. It will then execute the spell with the supplied data and handle any errors that may occur. Finally, it will check if the position is liquidatable and emit an event.

**Modifiers**

* `onlyEOAEx`: The function can only be called by an externally-owned account that is executing a spell

**Parameters**

| Name         | Type         | Description                                                     |
| ------------ | ------------ | --------------------------------------------------------------- |
| `positionId` | uint256      | The position ID to execute the action, or zero for new position |
| `spell`      | address      | The target spell to invoke the execution                        |
| `data`       | bytes memory | Extra data to pass to the target for the execution              |

**Return:**

* (uint256): The position ID that was executed and created.

#### lend

{% code overflow="wrap" %}

```solidity
function lend(address token, uint256 amount) external override inExec poke(token) onlyWhitelistedToken(token)
```

{% endcode %}

This function allows the called to lend tokens to the bank as isolated collateral. The function must be called while under execution. The token must be whitelisted before lending.&#x20;

**Modifiers:**

* `inExec`: The function can only be called while under execution
* `poke(token)`: The function will poke the token before execution to ensure its balance and allowance is up-to-date
* `onlyWhitelistedToken(token)`: The function can only be called with a whitelisted token

**Parameters**

<table><thead><tr><th width="183.33333333333331">Name</th><th width="224">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The token to be deposited in the bank as isolated collateral</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The amount of tokens to be lent</td></tr></tbody></table>

#### withdrawLend

{% code overflow="wrap" %}

```solidity
function withdrawLend(address token, uint256 shareAmount) external override inExec poke(token)
```

{% endcode %}

This function withdraws isolated collateral tokens that were lent to the bank. It first checks if the withdrawLend function is allowed to execute. It then retrieves the Position storage and Bank memory objects from their respective mappings. If the token address does not match the underlying token address in the Position storage, the function throws an `INVALID_UTOKEN` error.

If `shareAmount` is equal to `type(uint256).max`, the function sets `shareAmount` to the underlyingVaultShare stored in the Position storage.

The function then calculates the amount to withdraw using either the softVault or hardVault. If `_isSoftVault(token)` returns true, the function calls the `approve` and `withdraw` functions of the `ISoftVault` interface. If it returns false, the function calls the `withdraw` function of the `IHardVault` interface.

After the tokens are withdrawn, the underlyingVaultShare stored in the Position storage is updated, the tokens are approved for transfer to the `feeManager` contract, and the withdrawal fee is taken by calling the `doCutWithdrawFee` function of the `feeManager` contract. Finally, the tokens are transferred to the caller.

**Modifiers:**

* `inExec`: This modifier checks if the function is being called from the spell contract while under execution
* `poke`: This modifier updates the state of the contract by calling the poke method with the given token address

**Parameters:**

<table><thead><tr><th width="183.33333333333331">Name</th><th width="224">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The token address of the isolated collateral token to be withdrawn</td></tr><tr><td><code>shareAmount</code></td><td>uint256</td><td>The number of share tokens to be withdrawn</td></tr></tbody></table>

#### borrow

{% code overflow="wrap" %}

```solidity
function borrow(address token, uint256 amount) external override inExec poke(token) onlyWhitelistedToken(token) returns (uint256 borrowedAmount)
```

{% endcode %}

This function allows the caller to borrow tokens from the bank. It first checks if the borrow function is allowed to execute. It then retrieves the Bank storage and Position storage objects from their respective mappings. If the Position storage has no debt token set, it sets the token. This function can only be called from the spell contract while under execution

**Modifiers:**

* `inExec`: This modifier checks if the function is being called from the spell contract while under execution
* `poke`: This modifier updates the state of the contract by calling the poke method with the given token address
* `onlyWhitelistedToken`: This modifier checks if the given token address is whitelisted&#x20;

**Parameters:**

<table><thead><tr><th width="183.33333333333331">Name</th><th width="224">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The token to borrow from the bank</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The number of tokens to borrow</td></tr></tbody></table>

**Return:**

* `borrowedAmount` (uint256): The number of tokens borrowed.

#### repay

{% code overflow="wrap" %}

```solidity
function repay(address token, uint256 amountCall) external override inExec poke(token) onlyWhitelistedToken(token)
```

{% endcode %}

This function allows a user to repay a specific token to the bank. It should only be called during execution. Before executing the function, it checks whether the repay is allowed. If the repay is not allowed, it will revert with an error message.

The function then calls the internal function `_repay()` with the position ID, token, and amountCall as parameters. `_repay()` calculates the amount to be repaid and the corresponding debt share reduced. The function then emits a `Repay` event with the relevant parameters.

**Modifiers:**

* `inExec`: This modifier checks if the function is being called from the spell contract while under execution
* `poke`: This modifier updates the state of the contract by calling the poke method with the given token address
* `onlyWhitelistedToken`: This modifier checks if the given token address is whitelisted&#x20;

**Parameters:**&#x20;

<table><thead><tr><th width="183.33333333333331">Name</th><th width="224">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The token to be repaid to the bank</td></tr><tr><td><code>amountCall</code></td><td>uint256</td><td>The number of tokens to be repaid via <code>transferFrom</code></td></tr></tbody></table>

#### \_repay

{% code overflow="wrap" %}

```solidity
function _repay(uint256 positionId, address token, uint256 amountCall) internal returns (uint256, uint256)
```

{% endcode %}

This function is used to perform a repayment action on a given position ID, using the specified token. It returns the amount actually taken and the debt share reduced. The debt token of the position must match the specified token, otherwise, the function will revert. The amount to repay must not exceed the old debt, otherwise, the function will revert. The function must be called while under execution.

**Parameters:**

<table><thead><tr><th width="183.33333333333331">Name</th><th width="173">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>positionId</code></td><td>uint256</td><td>The position ID to query for repayment of debt</td></tr><tr><td><code>token</code></td><td>address</td><td>The token to be repaid to the bank</td></tr><tr><td><code>amountCall</code></td><td>uint256</td><td>The number of tokens to be repaid via <code>transferFrom</code></td></tr></tbody></table>

**Returns:**

<table><thead><tr><th width="180.33333333333331">Name</th><th width="88">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>paid</code></td><td>uint</td><td>The amount actually taken from the user</td></tr><tr><td><code>lessShare</code></td><td>uint</td><td>The debt share reduced from the position after repayment.</td></tr></tbody></table>

#### putCollateral

{% code overflow="wrap" %}

```solidity
function putCollateral(address collToken, uint256 collId, uint256 amountCall) external override inExec
```

{% endcode %}

This function allows users to put more collateral into their position. The function first checks if the collateral token being used is the same as the one already specified in the position. If not, it checks if the oracle supports the wrapped token of the LP address. If the collateral size of the position is greater than zero, it reverts. If both checks pass, the collateral token and ID are updated in the position.

The function then calls the internal \_doERC1155TransferIn() function to transfer the ERC1155 tokens from the user's wallet to the contract. The amount of tokens transferred is added to the position's collateral size. An event PutCollateral() is then emitted to signify that collateral has been added to the position.

**Modifiers:**&#x20;

* `inExec` Can only be called during execution

**Parameters:**

<table><thead><tr><th width="164.33333333333331">Name</th><th width="129">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>collToken</code></td><td>address</td><td>The address of the token that will be used as collateral</td></tr><tr><td><code>collId</code></td><td>uint256</td><td>The token ID that corresponds to the specific ERC1155 toke being used as collateral.</td></tr><tr><td><code>amountCall</code></td><td>uint256</td><td>The amount of ERC1155 tokens to be put as collateral by calling <code>transferFrom</code></td></tr></tbody></table>

#### takeCollateral

{% code overflow="wrap" %}

```solidity
function takeCollateral(uint256 amount) external override inExec returns (uint256)
```

{% endcode %}

This function allows users to take some of their collateral back. It must only be called during execution. The function first retrieves the position from the positions mapping. If the amount to be taken back is set to the maximum uint256 value, it sets the amount to the full collateral size of the position. Then, it reduces the collateral size of the position by the amount being taken back.

The function then calls the safeTransferFrom() function of the IERC1155Upgradeable interface to transfer the ERC1155 tokens from the contract back to the user's wallet. An event TakeCollateral() is emitted to signify that collateral has been taken back from the position. The amount of tokens taken back is returned.

**Modifiers:**&#x20;

* `inExec` Can only be called during execution

**Parameters:**

* `amount` (uint256): The amount of ERC1155 tokens to be taken back by transfer

#### \_doBorrow

{% code overflow="wrap" %}

```solidity
function _doBorrow(address token, uint256 amountCall) internal returns (uint256 borrowAmount)
```

{% endcode %}

This function is used to perform a borrow from a bank and returns the amount borrowed.&#x20;

**Parameters:**

| Name         | Type    | Description                                  |
| ------------ | ------- | -------------------------------------------- |
| `token`      | address | The token address to perform borrow action   |
| `amountCall` | uint256 | The amount ot use in the `transferFrom` call |

**Returns:**

* `borrowAmount` (uint256): The amount actually borrowed from the bank

#### \_doRepay

{% code overflow="wrap" %}

```solidity
function _doRepay(address token, uint256 amountCall) internal returns (uint256 repaidAmount)
```

{% endcode %}

This function is used to perform a repay to the bank and returns the amount actually repaid.&#x20;

**Parameters:**

| Name         | Type    | Description                                 |
| ------------ | ------- | ------------------------------------------- |
| `token`      | address | The token address to perform repay action   |
| `amountCall` | uint256 | The amount ot use in the `repayBorrow` call |

**Returns:**

* `repaidAmount` (uint256): The amount actually repaid to the bank

#### \_doERC20TransferIn

{% code overflow="wrap" %}

```solidity
function _doERC20TransferIn(address token, uint256 amountCall) internal returns (uint256)
```

{% endcode %}

This function is used to perform an ERC20 transfer-in and return the amount actually received.

**Parameters:**

| Name         | Type    | Description                                  |
| ------------ | ------- | -------------------------------------------- |
| `token`      | address | The token address to perform transfer action |
| `amountCall` | uint256 | The amount ot use in the `transferFrom` call |

**Returns:**

* (uint256): The amount actually received from the transfer

#### \_doERC1155TransferIn

{% code overflow="wrap" %}

```solidity
function _doERC1155TransferIn(address token, uint256 id, uint256 amountCall) internal returns (uint256)
```

{% endcode %}

This function is used to perform an ERC1155 transfer-in and return the amount actually received.

**Parameters:**

| Name         | Type    | Description                                  |
| ------------ | ------- | -------------------------------------------- |
| `token`      | address | The token address to perform transfer action |
| `id`         | uint256 | The id to perform the transfer action for    |
| `amountCall` | uint256 | The amount ot use in the `transferFrom` call |

**Returns:**

* (uint256): The amount actually received from the transfer

#### \_isSoftVault

{% code overflow="wrap" %}

```solidity
function _isSoftVault(address token) internal view returns (bool)
```

{% endcode %}

This function checks whether the given `token` address corresponds to a soft vault or hard vault. The function accesses the `banks` mapping to retrieve the `softVault` address for the given `token`. It then calls the `uToken()` function of the `ISoftVault` interface to get the underlying token address of the soft vault. If the retrieved underlying token address is equal to the given `token`, then the vault is a soft vault and the function returns `true`. Otherwise, it returns `false`.

**Parameters:**

* `token` (address): The token address to check

**Returns:**

* `bool` : `true` if the vault is a soft vault, `false` if it is a hard vault

#### \_ensureApprove

{% code overflow="wrap" %}

```solidity
function _ensureApprove(address token, address spender, uint256 amount) internal
```

{% endcode %}

This function is used to reset the approval for `spender` to zero and set it again to `amount`. The function calls the `approve` function of the `IERC20Upgradeable` interface to reset the approval to zero and then calls it again to set the approval to `amount`

**Parameters:**

| Name      | Type    | Description                           |
| --------- | ------- | ------------------------------------- |
| `token`   | address | the token adress to approve           |
| `spender` | address | the address of the spender to approve |
| `amount`  | uint256 | the amount to approve                 |


# Variables

The following are the most important variables used in the contract:

* `_NOT_ENTERED`: a constant that indicates that the lock is not entered
* `_ENTERED`: a constant that indicates that the lock is entered
* `_NO_ID`: a constant that indicates that there is no position ID
* `_NO_ADDRESS`: a constant that indicates that there is no address
* `_GENERAL_LOCK`: a variable that is used as a lock to prevent reentrancy attacks
* `_IN_EXEC_LOCK`: a variable that is used as a lock to avoid potential race conditions
* `POSITION_ID`: a variable that indicates the position ID currently under execution
* `SPELL`: a variable that indicates the spell currently under execution
* `config`: an instance of `IProtocolConfig` that stores the protocol configuration
* `oracle`: an instance of `ICoreOracle` that stores the address of the oracle contract
* `feeManager`: an instance of `IFeeManager` that stores the address of the fee manager contract
* `nextPositionId`: a variable that stores the next available position ID, starting from 1
* `bankStatus`: a variable that stores the status of the bank, each bit stores a certain bank status, e.g. borrow allowed, repay allowed
* `allBanks`: an array that stores the list of all listed banks
* `banks`: a mapping from token to bank data
* `bTokenInBank`: a mapping from bToken to its existence in bank
* `positions`: a mapping from position ID to position data
* `allowContractCalls`: a boolean variable that determines whether to allow calls from contracts or not
* `whitelistedTokens`: a mapping from token to whitelist status
* `whitelistedSpells`: a mapping from spell to whitelist status
* `whitelistedContracts`: a mapping from user to whitelist status


# Modifiers

#### onlyEOAEx()

This modifier ensures that the function is called from an externally owned account (EOA) when the `allowContractCalls` variable is set to `false` and the caller is not whitelisted. If the caller is a contract and is not whitelisted, the modifier will revert with an error message.

**Parameters**

* None

**Errors**

* `NOT_EOA(address)` - If the caller is a contract and is not whitelisted, this error is thrown.

**Example Usage**

{% code overflow="wrap" %}

```solidity
function myFunction() public onlyEOAEx() {
    // Only executable by an externally owned account that is whitelisted or if allowContractCalls is true.
}
```

{% endcode %}

#### onlyWhitelistedToken(address token)

This modifier ensures that the token is already whitelisted. If the token is not whitelisted, the modifier will revert with an error message.

**Parameters**

* `token` - The address of the token to check if it's whitelisted.

**Errors**

* `TOKEN_NOT_WHITELISTED(address)` - If the token is not whitelisted, this error is thrown.

**Example Usage**

{% code overflow="wrap" %}

```solidity
function myFunction(address token) public onlyWhitelistedToken(token) {
    // Only executable with a whitelisted token.
}
```

{% endcode %}

#### lock()

This modifier ensures that the function is not reentrant. If the function is currently being executed, the modifier will revert with an error message.

**Parameters**

* None

**Errors**

* `LOCKED()` - If the function is currently being executed, this error is thrown.

**Example Usage**

{% code overflow="wrap" %}

```solidity
function myFunction() public lock() {
    // Only executable if no other function is currently executing.
}
```

{% endcode %}

#### inExec()

This modifier ensures that the function is called from within the execution scope. The `POSITION_ID` must be set to a non-zero value and the `SPELL` variable must be set to the address of the calling contract. If the function is currently being executed or the execution scope has not been set, the modifier will revert with an error message.

**Parameters**

* None

**Errors**

* `NOT_IN_EXEC()` - If the function is not called from within the execution scope, this error is thrown.
* `NOT_FROM_SPELL(address)` - If the caller is not the `SPELL` contract, this error is thrown.
* `LOCKED()` - If the function is currently being executed or the execution scope has not been set, this error is thrown.

**Example Usage**

{% code overflow="wrap" %}

```solidity
function myFunction() public inExec() {
    // Only executable if called from within the execution scope.
}
```

{% endcode %}

#### poke(address token)

This modifier ensures that the interest rate of the given token is accrued before executing the function. If the token's interest rate has not been accrued, the modifier will accrue the interest rate before executing the function.

**Parameters**

* `token` - The address of the token to accrue interest rate

**Errors**

* None

**Example Usage**

{% code overflow="wrap" %}

```solidity
function myFunction(address token) public poke(token) {
    // Only executable if the interest rate of the token has been accrued.
}
```

{% endcode %}


# Fee Manager

### Intro

The `FeeManager` contract is used to calculate and collect fees from various operations within the Blueberry protocol, such as depositing, withdrawing, and generating rewards. The contract is responsible for deducting fees from the relevant token amounts and transferring them to the designated treasury address.

### Contract Overview

The FeeManager contract is implemented in Solidity programming language with version 0.8.16. It is imported with the `OwnableUpgradeable` and `SafeERC20Upgradeable` contracts from the OpenZeppelin library, which are used for access control and safe ERC20 token transfers, respectively.

The contract implements four public functions for cutting fees from token transactions: `doCutDepositFee`, `doCutWithdrawFee`, `doCutRewardsFee`, and `doCutVaultWithdrawFee`. Each function takes the relevant token address and amount as input parameters and calls the internal function `_doCutFee` to calculate and collect the fee.

### &#x20;Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(IProtocolConfig config_) external initializer
```

{% endcode %}

This function is an initializer function that sets the `config` variable, which is an interface to the main Blueberry protocol configuration contract. The function also uses the `__Ownable_init()` function from the `OwnableUpgradeable` contract to initialize the owner of the contract.

#### &#x20;doCutDepositFee

{% code overflow="wrap" %}

```solidity
function doCutDepositFee(address token, uint256 amount) external returns (uint256)
```

{% endcode %}

This function cuts the deposit fee from the specified token `amount` and transfers it to the treasury address. The fee rate is obtained from the `config` variable using the `depositFee` function. The function then returns the amount of the token after the fee has been deducted.

#### doCutWithdrawFee

{% code overflow="wrap" %}

```solidity
function doCutWithdrawFee(address token, uint256 amount) external returns (uint256)
```

{% endcode %}

This function cuts the withdraw fee from the specified token `amount` and transfers it to the treasury address. The fee rate is obtained from the `config` variable using the `withdrawFee` function. The function then returns the amount of the token after the fee has been deducted.

#### doCutRewardsFee

{% code overflow="wrap" %}

```solidity
function doCutRewardsFee(address token, uint256 amount) external returns (uint256)
```

{% endcode %}

This function cuts the performance fee from the specified token `amount` and transfers it to the treasury address. The fee rate is obtained from the `config` variable using the `rewardFee` function. The function then returns the amount of the token after the fee has been deducted.

#### doCutVaultWithdrawFee

{% code overflow="wrap" %}

```solidity
function doCutVaultWithdrawFee(address token, uint256 amount) external returns (uint256)
```

{% endcode %}

This function cuts the withdraw fee from the specified token `amount` only if the withdraw transaction is executed within a given window of time (2 months). The fee rate is obtained from the `config` variable using the `withdrawVaultFee` function. The function then returns the amount of the token after the fee has been deducted, or the full `amount` if the withdraw transaction is executed outside the withdraw fee window.

#### \_doCutFee

{% code overflow="wrap" %}

```solidity
function _doCutFee(address token, uint256 amount, uint256 feeRate) internal returns (uint256)
```

{% endcode %}

This function is an internal function that cuts a fee from a specified token `amount` based on the given `feeRate` and transfers the fee amount to the treasury address. The function returns the amount of the token after the fee has been deducted.


# ProtocolConfig

This contract defines a set of configurable parameters that are used throughout the protocol. It also defines a set of setter functions for these parameters that can be called by the contract owner.

### State Variables

The state variables of this contract are as follows:

* `feeManager`: an instance of the `IFeeManager` interface that manages the fees charged by the protocol.
* `depositFee`: a `uint256` that represents the deposit fee charged by the protocol as a percentage of the deposited amount (default is 0.5% or 50 basis points).
* `withdrawFee`: a `uint256` that represents the withdrawal fee charged by the protocol as a percentage of the withdrawn amount (default is 0.5% or 50 basis points).
* `rewardFee`: a `uint256` that represents the reward fee charged by the protocol as a percentage of the total reward amount (default is 10% or 1000 basis points).
* `withdrawVaultFee`: a `uint256` that represents the withdrawal fee charged by the protocol's liquidity vault (default is 1% or 100 basis points).
* `withdrawVaultFeeWindow`: a `uint256` that represents the time window during which the withdrawal fee charged by the protocol's liquidity vault is applied (default is 60 days).
* `withdrawVaultFeeWindowStartTime`: a `uint256` that represents the start time of the window during which the withdrawal fee charged by the protocol's liquidity vault is applied (default is 0).
* `maxSlippageOfClose`: a `uint256` that represents the maximum slippage of converting withdrawn reserves to debt tokens when closing a position (default is 3% or 300 basis points).
* `treasuryFeeRate`: a `uint256` that represents the percentage of the deposit/withdraw fee that is directed to the protocol's treasury (default is 0.15% or 30 basis points). \***NOT UTILIZED IN THIS VERSION YET\***
* `blbStablePoolFeeRate`: a `uint256` that represents the percentage of the deposit/withdraw fee that is directed to the protocol's stability pool (default is 0.175% or 35 basis points). \***NOT UTILIZED IN THIS VERSION YET\***
* `treasury`: an `address` that represents the wallet address of the protocol's treasury.
* `blbUsdcIchiVault`: an `address` that represents the address of the protocol's fee split for ICHI vault. \***NOT UTILIZED IN THIS VERSION YET\***
* `blbStabilityPool`: an `address` that represents the address \***NOT UTILIZED IN THIS VERSION YET\***

### Functions&#x20;

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(address treasury_) external initializer
```

{% endcode %}

This function is the initializer function which is called once when the contract is deployed. It sets the initial values for the contract's state variables such as depositFee, withdrawFee, rewardFee, treasuryFeeRate, blbStablePoolFeeRate, blbIchiVaultFeeRate, withdrawVaultFee, maxSlippageOfClose, and treasury. The `treasury_` argument is used to set the treasury address for the contract.

#### startVaultWithdrawFee

{% code overflow="wrap" %}

```solidity
function startVaultWithdrawFee() external onlyOwner
```

{% endcode %}

This function is called by the owner to start the timer for the vault withdraw fee window. It sets the `withdrawVaultFeeWindowStartTime` to the current block timestamp.

#### setDepositFee

{% code overflow="wrap" %}

```solidity
function setDepositFee(uint256 depositFee_) external onlyOwner
```

{% endcode %}

This function is called by the owner to set the deposit fee on isolated collateral provided when opening a leverage position. It sets the deposit fee to the specified `depositFee_` argument, which is capped at 20%.

#### setWithdrawFee

{% code overflow="wrap" %}

```solidity
function setWithdrawFee(uint256 withdrawFee_) external onlyOwner
```

{% endcode %}

This function is called by the owner to set the withdraw fee on isolated collateral provided when opening a leverage position. It sets the withdraw fee to the specified `withdrawFee_` argument, which is capped at 20%.

#### setWithdrawVaultFeeWindow

```solidity
function setWithdrawFeeWindow(uint256 withdrawVaultFeeWindow_) external onlyOwner
```

This function is called by the owner to set the withdraw fee window for vaults on collateral supplied to vaults. It sets the window to the specified `withdrawVaultFeeWindow_` argument, which is capped at 60 days.

#### setMaxSlippageOfClose

{% code overflow="wrap" %}

```solidity
function setMaxSlippageOfClose(uint256 slippage_) external onlyOwner 
```

{% endcode %}

This function is called by the owner to set the maximum slippage of converting withdrawn reserves to debt tokens when closing position. It sets the `maxSlippageOfClose` to the specified `slippage_` argument, which is capped at 20%.

#### setRewardFee

{% code overflow="wrap" %}

```solidity
function setRewardFee(uint256 rewardFee_) external onlyOwner 
```

{% endcode %}

This function is called by the owner to set the reward fee. This fee applies to any rewards that are earned through a leverage position. It sets the reward fee to the specified `rewardFee_` argument, which is capped at 20%.

#### setFeeDistribution  \*Not Used in this version yet\*

{% code overflow="wrap" %}

```solidity
setFeeDistribution(uint256 treasuryFeeRate_, uint256 blbStablePoolFeeRate_, uint256 blbIchiVaultFeeRate_) external onlyOwner
```

{% endcode %}

This function is called by the owner to set the fee distribution rates. It sets the `treasuryFeeRate`, `blbStablePoolFeeRate`, and `blbIchiVaultFeeRate` variables to the specified arguments, and checks that the sum of these values is equal to the `DENOMINATOR` constant defined in the `BlueBerryConst.sol` library.

#### setTreasuryWallet

{% code overflow="wrap" %}

```solidity
 function setTreasuryWallet(address treasury_) external onlyOwner
```

{% endcode %}

This function is called by the owner to set the treasury address for the contract. It sets the `treasury` variable to the specified `treasury_` argument.

#### setFeeManager

{% code overflow="wrap" %}

```solidity
function setFeeManager(address feeManager_) external onlyOwner 
```

{% endcode %}

This function is called by the owner to set the fee manager address for the contract. It sets the `feeManager` variable to the specified `feeManager_` argument.

#### setBlbUsdcIchiVault \*Not used in this version yet\*

{% code overflow="wrap" %}

```solidity
function setBlbUsdcIchiVault(address vault_) external onlyOwner
```

{% endcode %}

This function is called by the owner to set the $BLB liquidity pool against stablecoins address for the contract. It sets the `blbUsdcIchiVault` variable to the specified `vault_` argument.

#### setBlbStabilityPool \*Not used in this version yet\*

{% code overflow="wrap" %}

```solidity
function setBlbStabilityPool(address pool_) external onlyOwner
```

{% endcode %}

This function is called by the owner to set the $BLB liquidity pool against stablecoins address for the contract. It sets the `blbStabilityPool` variable to the specified `pool_` argument.


# Oracle


# Introduction

To get prices inside of the Blueberry Protocol. The usage of Oracles is required to ensure there is a fresh and valid price at all times. This ensures the safety and sustainability of the protocol.&#x20;

AggregatorOracle is a contract that provides aggregated price feeds from several oracle sources

CoreOracle is a contract that provides price feeds to the Bank contract


# AggregatorOracle

AggregatorOracle is a smart contract that provides aggregated price feeds from multiple oracle sources.

### Functions

#### \_setPrimarySources

{% code overflow="wrap" %}

```solidity
function _setPrimarySources(address token, uint256 maxPriceDeviation, IBaseOracle[] memory sources) internal
```

{% endcode %}

This function sets the primary oracle sources for a given token.

**Parameters:**

<table><thead><tr><th width="222.33333333333331">Name</th><th width="111">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>address of the token for which the primary oracle sources are being set</td></tr><tr><td><code>maxPriceDeviation</code></td><td>uint256</td><td>maximum price deviation allowed for the token's price feed</td></tr><tr><td><code>sources</code></td><td>array</td><td>an array of <code>IBaseOracle</code> contracts representing the primary oracle sources for the token</td></tr></tbody></table>

**Events:**

* `SetPrimarySources`: emitted after the primary oracle sources have been set successfully. The event contains the following parameters:
  * `token`: address of the token for which the primary oracle sources have been set.
  * `maxPriceDeviation`: maximum price deviation allowed for the token's price feed.
  * `oracles`: an array of `IBaseOracle` contracts representing the primary oracle sources for the token.

**Requirements:**

* The `token` parameter must not be the zero address.
* The `maxPriceDeviation` parameter must not be greater than `Constants.MAX_PRICE_DEVIATION` (a constant defined in `BlueBerryConst.sol`).
* The length of the `sources` array must be less than or equal to 3.
* The address of each `IBaseOracle` contract in the `sources` array must not be the zero address.

#### setPrimarySources

{% code overflow="wrap" %}

```solidity
function setPrimarySources(address token, uint256 maxPriceDeviation, IBaseOracle[] memory sources) external onlyOwner
```

{% endcode %}

This function sets the primary oracle sources for a given token, and can only be called by the owner of the contract

**Parameters:**

<table><thead><tr><th width="222.33333333333331">Name</th><th width="111">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>address of the token for which the primary oracle sources are being set</td></tr><tr><td><code>maxPriceDeviation</code></td><td>uint256</td><td>maximum price deviation allowed for the token's price feed</td></tr><tr><td><code>sources</code></td><td>array</td><td>an array of <code>IBaseOracle</code> contracts representing the primary oracle sources for the token</td></tr></tbody></table>

**Events**:

* `SetPrimarySources`: emitted after the primary oracle sources have been set successfully. The event contains the following parameters:
  * `token`: address of the token for which the primary oracle sources have been set.
  * `maxPriceDeviation`: maximum price deviation allowed for the token's price feed.
  * `oracles`: an array of `IBaseOracle` contracts representing the primary oracle sources for the token.

**Requirements:**&#x20;

* This function has the same requirements as the `_setPrimarySources` function.

#### setMultiPrimarySources

{% code overflow="wrap" %}

```solidity
function setMultiPrimarySources(address[] memory tokens, uint256[] memory maxPriceDeviationList, IBaseOracle[][] memory allSources) external onlyOwner
```

{% endcode %}

This function sets multiple primary oracle sources for multiple tokens. This function first validates the inputs by ensuring that the length of all arrays is the same. It then calls the internal function \_setPrimarySources() for each token to set its primary sources.

**Parameters:**

<table><thead><tr><th width="260.3333333333333">Name</th><th width="90">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokens</code></td><td>array</td><td>an array of addresses of the token for which the primary oracle sources are being set</td></tr><tr><td><code>maxPriceDeviationList</code></td><td>array</td><td>an array of maximum price deviations in base 10000 allowed for the token's price feed</td></tr><tr><td><code>allSources</code></td><td>array</td><td>a 2D array of primary oracle sources for each token</td></tr></tbody></table>

#### \_isValidPrices

{% code overflow="wrap" %}

```solidity
function _isValidPrices(uint256 price0, uint256 price1, uint256 maxPriceDeviation) internal pure returns (bool)
```

{% endcode %}

This is an internal function used to validate the deviation of two given prices.

**Parameters:**

<table><thead><tr><th width="221.33333333333331">Name</th><th width="160">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>price0</code></td><td>uint256</td><td>the first price in base 1e18</td></tr><tr><td><code>price1</code></td><td>uint256</td><td>the second price in base 1e18</td></tr><tr><td><code>maxPriceDeviation</code></td><td>uint256</td><td>the maximum price deviation in base 10000</td></tr></tbody></table>

#### getPrice

{% code overflow="wrap" %}

```solidity
function getPrice(address token) external view override returns (uint256)
```

{% endcode %}

This function returns the USD price of a given token. The price is multiplied by 10^18. It also supports at most 3 oracle sources per token.

**Parameters:**

* `token` (address): The address of the token to get the price of

**Return:**

* `uint256`: The USD price of the token, multiplied by 10^18

**Logic**:

1. Check if there is at least one primary oracle source for the token. If there isn't, revert with the NO\_PRIMARY\_SOURCE error.
2. Create a dynamic array of uint256 called prices with a length of candidateSourceCount, which is the number of primary oracle sources for the token.
3. Loop through each primary oracle source for the token and try to get the price. If successful, add the price to the prices array and increment the validSourceCount.
4. If there are no valid prices, revert with the NO\_VALID\_SOURCE error.
5. Sort the prices in ascending order.
6. Get the max price deviation for the token.
7. Depending on the number of valid sources, calculate the price using one of the following methods:
   * If there is only one valid source, return the price.
   * If there are two valid sources, check if the prices are within the max price deviation. If they are, return the average price. If not, revert with the EXCEED\_DEVIATION error.
   * If there are three valid sources, check if each pair of prices is within the max price deviation. If all pairs are within the deviation threshold, return the median price. If one pair is within the deviation threshold, return the average of that pair. If none of the pairs are within the deviation threshold, revert with the EXCEED\_DEVIATION error.


# CoreOracle

The contract provides price feeds to other contracts, such as the `BlueberryBank.sol` Contract

### State Variables

The `CoreOracle` contract contains the following state variables:

#### routes

{% code overflow="wrap" %}

```solidity
mapping(address => address) public routes;
```

{% endcode %}

This mapping stores the oracle source routes for tokens. For each token address `t`, the mapping stores the oracle source route address for `t`.

#### liqThresholds

{% code overflow="wrap" %}

```solidity
mapping(address => uint256) public liqThresholds;
```

{% endcode %}

This mapping stores the liquidation threshold for tokens. The number is multiplied by 1e4. For volatile tokens 85% and 90% for stablecoins as a negative Profit loss on the position in comparison to the supplied tokens as isolated collateral.

#### whitelistedERC1155

{% code overflow="wrap" %}

```solidity
mapping(address => bool) public whitelistedERC1155;
```

{% endcode %}

This mapping stores the wrapper addresses for the whitelisted status of ERC1155 tokens in the protocol.

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize() external initializer
```

{% endcode %}

This function initializes the `CoreOracle` contract. It is called during contract deployment.

#### setRoutes

{% code overflow="wrap" %}

```solidity
function setRoutes(address[] calldata tokens, address[] calldata oracleRoutes) external onlyOwner
```

{% endcode %}

This function sets the oracle source routes for tokens. It takes two arrays as inputs, `tokens` and `oracleRoutes`, both of which must have the same length. For each index `i`, the function sets the oracle source route for the token at index `i` to the address in `oracleRoutes[i]`.

#### setLiqThresholds

{% code overflow="wrap" %}

```solidity
function setLiqThresholds(address[] memory tokens, uint256[] memory thresholds) external onlyOwner
```

{% endcode %}

This function sets the token liquidation thresholds. It takes two arrays as inputs, `tokens` and `thresholds`, both of which must have the same length. For each index `i`, the function sets the liquidation threshold for the token at index `i` to the value in `thresholds[i]`.

#### setWhitelistERC1155

{% code overflow="wrap" %}

```solidity
function setWhitelistERC1155(address[] memory tokens, bool ok) external onlyOwner
```

{% endcode %}

This function whitelists ERC1155 tokens. It takes an array `tokens` of tokens to whitelist and a boolean `ok` indicating whether to whitelist or blacklist the tokens. For each token in `tokens`, the function sets its whitelist status to the value in `ok`.

#### \_getPrice

{% code overflow="wrap" %}

```solidity
function _getPrice(address token) internal view returns (uint256)
```

{% endcode %}

This internal function returns the USD price of a given token, multiplied by 10^18.

#### getPrice

{% code overflow="wrap" %}

```solidity
function getPrice(address token) external view override returns (uint256)
```

{% endcode %}

This function returns the USD price of a given token, multiplied by 10^18

#### isWrappedTokenSupported

{% code overflow="wrap" %}

```solidity
function isWrappedTokenSupported(address token,uint256 tokenId) external view override returns (bool)
```

{% endcode %}

This function returns a boolean indicating whether the oracle supports the underlying token of a given wrapper token. Only validate wrappers of Blueberry protocol such as WERC20

#### isTokenSupported

{% code overflow="wrap" %}

```solidity
function isTokenSupported(address token) external view override returns (bool)
```

{% endcode %}

This function returns a boolean indicating whether the oracle supports a given ERC20 token.


# Spell


# Introduction

These contracts are designed to facilitate borrowing, lending, and collateral management functionalities for deployments into outside protocols while utilizing the Blueberry Protocol

* [BasicSpell](/developer-guides/contracts/spell/basicspell) - Abstract contract that provides a set of functions to be implemented by its inheriting contracts.
* [AuraSpell](/developer-guides/contracts/spell/auraspell) - Contract that provides the functions to be used when interacting with Balancer Pools and stakes the BPT token on Aura.
* [ConvexSpell](/developer-guides/contracts/spell/convexspell) - Contract that provides the functions to be used when interacting with Curve Pools and stakes the LP token on Convex.&#x20;
* [IchiSpell](/developer-guides/contracts/spell/ichispell) - Contract that provides a set of functions to be used when interacting with the Ichi Vault ecosystem.&#x20;
* [LongShortSpell](/developer-guides/contracts/spell/longshortspell) - Contract that provides the functions to allow a user to go directionally long or short a specific asset.


# AuraSpell

The `AuraSpell` contract is a contract that defines how the Blueberry Protocol interacts with Aura pools. It enables users to open and close positions and interact with the Blueberry Money Market, Balancer pools, and Aura pools.&#x20;

### Contract Dependencies

#### OpenZeppelin Contracts

The contract imports `SafeERC20Upgradeable` from the OpenZeppelin Contracts Upgradeable library, which is an open-source library that provides secure and tested implementations of popular token standards and other useful utilities.

#### BasicSpell

The contract imports `BasicSpell`, which is a custom implementation that serves as the base contract for the `AuraSpell`.

#### Interfaces

The contract imports interfaces for interacting with several external contracts, including Curve Oracle, Wrapped Aura Pools, Balancer Pool, and Uniswap V2 Router02.

### State Variables

The contract has several state variables for storing contract addresses and external contract instances.

* `IWAuraPools public wAuraPools`: The address of the Wrapped Aura Pools contract.
* `ICurveOracle public crvOracle`: The address of the Curve Oracle contract.
* `address public AURA`: The address of the AURA token.

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(IBank bank_, address werc20_, address weth_, address wAuraPools_) external initializer
```

{% endcode %}

The `initialize` function initializes the contract and sets the initial state variables.

#### addStrategy

{% code overflow="wrap" %}

```solidity
function addStrategy(address bpt, uint256 maxPosSize) external onlyOwner
```

{% endcode %}

This function adds a strategy to the contract.

#### openPositionFarm

{% code overflow="wrap" %}

```solidity
function openPositionFarm(OpenPosParam calldata param) external exisitingStrategy(param.StrategyId) existingCollateral(param.strategyId, param.collToken)
```

{% endcode %}

This function adds liquidity to the Balancer pool and stakes it in the Aura pool.

#### closePositionFarm

{% code overflow="wrap" %}

```solidity
function closePositionFarm(
    ClosePosParam calldata param,
    IUniswapV2Router02 swapRouter,
    address[][] calldata swapPath
)
    external
    existingStrategy(param.strategyId)
    existingCollateral(param.strategyId, param.collToken);

```

{% endcode %}

This function closes a position in the farm, removing liquidity from the Balancer pool and unstaking from the Aura pool.

```
```


# BasicSpell

The BasicSpell contract is an abstract contract that provides a set of functions to be implemented by its inheriting contracts. This contract is designed to facilitate borrowing, lending, and collateral management functionalities for other contracts in the BlueBerry Protocol

### Variables

#### bank

* Type: `IBank`
* Description: The bank contract that provides borrowing, lending, and collateral management functionalities

#### werc20

* Type: `IWERC20`
* Description: The wrapped ERC20 contract that is used as collateral for borrowing and lending operations

#### weth

* Type: `address`&#x20;
* Description: The address of the WETH contract

### Functions

#### \_\_BasicSpell\_init

{% code overflow="wrap" %}

```solidity
function __BasicSpell_init(IBank _bank, address _werc20, address _weth) internal onlyInitializing 
```

{% endcode %}

Initializes the contract by setting the parameters

**Parameters**

<table><thead><tr><th width="161.33333333333331">Name</th><th width="184">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_bank</code></td><td><code>IBank</code></td><td>The address of the bank contract</td></tr><tr><td><code>_werc20</code></td><td><code>address</code></td><td>The address of the wrapped ERC20 contract</td></tr><tr><td><code>_weth</code></td><td><code>address</code></td><td>The address of the WETH contract</td></tr></tbody></table>

#### \_addStrategy

```solidity
function _addStrategy(address vault, uint256 maxPosSize) internal
```

Adds a strategy to the specific spell

**Parameters**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>vault</code></td><td>address</td><td>The address of the vault to add</td></tr><tr><td><code>maxPosSize</code></td><td>uint256</td><td>the USD price of the maximum position size for the given strategy based 1e18 </td></tr></tbody></table>

#### setMaxPosSize

{% code overflow="wrap" %}

```solidity
function setMaxPosSize(uint256 strategyID, uint256 maxPosSize) external existingStrategy(strategyId) onlyOWner
```

{% endcode %}

**Parameters**

<table><thead><tr><th width="158.33333333333331">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>strategyId</code></td><td>uint256</td><td>The strategy ID to be adjusted</td></tr><tr><td><code>maxPosSize</code></td><td>uint256</td><td>the new USD price of the maximum position size for the given strategy based 1e18 </td></tr></tbody></table>

#### setCollateralsMaxLTVs

{% code overflow="wrap" %}

```solidity
function setCollateralsMaxLTVs(uint256 strategyId, address[] memory collaterals, uint256[] memory maxLTVs) external existingStrategy(strategyId) onlyOwner
```

{% endcode %}

Allows the owner to set the maxLTV values of a specific collateral type for the given strategy

**Parameters**

<table><thead><tr><th width="170.33333333333331">Name</th><th width="110">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>strategyId</code></td><td>uint256</td><td>The strategy ID to be adjusted</td></tr><tr><td><code>collaterals</code></td><td>array</td><td>An array of addresses of the collaterals to have their max values set</td></tr><tr><td><code>maxLTVs</code></td><td>array</td><td>An array of the values for the given collaterals to set their maximums.</td></tr></tbody></table>

#### \_validateMaxLTV

```solidity
function _validateMaxLTV(uint256 strategyId) internal view
```

An internal function to ensure that the ltv of a strategy is within the maximum value bounds.

* `strategyId` (uint256) - The given ID to be checked and validated

#### \_validateMaxPosSize

```solidity
function _validateMaxPosSize(uint256 strategyId) internal view
```

An internal function to ensure that the max Position Size of a strategy is within the maximum value bounds.

`strategyId` (uint256) - The given ID to be checked and validated

#### \_doRefund

```solidity
function _doRefund(address token) internal
```

Refunds any remaining balance of the specified token to the current bank executor.

**Parameters**

* `token` (address): The address of the token to refund

#### \_doCutRewardsFee

{% code overflow="wrap" %}

```solidity
function _doCutRewardsFee(address token) internal
```

{% endcode %}

Cuts the rewards from the current bank executor to the protocols treasury.

**Parameters**

* `token` (address): The address of the token to cut

#### \_doRefundRewards

```solidity
function _doRefundRewards(address token) internal
```

Cut rewards fee and refund the rewards tokens from spell to the current bank executor

**Parameters**

`token` (address): The address of the token to refund

#### \_doLend

{% code overflow="wrap" %}

```solidity
function _doLend(address token, uint256 amount) internal 
```

{% endcode %}

Lends the specified amount of the token to the bank on behalf of the current executor

**Parameters**

<table><thead><tr><th width="242">Name</th><th width="177.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to lend</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to lend</td></tr></tbody></table>

#### \_doWithdraw

{% code overflow="wrap" %}

```solidity
function _doWithdraw(address token, uint256 amount) internal
```

{% endcode %}

Withdraws the specified amount of the token from the bank on behalf of the current executor

**Parameters**

<table><thead><tr><th width="242">Name</th><th width="177.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to withdraw</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to withdraw</td></tr></tbody></table>

#### \_doBorrow

{% code overflow="wrap" %}

```solidity
function _doBorrow(address token, uint256 amount) internal returns (uint256 borrowedAmount)
```

{% endcode %}

Borrows the specified amount of the token from the bank on behalf of the current executor

**Parameters**

<table><thead><tr><th width="242">Name</th><th width="177.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to borrow</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to borrow</td></tr></tbody></table>

**Returns**

* `borrowedAmount` : The number of tokens actually borrowed

#### \_doRepay

{% code overflow="wrap" %}

```solidity
function _doRepay(address token, uint256 amount) internal
```

{% endcode %}

Repays the specified amount of the token to the bank on behalf of the current executor

**Parameters**

<table><thead><tr><th width="242">Name</th><th width="177.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to repay</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to repay</td></tr></tbody></table>

#### \_doPutCollateral

```solidity
function _doPutCollateral(address token, uint256 amount) internal
```

This function puts collateral tokens inside the bank

**Parameters**

<table><thead><tr><th width="242">Name</th><th width="134.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to put in the bank</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to put in the bank</td></tr></tbody></table>

#### \_doTakeCollateral

{% code overflow="wrap" %}

```solidity
function _doTakeCollateral(address token, uint256 amount) internal
```

{% endcode %}

This function takes collateral tokens out of the bank by burning the equivalent amount of wrapped ERC20 tokens (wERC20) using the `burn` function of the wERC20 token contract.

**Parameters**

<table><thead><tr><th width="209">Name</th><th width="134.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to take out of the bank</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to take out of the bank</td></tr></tbody></table>

#### increasePosition

```solidity
function increasePosition(address token, uint256 amount) external
```

This function allows for the user to increase their isolated collateral to support their position

**Parameters**

<table><thead><tr><th width="209">Name</th><th width="134.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td><code>address</code></td><td>The address of the token to put in the bank</td></tr><tr><td><code>amount</code></td><td><code>uint256</code></td><td>The amount of token to put in the bank</td></tr></tbody></table>

#### reducePosition

{% code overflow="wrap" %}

```solidity
function reducePosition(uint256 strategyID, address collToken, uint256 collShareAmount) external
```

{% endcode %}

This function allows for the user to reduce their isolated collateral in a given position

**Parameters**

<table><thead><tr><th width="209.33333333333331">Name</th><th width="134">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>strategyId</code></td><td><code>uint256</code></td><td>The strategy to be targeted</td></tr><tr><td><code>collToken</code></td><td><code>address</code></td><td>The address of the isolated collateral token</td></tr><tr><td><code>collShareAmount</code></td><td><code>uint256</code></td><td>The amount of isolated collateral to be removed</td></tr></tbody></table>

#### receive

```solidity
receive() external payable
```

This is a fallback function that is used to receive Ether only from the Wrapped Ether (WETH) contract. If the function receives Ether from an address other than the WETH contract, it reverts with an error.


# ConvexSpell

The `ConvexSpell` contract is a factory contract that defines how the Blueberry Protocol interacts with Convex pools. This contract handles adding strategies, opening and closing positions, and managing collateral tokens. It inherits from the `BasicSpell` contract and utilizes the OpenZeppelin's SafeERC20Upgradeable library.

### Variables

* `wConvexPools`: Address of Wrapped Convex Pools.
* `crvOracle`: Address of the Curve Oracle.
* `CVX`: Address of the CVX token.

### Functions

**`initialize`**

Initializes the contract with the necessary parameters.

Parameters:

* `bank_`: Address of the Bank contract.
* `werc20_`: Address of the WERC20 contract.
* `weth_`: Address of the WETH contract.
* `wConvexPools_`: Address of the Wrapped Convex Pools contract.
* `crvOracle_`: Address of the Curve Oracle contract.

**`addStrategy`**

Adds a new strategy to the spell.

Parameters:

* `crvLp`: Address of the CRV LP token for the given strategy.
* `maxPosSize`: The maximum position size in USD (1e18-based) for the given strategy.

**`openPositionFarm`**

Opens a position and adds liquidity to a Curve pool with two underlying tokens while staking to the Curve gauge.

Parameters:

* `param`: An `OpenPosParam` struct containing parameters for the position.
* `minLPMint`: Minimum LP token amount to be minted for slippage control.

**`closePositionFarm`**

Closes a position, removes liquidity from the Curve pool, and repays the debt.

Parameters:

* `param`: A `ClosePosParam` struct containing parameters for the position.
* `swapRouter`: An instance of the UniswapV2Router02 contract.
* `swapPath`: A 2D array of addresses representing the path to swap reward tokens for debt tokens.

### Structs

#### OpenPosParam

Struct containing parameters for opening a position.

Fields:

* `strategyId`: The ID of the strategy.
* `collToken`: Address of the collateral token.
* `collAmount`: The amount of collateral tokens.
* `borrowToken`: Address of the borrowed token.
* `borrowAmount`: The amount of borrowed tokens.
* `farmingPoolId`: The ID of the farming pool.

#### ClosePosParam

Struct containing parameters for closing a position.

Fields:

* `strategyId`: The ID of the strategy.
* `collToken`: Address of the collateral token.
* `amountPosRemove`: The amount of position to be removed.
* `amountShareWithdraw`: The amount of shares to be withdrawn.
* `borrowToken`: Address of the borrowed token.
* `amountRepay`: The amount of debt to be repaid.


# IchiSpell

This contract is used to manage the deployments of borrowing tokens to enter into ICHI vault's. The contract allows users to open and close positions by depositing collateral into the Blueberry money market and borrowing tokens to achieve the desired leverage.&#x20;

### Structs

The contract defines the following structs:

* `Strategy`:A struct that represents an ICHI vault strategy. It contains the address of the vault and the maximum position size, which is a USD price-based value
* `OpenPosParam`: A struct that represents the parameters required to open a position. It contains the strategy ID, collateral token address, borrowing token address, collateral amount, borrowing amount , and farming pool ID
* `ClosePosParam`: A struct that represents the parameters required to close a position. It contains the strategy ID, collateral token address, borrowing token address, amount of LP tokens to remove, amount of debt to repay, amount of isolated collateral to withdraw, and sell slippage.

### State Variables

The contract has the following state variables:

* `swapPool`: A private state variable that is used to store the Uniswap V3 pool when swapping tokens.
* `strategies`: A public array of `Strategy` structs that stores all the ICHI vault strategies
* `maxLTV`: A mapping that maps strategy IDs to collateral tokens and their maximum loan-to-value (LTV) ratios
* `wIchiFarm`: An instance of the `IWIchiFarm` interface that is used to interact with the ICHI farm
* `ICHI`: The address of the ICHI token

### Events

The contract emits the following events:

* `StrategyAdded(uint256 strategyId, address vault, uint256 maxPosSize)`: Emits when a new strategy is added to the contract.
* `CollateralsMaxLTVSet(uint256 strategyId, address[] collaterals, uint256[] maxLTVs)`: Emits when the maximum LTV ratios are set for collateral tokens.

### Modifiers

The contract defines the following modifiers:

* `existingStrategy(uint256 strategyId)`: A modifier that checks if a strategy ID exists.
* `existingCollateral(uint256 strategyId, address col)`: A modifier that checks if a collateral token exists for a strategy.

### Functions

The contract defines the following functions:

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(IBank bank_, address werc20_, address weth_, address wichiFarm_) external initializer 
```

{% endcode %}

This function is an initializer function that is used to set the contract's state variables. It takes the following:

**Parameters:**

<table><thead><tr><th width="167.33333333333331">Name</th><th width="142">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>bank_</code></td><td>IBank</td><td>An interface for the Bank contract that manages positions and collateral</td></tr><tr><td><code>werc20_</code></td><td>address</td><td>The address of the WERC20 contract used to wrap collateral tokens</td></tr><tr><td><code>weth_</code></td><td>address</td><td>The address of the WETH contract used to wrap ETH</td></tr><tr><td><code>wichiFarm_</code></td><td>address</td><td>The address of the WIchiFarm contract used to interact with the ICHI farming system</td></tr></tbody></table>

#### addStrategy

{% code overflow="wrap" %}

```solidity
function addStrategy(address vault, uint256 maxPosSize) external onlyOwner
```

{% endcode %}

This function is used to add a new strategy to the contract. The function is marked as external and can only be called by the contract's owner. The function first checks that the `vault` parameter is not an empty address and that the `maxPosSize` parameter is greater than zero. Then, a new `Strategy` struct is created with the `vault` and `maxPosSize` parameters and added to the `strategies` array. An event is emitted with the index of the new strategy, the vault address, and the maximum position size.

**Parameters:**

<table><thead><tr><th width="173.33333333333331">Name</th><th width="119">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>vault</code></td><td>address</td><td>The address of the ICHI vault used for the strategy</td></tr><tr><td><code>maxPosSize</code></td><td>uint256</td><td>The maximum size of a position for the given vault, expressed in USD and based on 1e18</td></tr></tbody></table>

#### \_deposit

{% code overflow="wrap" %}

```solidity
function _deposit(OpenPosParam calldata param) internal
```

{% endcode %}

This function is an internal function that deposits assets onto an ICHI Vault as part of an open position. The function starts by getting the strategy information for the given `strategyId` using the `strategies` array. It then executes three main steps:

1. Deposit isolated collaterals on Blueberry Money Market
2. Borrow specific amounts
3. Add liquidity - Deposit on ICHI Vault

Step 1 is done by calling the `_doLend` function, which deposits the collateral into the Blueberry Money Market. Step 2 is done by calling the `_doBorrow` function, which borrows the specified amount of tokens from the Blueberry Money Market.

Step 3 involves adding liquidity by depositing the borrowed tokens into the ICHI Vault. The function starts by checking if the borrow token is one of the tokens supported by the ICHI Vault using the `token0` and `token1` functions of the ICHI Vault contract. If the borrow token is not supported by the ICHI Vault, the function reverts with an error message.

The function then approves the transfer of the borrowed tokens to the ICHI Vault using the `_ensureApprove` function. It then calls the `deposit` function of the ICHI Vault contract, passing in the amount of tokens to deposit and the address of the current contract as the recipient of the ICHI Vault shares. The function stores the returned ICHI Vault shares in the `ichiVaultShare` variable.

After adding liquidity to the ICHI Vault, the function validates the maximum LTV and maximum position size for the current strategy using the `_validateMaxLTV` and `_validateMaxPosSize` functions, respectively. If either validation fails, the function reverts with an error message.

**Parameters:**

* `OpenPosParam` (struct): A struct containing the parameters for the open position.

#### openPosition

{% code overflow="wrap" %}

```solidity
function openPosition(OpenPosParam calldata param) external exisitingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)
```

{% endcode %}

This is an external function that is used to deposit assets on the IchiVault. It takes in an OpenPosParam struct as its only parameter which contains the necessary information to open a new position. The function performs the following steps:

1. It checks that the strategy with the given ID exists in the system.
2. It checks that the collateral token associated with the given strategy also exists in the system.
3. It calls the internal `_deposit` function to deposit the required assets on the IchiVault.
4. It puts the ICHI Vault LP token as collateral in the bank.

**Parameters:**

* `OpenPosParam` (struct): A struct containing the parameters to open a new position. Which includes the following fields -&#x20;
  * `strategyId` `uint256:` representing the ID of the strategy to use.
  * `collToken` `address:` representing the address of the collateral token.
  * `borrowToken` `address:` representing the address of the token to borrow.
  * `collAmount` `uint256:` representing the number of collateral to deposit.
  * `borrowAmount` `uint256:` representing the number of tokens to borrow.
  * `farmingPid` `uint256:` representing the ID of the farming pool.

#### openPositionFarm

{% code overflow="wrap" %}

```solidity
function openPositionFarm(OpenPosParam calldata param) external existingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)
```

{% endcode %}

An external function that allows a user to deposit assets on IchiVault and farm in Ichi Farm. It checks that the given strategy, collateral token, and farming pool ID are existing in the contract. The function calls the `_deposit` function and then takes out the collateral, deposits on the farming pool, and puts the ICHI Vault LP token as collateral.

**Parameters:**

* `OpenPosParam` (struct): A struct containing the parameters to open a new position. Which includes the following fields -&#x20;
  * `strategyId` `uint256:` representing the ID of the strategy to use.
  * `collToken` `address:` representing the address of the collateral token.
  * `borrowToken` `address:` representing the address of the token to borrow.
  * `collAmount` `uint256:` representing the number of collateral to deposit.
  * `borrowAmount` `uint256:` representing the number of tokens to borrow.
  * `farmingPid` `uint256:` representing the ID of the farming pool.

#### \_withdraw

{% code overflow="wrap" %}

```solidity
function _withdraw(ClosePosParam calldata param) internal
```

{% endcode %}

This is an internal function to withdraw assets from ICHI Vault, swap withdrawn assets to debt token, withdraw isolated collaterals from Blueberry Money Market, repay debt, and refund the rest to the user.

**Parameters:**

* `ClosePosParam`(struct): Is a struct that contains the following-&#x20;
  * `strategyId`(uint256): representing the id of the strategy.
  * `amountLpRemove`(uint256): representing the amount of liquidity pool token to remove.
  * `sellSlippage`(uint256): representing the slippage percentage for the swap.
  * `borrowToken`(address): representing the token to borrow.
  * `collToken`(address): representing the collateral token to use.
  * `sqrtRatioLimit`(uint160): representing the square root of the price ratio limit.
  * `amountRepay`(uint256): representing the amount of debt to repay.
  * `amountShareWithdraw`(uint256): representing the amount of isolated collateral to withdraw.

**Function Steps:**

1. Check if `param.sellSlippage` is less than or equal to the maximum slippage set in the bank's configuration. If it is greater than the maximum slippage, revert the transaction with an error message.
2. Get the strategy using the `param.strategyId`.
3. Get the ICHI vault instance using the `strategy.vault` address.
4. Compute the amount of debt to repay. If `param.amountRepay` is `type(uint256).max`, set `amountRepay` to the current debt of the position using `bank.currentPositionDebt(positionId)`.
5. Calculate the actual amount to remove. If `param.amountLpRemove` is `type(uint256).max`, set `amountLpRemove` to the current balance of the contract in the ICHI vault using `vault.balanceOf(address(this))`.
6. Withdraw liquidity from the ICHI vault using `vault.withdraw(amountLpRemove, address(this))`.
7. Determine if the token to swap is `token0` or `token1` and calculate the amount to swap. If the amount is greater than 0, swap the token using `swapPool.swap()`.
8. Withdraw isolated collateral from the bank using `_doWithdraw()`.
9. Repay the debt using `_doRepay()`.
10. Validate the maximum loan-to-value ratio using `_validateMaxLTV()`.
11. Refund the remaining tokens to the user using `_doRefund()`.

#### closePosition

{% code overflow="wrap" %}

```solidity
function closePosition(ClosePosParam calldata param) external existingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)
```

{% endcode %}

This is an external function to withdraw assets from ICHI Vault

**Parameters:**

* `ClosePosParam`(struct): Is a struct that contains the following-&#x20;
  * `strategyId`(uint256): representing the id of the strategy.
  * `amountLpRemove`(uint256): representing the amount of liquidity pool token to remove.
  * `sellSlippage`(uint256): representing the slippage percentage for the swap.
  * `borrowToken`(address): representing the token to borrow.
  * `collToken`(address): representing the collateral token to use.
  * `sqrtRatioLimit`(uint160): representing the square root of the price ratio limit.
  * `amountRepay`(uint256): representing the amount of debt to repay.
  * `amountShareWithdraw`(uint256): representing the amount of isolated collateral to withdraw.

#### closePositionFarm

{% code overflow="wrap" %}

```solidity
function closePositionFarm(ClosePosParam calldata param) external existingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)
```

{% endcode %}

This function is an external function that allows a user to close their position in a farming strategy. The function first validates that the specified collateral token is correct and then removes the collateral token from the Bank. It then burns the withdrawn collateral token from the wIchiFarm and refunds the rewards. The function then calls the `_withdraw` function to remove liquidity and ends by refunding the ICHI token.

**Parameters:**&#x20;

`ClosePosParam`(struct): Is a struct that contains the following-&#x20;

* `strategyId`(uint256): representing the id of the strategy.
* `collToken`(address): the address of the collateral token to be used
* `borrowToken`(address): representing the token to borrow.
* `amountRepay`(uint256): representing the amount of debt to repay.
* `amountLpRemove`(uint256): representing the amount of liquidity pool token to remove.
* `amountShareWithdraw`(uint256): representing the amount of isolated collateral to withdraw.
* `sqrtRatioLimit`(uint160): representing the square root of the price ratio limit.
* `sellSlippage`(uint256): representing the slippage percentage for the swap.

#### uinswapV3 SwapCallback&#x20;

{% code overflow="wrap" %}

```solidity
function uniswapV3SwapCallback(in256 amount0Delta, int256 amount1Delta, bytes calldata data) external override
```

{% endcode %}

This function is a callback function that is called by a Uniswap V3 pool contract after a swap transaction is completed. The function checks if the caller is the correct pool contract and transfers the swapped tokens to the appropriate address.

**Parameters:**

<table><thead><tr><th width="180.33333333333331">Name</th><th width="224">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>amount0Delta</code></td><td>int256</td><td>The change in token0 amount</td></tr><tr><td><code>amount1Delta</code></td><td>int256</td><td>The change in token1 amount</td></tr><tr><td><code>data</code></td><td>bytes calldata</td><td>Encoded address of the payer</td></tr></tbody></table>


# LongShortSpell

The ShortLongSpell contract is a factory contract that defines how Blueberry Protocol interacts for leveraging an asset either long or short. It extends the BasicSpell contract and is responsible for depositing and withdrawing assets, as well as opening and closing positions. The contract utilizes OpenZeppelin's SafeERC20Upgradeable and SafeCast libraries, as well as interfaces from other contracts like ISoftVault, IWERC20, and libraries from Paraswap.

### Dependencies

* OpenZeppelin Contracts Upgradeable
* BasicSpell.sol
* Interfaces (ISoftVault.sol, IWERC20.sol)
* Libraries (Paraswap/PSwapLib.sol)

### Contract Overview

#### State Variables

* `wrapper`: An instance of IWERC20 that represents the wrapped ERC20 token.
* `augustusSwapper`: The address of the paraswap AugustusSwapper.
* `tokenTransferProxy`: The address of the paraswap TokenTransferProxy.

### Initialization

The `initialize` function takes the following arguments:

* `IBank bank_`: Instance of the Bank contract
* `address werc20_`: Address of the WERC20 token contract
* `address weth_`: Address of the wrapped Ether (WETH) contract
* `address augustusSwapper_`: Address of the Paraswap AugustusSwapper contract
* `address tokenTransferProxy_`: Address of the Paraswap TokenTransferProxy contract

This function initializes the contract by setting the address for the AugustusSwapper, TokenTransferProxy, and Wrapper contracts, and calling the `__BasicSpell_init` function.

### Deposit

The `_deposit` function takes the following parameters:

* `OpenPosParam calldata param`: Struct containing the parameters for opening a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This internal function handles the process of depositing assets by performing the following steps:

1. Depositing isolated collateral in the Blueberry Money Market
2. Borrowing a specified amount of tokens from the Blueberry Money Market
3. Swapping the borrowed tokens to the strategy token
4. Depositing the swapped tokens to the SoftVault
5. Validating the maximum Loan-to-Value (LTV) ratio
6. Validating the maximum position size

### Open Position

The `openPosition` function takes the following parameters:

* `OpenPosParam calldata param`: Struct containing the parameters for opening a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This external function is used for opening a new position. It calls the internal `_deposit` function to handle the deposit process, puts collateral and handles refunds.

### Withdraw

The `_withdraw` function takes the following parameters:

* `ClosePosParam calldata param`: Struct containing the parameters for closing a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This internal function handles the process of withdrawing assets by performing the following steps:

1. Calculate the actual amount to remove from the position
2. Withdraw assets from the SoftVault
3. Swap the strategy token to the isolated collateral token
4. Withdraw the isolated collateral from the Blueberry Money Market
5. Repay the debt and refund the remaining amount to the user
6. Validate the maximum LTV ratio

### Close Position

The `closePosition` function takes the following parameters:

* `ClosePosParam calldata param`: Struct containing the parameters for closing a position
* `Utils.MegaSwapSellData calldata swapData`: Struct containing the swap data for the MegaSwap operation

This external function is used for closing a position. It checks for correct strategy and collateral tokens, takes out collateral, and calls the internal `_withdraw` function to handle the withdrawal process.

### Add Strategy

The `addStrategy` function takes the following parameters:

* `address swapToken`: Address of the token for the given strategy
* `uint256 maxPosSize`: USD price of the maximum position size for the given strategy, based on 1e18

This external function is used for adding a strategy to the spell. It can only be called by the contract owner. It calls the internal `_addStrategy` function to add a strategy with the specified `swapToken` address and `maxPosSize`.

### Additional Functions

The contract also contains several utility functions such as `_doLend`, `_doBorrow`, `_ensureApprove`, `_validateMaxLTV`, `_validateMaxPosSize`, `_doPutCollateral`, `_doWithdraw`, `_doRepay`, and `_doRefund`. These functions help with various operations related to lending, borrowing, approving tokens, validating LTV ratios, validating position sizes, putting collateral, withdrawing, repaying debts, and refunding assets.

### Modifiers

The contract includes the following modifiers to validate the input parameters for certain functions:

* `existingStrategy`: Ensures that the strategy ID provided as a parameter exists
* `existingCollateral`: Ensures that the collateral token provided as a parameter exists for the specified strategy


# Vault


# Introduction

Vault contracts inside of the Blueberry protocol, allow users to lend tokens that can be used as isolated collateral. There are two different types of vaults inside the protocol:

* [**Blueberry SoftVault Contracts**](/developer-guides/contracts/vault/softvault)**:** The contracts that allow users to lend tokens (ERC20) and earn lending interest (interest rate is reflected from how much users borrow the token (Active utilization rate)). This is using the underlying Blueberry Money Market (Compound Fork) [Lending Protocol](/lending-protocol/overview)
* [**Blueberry HardVault Contracts**](/developer-guides/contracts/vault/hardvault)**:** The contracts that allow users to lock LP (ERC1155) tokens as collateral.


# HardVault

The Hard Vault contract is designed to hold LP (Liquidity Provider) tokens as collateral. The contract is ERC1155 compliant, which means that the underlying LP tokens are identified by casted tokenId from token address.

### State Variables

The Hard Vault contract has the following state variables:

* `config`: The address of the protocol configuration contract.

### Events

The Hard Vault contract emits the following events:&#x20;

* `Deposited`: Emitted when a user deposits LP tokens into the vault.
* `Withdrawn`: Emitted when a user withdraws LP tokens from the vault.

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
initialize(IProtocolConfig _config) external initializer
```

{% endcode %}

The `initialize` function is an initializer function that is called when the contract is deployed. It initializes the state variables of the contract.

**Parameters:**

* `_config`(IProtocolConfig): The address of the protocol configuration contract.

#### \_encodeTokenId

{% code overflow="wrap" %}

```solidity
_encodeTokenId(address uToken) internal pure returns (uint)
```

{% endcode %}

The `_encodeTokenId` function takes an underlying token address and encodes it into a token ID.

**Parameters:**

* `uToken`(address): The address of the underlying token.

#### \_decodeTokenId

{% code overflow="wrap" %}

```solidity
_decodeTokenId(uint tokenId) internal pure returns (address)
```

{% endcode %}

The `_decodeTokenId` function takes a token ID and decodes it into an underlying token address.

**Parameters:**

* `tokenId`(uint): The token ID to decode.

#### balanceOfERC20

{% code overflow="wrap" %}

```solidity
balanceOfERC20(address token, address user) external view override returns (uint256)
```

{% endcode %}

The `balanceOfERC20` function returns the balance of an underlying ERC20 token for a given user.

**Parameters:**

* `token`: The address of the ERC20 token.
* `user`: The address of the user.

#### getUnderlyingToken

{% code overflow="wrap" %}

```solidity
getUnderlyingToken(uint256 tokenId) external pure override returns (address token)
```

{% endcode %}

The `getUnderlyingToken` function returns the underlying ERC20 token address for a given ERC1155 token ID.

**Parameters:**

* `tokenId`: The ERC1155 token ID.

#### deposit

{% code overflow="wrap" %}

```solidity
deposit(address token, uint256 amount) external override nonReentrant returns (uint256 shareAmount)
```

{% endcode %}

The `deposit` function allows a user to deposit underlying assets into the vault and issue share tokens.

**Parameters:**

* `token`: The address of the underlying token to deposit.
* `amount`: The amount of underlying tokens to deposit.

#### withdraw

{% code overflow="wrap" %}

```solidity
withdraw(address token, uint256 shareAmount) external override nonReentrant returns (uint256 withdrawAmount)
```

{% endcode %}

The `withdraw` function allows a user to withdraw underlying assets from the vault.

**Parameters:**

* `token`: The address of the underlying token to withdraw.
* `shareAmount`: The amount of share tokens to redeem.


# SoftVault

The Soft Vault contract allows users to lend and borrow tokens from/to Blueberry Money Market. SoftVault communicates with bTokens to lend and borrow underlying tokens from/to Blueberry Money Market. Underlying tokens can be ERC20 tokens listed by the Blueberry team, such as USDC, USDT, DAI, WETH, etc.

### Variables

The contract has the following variables:

* `bToken`: An instance of a cToken contract.
* `uToken`: An instance of an underlying token contract.
* `config`: An instance of Blueberry Protocol configuration contract.

### Events

The contract has the following events:

* `Deposited`: Emits when a user deposits an underlying token and receives share tokens.
* `Withdrawn`: Emits when a user withdraws an underlying token by redeeming share tokens.

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(IProtocolConfig _config, ICErc20 _bToken, string memory _name, string memory _symbol) external initializer
```

{% endcode %}

The `initialize` function initializes the contract. It sets the contract owner, ERC20 name, ERC20 symbol, Blueberry Protocol configuration, bToken contract, and uToken contract.

#### decimals

{% code overflow="wrap" %}

```solidity
function decimals() public view override returns (uint8)
```

{% endcode %}

The `decimals` function returns the number of decimals of the bToken contract

#### deposit

{% code overflow="wrap" %}

```solidity
function deposit(uint256 amount) external override nonReentrant returns (uint256 shareAmount);
```

{% endcode %}

The `deposit` function allows users to deposit an underlying token and receive share tokens in exchange. It transfers the underlying token to the SoftVault contract, approves the transfer of the underlying token to the bToken contract, mints bTokens, and issues share tokens to the user. The function returns the amount of share tokens issued.

#### withdraw

{% code overflow="wrap" %}

```solidity
function withdraw(uint256 shareAmount) external override nonReentrant returns (uint256 withdrawAmount);
```

{% endcode %}

The `withdraw` function allows users to withdraw an underlying token by redeeming share tokens. It burns the share tokens from the user, redeems bTokens for the underlying token, cuts the vault withdraw fee if it's within the window (2 months), and transfers the underlying token to the user. The function returns the amount of underlying tokens transferred to the user.


# Utils


# BlueBerryConst

The contract that includes the constants utilized across the Blueberry protocol

<table><thead><tr><th width="229">Constant</th><th width="101">Type</th><th width="325">Description</th><th>Value</th></tr></thead><tbody><tr><td>DENOMINATOR</td><td>uint256</td><td>value of the denominator</td><td>10000</td></tr><tr><td>MIN_LIQ_THRESHOD</td><td>uint256</td><td>lowest value for liquidations</td><td>8000</td></tr><tr><td>PRICE_PRECISION</td><td>uint256</td><td>decimal return for oracle</td><td>1e18</td></tr><tr><td>MAX_PRICE_DEVIATION</td><td>uint256</td><td>max price deviation</td><td>1000</td></tr><tr><td>MIN_TIME_GAP</td><td>uint32</td><td>the smallest acceptable gap for price reporting</td><td>1 hour</td></tr><tr><td>MAX_TIME_GAP</td><td>uint32</td><td>the largest acceptable gap for price repoting</td><td>2 days</td></tr><tr><td>MAX_FEE_RATE</td><td>uint256</td><td>the maximum fee that can be taken in the protocol</td><td>2000</td></tr><tr><td>MAX_WITHDRAW_VAULT_FEE_WINDOW</td><td>uint256</td><td>the maximum time period for vaults having additional withdraw penalty</td><td>60 days</td></tr></tbody></table>


# BlueBerryErrors

| Error                                                        | Description                                                                   | Type of Error |
| ------------------------------------------------------------ | ----------------------------------------------------------------------------- | ------------- |
| ZERO\_AMOUNT                                                 | Thrown when the amount is zero                                                | Common        |
| ZERO\_ADDRESS                                                | Thrown when the address is zero                                               | Common        |
| INPUT\_ARRAY\_MISMATCH                                       | Thrown when the array input has a mismatch for token length                   | Common        |
| TOO\_LONG\_DELAY(uint256 delayTime)                          | Thrown when the delay time is too long                                        | Oracle        |
| NO\_MAX\_DELAY(address token)                                | Thrown when there is no maximum delay set for the token                       | Oracle        |
| PRICE\_OUTDATED(address token)                               | Thrown when the price is larger than the maximum delay                        | Oracle        |
| NO\_SYM\_MAPPING(address token)                              | Thrown when there is no                                                       | Oracle        |
| OUT\_OF\_DEVIATION\_CAP(uint256 deviation)                   | Thrown when the deviation is greater than the cap.                            | Oracle        |
| EXCEED\_SOURCE\_LENGTH(uint256 length)                       | Thrown when the source length is too long                                     | Oracle        |
| NO\_PRIMARY\_SOURCE(address token)                           | Thrown when there is no primary price feed for the token                      | Oracle        |
| NO\_VALID\_SOURCE(address token)                             | Thrown when the input for a token is not valid                                | Oracle        |
| EXCEED\_DEVIATION()                                          | Thrown when the amount of deviation is greater than the cap                   | Oracle        |
| TOW\_LOW\_MEAN(uint256 mean)                                 | Thrown when the mean is below the required                                    | Oracle        |
| NO\_MEAN(address token)                                      | Thrown when there is no mean price for a token                                | Oracle        |
| NO\_STABLEPOOL(address token)                                | Thrown when there is no stable pool for a token                               | Oracle        |
| PRICE\_FAILED(address token)                                 | Thrown when unable to get a price for a token                                 | Oracle        |
| LIQ\_THRESHOLD\_TOO\_HIGH(uint256 threshold)                 | Thrown when the input is too large for the liquidation threshold              | Oracle        |
| LIQ\_THRESHOLD\_TOO\_LOW(uint256 threshold)                  | Thrown when the input is too small for the liquidation threshold              | Oracle        |
| ORACLE\_NOT\_SUPPORT(address token)                          | Thrown when a token does not have oracle support                              | Oracle        |
| ORACLE\_NOT\_SUPPORT\_LP(address lp)                         | Thrown when a LP token does not have oracle support                           | Oracle        |
| ORACLE\_NOT\_SUPPORT\_WTOKEN(address wToken)                 | Thrown when a wtoken does not have oracle support                             | Oracle        |
| ERC1155\_NOT\_WHITELISTED(address collToken)                 | Thrown when an invalid ERC1155 is provided as input as it is not whitelisted  | Oracle        |
| NO\_ORACLE\_ROUTE(address token)                             | Thrown when the token does not have a set oracle routing                      | Oracle        |
| NOT\_BANK(address caller)                                    | Thrown when a caller is not the bank address                                  | Spell         |
| REFUND\_ETH\_FAILED(uint256 balance)                         | Thrown when unable to refund the balance in ETH                               | Spell         |
| NOT\_FROM\_WETH(address from)                                | Thrown when an invalid WETH address is provided                               | Spell         |
| LP\_NOT\_WHITELISTED(address lp)                             | Thrown when an invalid LP address is provided as input                        | Spell         |
| COLLATERAL\_NOT\_EXIST(uint256 strategyId, address colToken) | Thrown when an invalid Collateral token is provided as input for a strategy   | Spell         |
| STRATEGY\_NOT\_EXIST(address spell, uint256 strategyId)      | Thrown when attempting to enter a non-supported strategy                      | Spell         |
| EXCEED\_MAX\_POS\_SIZE(uint256 strategyId)                   | Thrown when attempting to make a position larger than cap                     | Spell         |
| EXCEED\_MAX\_LTV()                                           | Thrown when attempting to make a position larger than the supplied collateral | Spell         |
| INCORRECT\_LP(address lpToken)                               | Thrown when an invalid LP address is provided as input                        | Ichi Spell    |
| INCORRECT\_PID(uint256 pid)                                  | Thrown when an invalid pool ID is provided as input                           | Ichi Spell    |
| INCORRECT\_COLTOKEN(address colToken)                        | Thrown when the collateral token is not the appropriate one                   | Ichi Spell    |
| INCORRECT\_UNDERLUING(address uToken)                        | Thrown when the underlying token is not the appropriate one                   | Ichi Spell    |
| NOT\_FROM\_UNIV3(address sender)                             | Thrown when the sender address is not a Uniswap V3 address                    | Ichi Spell    |
| BORROW\_FAILED(uint256 amount)                               | Thrown when borrowing has failed                                              | Vault         |
| REPAY\_FAILED(uint256 amount)                                | Thrown when repaying debt has failed                                          | Vault         |
| LEND\_FAILED(uint256 amount)                                 | Thrown when lending has failed                                                | Vault         |
| REDEEM\_FAILED(uint256 amount)                               | Thrown when redeeming has failed                                              | Vault         |
| INVALID\_TOKEN\_ID(uint256 tokenId)                          | Thrown when an invalid token ID is provided as input                          | Wrapper       |
| BAD\_PID(uint256 pid)                                        | Thrown if supplied an invalid pool ID                                         | Wrapper       |
| BAD\_REWARD\_PER\_SHARE(uint256 rewardPerShare)              | Thrown if there is a mismatch in rewards per share of a vault                 | Wrapper       |
| FEE\_TOO\_HIGH(uint256 feeBps)                               | Thrown if supplied value is too large for feeBps                              | Bank          |
| NOT\_UNDER\_EXECUTION()                                      | Thrown if attempting use function during execution                            | Bank          |
| BANK\_NOT\_LISTED(address token)                             | Thrown if the supplied token address is not supported by that bank            | Bank          |
| BANK\_ALREADY\_LISTED()                                      | Thrown if the Bank address is already supported in the protocol               | Bank          |
| BANK\_LIMIT()                                                | Thrown if the amount of banks has reached its limit                           | Bank          |
| CTOKEN\_ALREADY\_ADDED()                                     | Thrown if the cToken is already supported in the protocol                     | Bank          |
| NOT\_EOA(address from)                                       | Thrown if the address is not an externally owned account (EOA)                | Bank          |
| LOCKED()                                                     | Thrown if the `_IN_EXEC_LOCK` variable is not equal to `_NOT_ENTERED`         | Bank          |
| NOT\_FROM\_SPELL(address from)                               | Thrown if the sender is not the spell address                                 | Bank          |
| NOT\_FROM\_OWNER(uint256 positionId, address sender)         | Thrown when the sender is not the owner of a position                         | Bank          |
| NOT\_IN\_EXEC()                                              | Thrown when the function is called outside of execution.                      | Bank          |
| ANOTHER\_COL\_EXIST(address collToken)                       | Thrown when the collToken already exists in the protocol                      | Bank          |
| NOT\_LIQUIDATABLE(uint256 positionID)                        | Thrown when a position is still healthy                                       | Bank          |
| BAD\_POSISTION(uint256 posId)                                | Thrown when the position Id provided is not supported                         | Bank          |
| BAD\_COLLATERAL(uint256 positionId)                          | Thrown when the supplied collateral address is not supported                  | Bank          |
| INSUFFICIENT\_COLLATERAL()                                   | Thrown when the collateral required is too small.                             | Bank          |
| SPELL\_NOT\_WHITELISTED(address spell)                       | Thrown when the Spell address is not whitelisted                              | Bank          |
| TOKEN\_NOT\_WHITELISTED(address token)                       | Thrown when the Token address is not whitelisted                              | Bank          |
| REPAY\_EXCEEDS\_DEBIT(uint256 repay, uint256 debt)           | Thrown when repay value is larger than debt value                             | Bank          |
| LEND\_NOT\_ALLOWED()                                         | Thrown when lending is turned off                                             | Bank          |
| BORROW\_NOT\_ALLOWED()                                       | Thrown when borrowing is turned off                                           | Bank          |
| INVALID\_UTOKEN(address uToken)                              | Thrown when the uToken provided is not approved                               | Bank          |
| INVALID\_FEE\_DISTRIBUTION()                                 | Thrown when the fee distribution is not set                                   | Config        |
| NO\_TREASURY\_SET()                                          | Thrown when there is no treasury set                                          | Config        |


# EnsureApprove

Ensure Approve is an abstract contract with the following function

#### \_ensureApprove

```solidity
function _ensureApprove(address token, address spender, uint256 amount) internal
```

This function is used to reset the approval for `spender` to zero and set it again to `amount`. The function calls the `approve` function of the `IERC20Upgradeable` interface to reset the approval to zero and then calls it again to set the approval to `amount`

**Parameters:**

| Name      | Type    | Description                           |
| --------- | ------- | ------------------------------------- |
| `token`   | address | the token adress to approve           |
| `spender` | address | the address of the spender to approve |
| `amount`  | uint256 | the amount to approve                 |


# ERC1155NaiveReceiver

The `ERC1155NaiveReceiver` contract is an implementation of the `IERC1155Receiver` interface provided by OpenZeppelin, which allows the contract to receive ERC-1155 tokens. The contract handles single and batch transfers of ERC-1155 tokens, and can be used as a basic receiver for testing or simple use cases.

#### onERC1155Received

```solidity
function onERC1155Received(address, address, uint256, uint256, bytes calldata) external pure override returns (bytes4)
```

This function is called when a single ERC-1155 token is transferred to the contract. The function takes the following parameters:

* `address operator`: The address initiating the transfer.
* `address from`: The address from which the tokens are being transferred.
* `uint256 id`: The identifier of the token being transferred.
* `uint256 value`: The amount of tokens being transferred.
* `bytes calldata data`: Additional data provided with the transfer.

The function returns the function selector of `onERC1155Received` as a `bytes4` value, which is required by the ERC-1155 standard to acknowledge the successful receipt of the tokens.

#### onERC1155BatchReceived

```solidity
function onERC1155BatchReceived(address, address, uint256[] calldata, uint256[] calldata, bytes calldata) external pure override returns (bytes4)
```

This function is called when a batch of ERC-1155 tokens is transferred to the contract. The function takes the following parameters:

* `address operator`: The address initiating the transfer.
* `address from`: The address from which the tokens are being transferred.
* `uint256[] calldata ids`: An array of token identifiers being transferred.
* `uint256[] calldata values`: An array of amounts of tokens being transferred, with each element corresponding to an element in the `ids` array.
* `bytes calldata data`: Additional data provided with the transfer.

The function returns the function selector of `onERC1155BatchReceived` as a `bytes4` value, which is required by the ERC-1155 standard to acknowledge the successful receipt of the tokens.

#### supportsInterface

```solidity
function supportsInterface(bytes4 interfaceId) external view virtual override returns (bool)
```

This function checks if the contract supports a specific interface. It takes the following parameter:

* `bytes4 interfaceId`: The identifier of the interface to be checked.

The function returns a `bool` value indicating whether the contract supports the specified interface. In this implementation, the contract only supports the `IERC1155Receiver` interface.


# Wrapper


# Introduction

the contracts that handle the farming process (i.e. deposit into Masterchef contract) and wrap/unwrap user's collateral and forward wrapped tokens to bank/spells. Current supported Wrappers:

1. [WERC20](/developer-guides/contracts/wrapper/werc20) - Is an ERC1155 compliant contract that wraps ERC20 tokens.
2. [WIchiFarm](/developer-guides/contracts/wrapper/wichifarm) -&#x20;


# WAuraPools

The `WAuraPools` contract is a wrapper for leveraged liquidity provider (LP) tokens on the Blueberry Protocol. The contract allows users to mint and burn ERC-1155 tokens representing their LP positions, while also allowing them to interact with the underlying rewards of the associated pools.

### Key Features

* Inherits from OpenZeppelin's `ERC1155Upgradeable`, `ReentrancyGuardUpgradeable`, `OwnableUpgradeable`, and `EnsureApprove` contracts.
* Implements `IERC20Wrapper` and `IWAuraPools` interfaces.
* Mints and burns wrapped LP tokens (ERC-1155 tokens) while interacting with the underlying rewards.

### Functions

#### initialize

Initializes the contract with the given AURA token and Aura Pools contract addresses.

```solidity
function initialize(
    address aura_,
    address auraPools_
) external initializer;
```

#### encodeId

Encodes the given pool ID and AURA per share value into an ERC-1155 token ID.

```solidity
function encodeId(
    uint256 pid,
    uint256 auraPerShare
) public pure returns (uint256 id);
```

#### decodeId

Decodes the given ERC-1155 token ID into its pool ID and AURA per share value.

```solidity
function decodeId(
    uint256 id
) public pure returns (uint256 gid, uint256 auraPerShare);
```

#### getUnderlyingToken

Returns the underlying ERC20 token address for the given ERC-1155 token ID.

```solidity
function getUnderlyingToken(
    uint256 id
) external view override returns (address uToken);
```

#### getVault

Returns the Balancer vault associated with the given Balancer pool token.

```solidity
solidityCopy codefunction getVault(address bpt) public view returns (IBalancerVault);
```

#### getPoolTokens

Returns the tokens, balances, and last changed block for the given Balancer pool token.

```solidity
function getPoolTokens(
    address bpt
)
    external
    view
    returns (
        address[] memory tokens,
        uint256[] memory balances,
        uint256 lastChangedBlock
    );
```

#### getPool

Returns the Balancer pool address and pool ID associated with the given Balancer pool token and pool ID.

```solidity
function getPool(
    address bpt,
    uint256 pid
) external view returns (address, uint256);
```

#### getPoolInfoFromPoolId

Returns detailed information about the pool associated with the given pool ID.

```solidity
function getPoolInfoFromPoolId(
    uint256 pid
)
    public
    view
    returns (
        address lptoken,
        address token,
        address gauge,
        address crvRewards,
        address stash,
        bool shutdown
    );
```

#### pendingRewards

Returns the pending rewards for the given ERC-1155 token ID and amount.

```solidity
function pendingRewards(
    uint256 tokenId,
    uint256 amount
)
    public
    view
    override
    returns (address[] memory tokens, uint256[] memory rewards);
```

#### mint

Mints wrapped LP tokens (ERC-1155 tokens) for the given pool ID and amount.

```solidity
function mint(
    uint256 pid,
    uint256 amount
) external nonReentrant returns (uint256 id);
```

#### burn

Burns the given ERC-1155 token ID and amount to redeem the underlying LP tokens and associated rewards.

{% code overflow="wrap" %}

```solidity
function burn(
    uint256 id,
    uint256 amount
) external nonReentrant returns (address[] memory rewardTokens, uint256[] memory rewards);
```

{% endcode %}


# WConvexPools

The `WConvexPools` contract is a wrapper for Convex Finance LP token positions, allowing leverage to be applied to the LP tokens. The contract is designed to hold the leveraged LP tokens in the BlueberryBank and does not generate yields. LP tokens are identified by tokenIds encoded from the LP token address.

The contract inherits from `ERC1155Upgradeable`, `ReentrancyGuardUpgradeable`, `OwnableUpgradeable`, `EnsureApprove`, `IERC20Wrapper`, and `IWConvexPools`.

### Contract Initialization

The `initialize` function initializes the contract with the addresses of the CVX token and Convex Pools contract.

```solidity
function initialize(address cvx_, address cvxPools_) external initializer
```

### Functions

#### encodeId

The `encodeId` function encodes the pool id (pid) and CVX amount per share (cvxPerShare) into an ERC1155 token id.

```solidity
function encodeId(
    uint256 pid,
    uint256 cvxPerShare
) public pure returns (uint256 id)
```

#### decodeId

The `decodeId` function decodes an ERC1155 token id into the pool id (pid) and CVX amount per share (cvxPerShare).

```solidity
function decodeId(
    uint256 id
) public pure returns (uint256 gid, uint256 cvxPerShare)
```

#### getUnderlyingToken

The `getUnderlyingToken` function returns the underlying ERC20 token for the given ERC1155 token id.

```solidity
function getUnderlyingToken(
    uint256 id
) external view override returns (address uToken)
```

#### getPoolInfoFromPoolId

The `getPoolInfoFromPoolId` function returns the pool information (LP token, token, gauge, CRV rewards, stash, and shutdown status) for the given pool id.

```solidity
function getPoolInfoFromPoolId(
    uint256 pid
) public view returns (
    address lptoken,
    address token,
    address gauge,
    address crvRewards,
    address stash,
    bool shutdown
)
```

#### pendingRewards

The `pendingRewards` function returns the pending rewards for the given ERC1155 token id and amount. Rewards can be multiple tokens.

```solidity
function pendingRewards(
    uint256 tokenId,
    uint256 amount
) public view override returns (address[] memory tokens, uint256[] memory rewards)
```

#### mint

The `mint` function mints an ERC1155 token for the given LP token. It takes the Convex Pool id and token amount to wrap as input.

```solidity
function mint(
    uint256 pid,
    uint256 amount
) external nonReentrant returns (uint256 id)
```

#### burn

The `burn` function burns the ERC1155 token to redeem the underlying ERC20 token. It takes the token id and amount to burn as input.

```solidity
function burn(
    uint256 id,
    uint256 amount
) external nonReentrant returns (address[] memory rewardTokens, uint256[] memory rewards)
```


# WCurveGauge

This is the technical documentation for the WCurveGauge Solidity contract. The WCurveGauge contract is a wrapped Curve Gauge position that leverages LP tokens to be held in the BlueberryBank and does not generate yields. LP tokens are identified by tokenIds encoded from the LP token address.

### Imports

The contract imports several OpenZeppelin contracts and other utility contracts and interfaces.

```solidity
import "@openzeppelin/contracts-upgradeable/token/ERC1155/ERC1155Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

import "../utils/BlueBerryErrors.sol" as Errors;
import "../utils/EnsureApprove.sol";
import "../interfaces/IERC20Wrapper.sol";
import "../interfaces/IWCurveGauge.sol";
import "../interfaces/curve/ILiquidityGauge.sol";
```

### Contract Inheritance

The WCurveGauge contract inherits from the following contracts:

* ERC1155Upgradeable
* ReentrancyGuardUpgradeable
* OwnableUpgradeable
* EnsureApprove
* IERC20Wrapper
* IWCurveGauge

{% code overflow="wrap" %}

```solidity
contract WCurveGauge is
    ERC1155Upgradeable,
    ReentrancyGuardUpgradeable,
    OwnableUpgradeable,
    EnsureApprove,
    IERC20Wrapper,
    IWCurveGauge
```

{% endcode %}

### State Variables

The contract maintains the following state variables:

* `registry`: Address of Curve Registry
* `gaugeController`: Address of Curve Gauge Controller
* `CRV`: Address of CRV token
* `accCrvPerShares`: Mapping from gauge id to accCrvPerShare

```solidity
ICurveRegistry public registry;
ICurveGaugeController public gaugeController;
IERC20Upgradeable public CRV;
mapping(uint256 => uint256) public accCrvPerShares;
```

### Functions

#### initialize

This function initializes the contract with the addresses of the CRV token, Curve Registry, and Curve Gauge Controller.

{% code overflow="wrap" %}

```solidity
function initialize(
    address crv_,
    address crvRegistry_,
    address gaugeController_
) external initializer
```

{% endcode %}

#### encodeId

This function encodes the given pool id and CRV amount per share to an ERC1155 token id.

{% code overflow="wrap" %}

```solidity
function encodeId(
    uint256 pid,
    uint256 crvPerShare
) public pure returns (uint256 id)
```

{% endcode %}

#### decodeId

This function decodes the given ERC1155 token id to a pool id and CRV amount per share.

{% code overflow="wrap" %}

```solidity
function decodeId(
    uint256 id
) public pure returns (uint256 gid, uint256 crvPerShare)
```

{% endcode %}

#### getUnderlyingToken

This function returns the underlying ERC20 token of the given ERC1155 token id.

{% code overflow="wrap" %}

```solidity
function getUnderlyingToken(
    uint256 id
) external view override returns (address)
```

{% endcode %}

#### getLpFromGaugeId

This function returns the LP token address from the given gauge id.

{% code overflow="wrap" %}

```solidity
function getLpFromGaugeId(uint256 gid) public view returns (address)
```

{% endcode %}

#### pendingRewards

This function returns the pending rewards from the farming pool.

{% code overflow="wrap" %}

```solidity
function pendingRewards(
    uint256 tokenId,
    uint256 amount
)
    public
    view
    override
    returns (address[] memory tokens, uint256[] memory rewards)

```

{% endcode %}

#### mint

This function mints an ERC1155 token for the given LP token.

{% code overflow="wrap" %}

```solidity
function burn(
    uint256 id,
    uint256 amount
) external nonReentrant returns (uint256 rewards)
```

{% endcode %}

#### \_mintCrv

This internal function mints CRV rewards for the Curve gauge.

{% code overflow="wrap" %}

```solidity
function _mintCrv(ILiquidityGauge gauge, uint256 gid) internal
```

{% endcode %}


# WERC20

The WERC20 contract is an ERC1155 compliant contract that wraps ERC20 tokens. This contract is used to hold Leveraged LP Tokens in the BlueberryBank and do not generate yields. LP Tokens are identified by tokenIds encoded from the lp token address.

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize() external initializer
```

{% endcode %}

Initializes the contract by initializing ReentrancyGuard and setting the name of the token as WERC20.

#### \_encodeTokenId

{% code overflow="wrap" %}

```solidity
function _encodeTokenId(address uToken) internal pure returns (uint)
```

{% endcode %}

This function encodes the underlying token address to tokenId.

#### \_decodeTokenId

{% code overflow="wrap" %}

```solidity
function _decodeTokenId(uint tokenId) internal pure returns (address)
```

{% endcode %}

This function decodes the given tokenId to underlyingToken address.

#### getUnderlyingToken

{% code overflow="wrap" %}

```solidity
function getUnderlyingToken(uint256 tokenId) external pure override returns (address token)
```

{% endcode %}

This function returns the underlying ERC-20 token for the given ERC-1155 token id. It takes `tokenId` as input and returns `token` which is the underlying ERC-20 token.

#### pendingRewards

{% code overflow="wrap" %}

```solidity
function pendingRewards(uint256 tokenId, uint amount) public view override returns (address[] memory, uint256[] memory)
```

{% endcode %}

This function returns the pending rewards from the farming pool. Reward tokens can be multiple tokens. It takes `tokenId` and `amount` as input and returns two arrays, `address[] memory` and `uint256[] memory`.

#### balanceOfERC20

{% code overflow="wrap" %}

```solidity
function balanceOfERC20(address token, address user) external view override returns (uint256)
```

{% endcode %}

This function returns the underlying ERC20 balance for the user. It takes `token` and `user` as input and returns `uint256` which is the balance of the user.

#### mint

{% code overflow="wrap" %}

```solidity
function mint(address token, uint256 amount) external override nonReentrant returns (uint256 id)
```

{% endcode %}

This function mints ERC1155 token for the given ERC20 token. It takes `token` and `amount` as input and mints ERC1155 token.

#### burn

{% code overflow="wrap" %}

```solidity
function burn(address token, uint256 amount) external override nonReentrant
```

{% endcode %}

This function burns ERC1155 token to redeem ERC20 token back. It takes `token` and `amount` as input and burns ERC1155 token.


# WIchiFarm

This contract wraps the ICHI MasterChef farming contract by holding ICHI LP tokens in the BlueberryBank, while the underlying LP tokens are deposited into the ICHI farming pool to generate additional yields The LP tokens are identified by token IDs encoded from the LP token address and accPerShare of the deposited time.

### Variables

The `WIchiFarm` contract has the following state variables:

* `ICHIv1`: An `IERC20Upgradeable` variable that represents the address of the legacy ICHI token.
* `ICHI`: An `IIchiV2` variable that represents the address of the ICHI v2 token.
* `ichiFarm`: An `IIchiFarm` variable that represents the address of the ICHI farming contract.

### Functions

#### initialize

{% code overflow="wrap" %}

```solidity
function initialize(address _ichi, address _ichiv1, address _ichiFarm) external initializer
```

{% endcode %}

This function initializes the contract's state variables with the provided ICHI v1, ICHI v2, and ICHI farming contract addresses.

**Parameters:**

<table><thead><tr><th width="199">Name</th><th width="126.33333333333331">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_ichi</code></td><td>address</td><td>Address of the ICHI v2 token contract</td></tr><tr><td><code>_ichiv1</code></td><td>address</td><td>Address of the ICHI v1 token address</td></tr><tr><td><code>_ichiFarm</code></td><td>address</td><td>Address of the ICHI farming contract</td></tr></tbody></table>

#### encodeId

{% code overflow="wrap" %}

```solidity
function encodeId(uint256 pid, uint256 ichiPerShare) public pure returns (uint256 id)
```

{% endcode %}

This function encodes the pool ID and ICHI per share into an ERC-1155 token ID.

**Parameters:**

| Name           | Type    | Description                               |
| -------------- | ------- | ----------------------------------------- |
| `pid`          | uint256 | Pool ID                                   |
| `ichiPerShare` | uint256 | ICHI reward per share multiplied by 10e18 |

#### decodeId

{% code overflow="wrap" %}

```solidity
function decodeId(uint256 id) public pure returns (uint256 pid, uint256 ichiPerShare)
```

{% endcode %}

This function decodes the ERC-1155 token ID into the pool ID and ICHI per share.The pid is the first 16 bits of the token id, and ichiPerShare is the last 240 bits of the token id.

**Parameters:**

* `id` (uint256): ERC-1155 token ID

**Returns:**

<table><thead><tr><th width="172.33333333333331">Name</th><th width="132">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pid</code></td><td>uint256</td><td>The pool ID extracted from the first 16 bits fo the <code>id</code></td></tr><tr><td><code>ichiPerShare</code></td><td>uint256</td><td>The value of ichiPerShare extracted from the last 240 bits of the <code>id</code></td></tr></tbody></table>

#### getUnderlyingToken

{% code overflow="wrap" %}

```solidity
function getUnderlyingToken(uint256 id) external view override returns (address)
```

{% endcode %}

This function returns the underlying ERC-20 token for a given ERC1155 token id. It calls `decodeId` to extract the pid from the token id and then looks up the corresponding LP token address from the ICHI farming pool.

**Parameters:**

* `id`(uint256): The ERC1155 token ID to decode

**Returns:**

* `address`: The address of the underlying ERC-20 token

#### pendingRewards

{% code overflow="wrap" %}

```solidity
function pendingRewards(uint256 tokenId, uint amount) public view override returns (address[] memory tokens, uint256[] memory rewards)
```

{% endcode %}

This function returns the pending ICHI rewards for a given ERC1155 token id and amount of LP tokens. It calls `decodeId` to extract the pid and stIchiPerShare values from the token id, looks up the current enIchiPerShare value from the ICHI farming pool, and calculates the difference in ICHI rewards based on the change in ichiPerShare values.

**Parameters:**

<table><thead><tr><th width="167.33333333333331">Name</th><th width="169">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokenId</code></td><td>uint256</td><td>The ERC1155 token ID to encode</td></tr><tr><td><code>amount</code></td><td>uint</td><td>The amount of share</td></tr></tbody></table>

**Returns:**

<table><thead><tr><th width="166.33333333333331">Name</th><th width="171">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokens</code></td><td>array</td><td>An array containing the address of the reward token ( specifically ICHI)</td></tr><tr><td><code>rewards</code></td><td>uint256</td><td>An array containing the amount of ICHI rewards</td></tr></tbody></table>

#### mint

{% code overflow="wrap" %}

```solidity
function mint(uint256 pid, uint256 amount) external nonReentrant returns (uint256)
```

{% endcode %}

This function mints new ERC1155 tokens by wrapping a user's LP tokens in the ICHI farming pool. It first transfers the LP tokens from the user to the ERC1155 contract, approves the ICHI farming pool to spend the LP tokens, deposits the LP tokens into the ICHI farming pool, and then mints new ERC1155 tokens with the pid and current ichiPerShare values.

**Parameters:**

<table><thead><tr><th width="203.33333333333331">Name</th><th width="153">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>pid</code></td><td>uint256</td><td>The ID of the pool to deposit the LP tokens</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The amount of LP tokens to deposit</td></tr></tbody></table>

**Returns:**

* `uint256`: The token ID that was minted.

#### burn

{% code overflow="wrap" %}

```solidity
function burn(uint256 id, uint256 amount) external nonReentrant returns (uint256)
```

{% endcode %}

This function burns existing ERC1155 tokens to redeem a user's LP tokens from the ICHI farming pool and claim any pending ICHI rewards. It first decodes the token id to extract the pid, then burns the ERC1155 tokens from the user's account. It then calls the `harvest` and `withdraw` functions of the ICHI farming pool to claim the user's LP tokens and ICHI rewards, respectively. If the user has any pending ICHI rewards in the legacy ICHI contract, this function converts them to ICHI v2 tokens. Finally, the user's LP tokens and ICHI rewards are transferred to the user's account.

**Parameters:**

<table><thead><tr><th width="203.33333333333331">Name</th><th width="248">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>id</code></td><td>uint256</td><td>The ERC1155 token ID to burn</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The amount of tokens to burn</td></tr></tbody></table>

**Returns:**

* `uint256`: The pool ID that you will receive LP tokens back.

#### \_ensureApprove

{% code overflow="wrap" %}

```solidity
function _ensureApprove(address token, address spender, uint256 amount) internal
```

{% endcode %}

This internal function ensures that a user has approved the spender to spend at least the given amount of the given token. If the current allowance is less than the required amount, it approves the spender to spend the token up to the required amount.

**Parameters:**

<table><thead><tr><th width="201.33333333333331">Name</th><th width="171">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>token</code></td><td>address</td><td>The address of the token to check</td></tr><tr><td><code>spender</code></td><td>address</td><td>The address of the spender to check</td></tr><tr><td><code>amount</code></td><td>uint256</td><td>The amount of allowance to ensure</td></tr></tbody></table>


# Interact with Blueberry V1

## Example of what happens when users open a position on Blueberry V1


# Deployed Contracts

Blueberry Protocol - Mainnet&#x20;

<table><thead><tr><th width="307">Contract Name</th><th>Address</th><th data-hidden>Name</th><th data-hidden>Address</th></tr></thead><tbody><tr><td>BANK</td><td><pre><code>0xa34F59F634d48E2c3606048f2367326c46a4B5fA
</code></pre></td><td>Blueberry Bank</td><td></td></tr><tr><td>BLUEBERRYSTAKING</td><td><pre><code>0x10831C146Ee2e7214C09809f7E6003fe620522eb
</code></pre></td><td>Safebox CRV</td><td>0xB9C8D20BB251ee2E85D6276b0029b0d862d34c10</td></tr><tr><td>PROTOCOLCONFIG</td><td><code>0x26c85a3780ef040Bc29F7b2002DfeD2D493Df4d4</code></td><td>Safebox SUSHI</td><td>0x3f3E885c89db8EeFCF44e89Ed317E3a16e5bD768</td></tr><tr><td>FEEMANAGER</td><td><code>0x0D2A69FD6074cf2bFAeF844d65f13459E80309af</code></td><td></td><td></td></tr><tr><td>CORE_ORACLE</td><td><pre><code>0xdfe469ACe05C3d0D4461439e6cF5d0f46F33Ec56
</code></pre></td><td>Protocol Config</td><td>0xBaC40FA0f2b9Eee6EB4FFfa02557579434Da0BBB</td></tr><tr><td>ibCRVUSD</td><td><pre><code>0x0BA5761092727502b48575288B4A2B8f2FB724AE
</code></pre></td><td>WERC20</td><td></td></tr><tr><td>ibDAI</td><td><pre><code>0xCD68475A160a256a2C0595c36F497B7cD1fC7672
</code></pre></td><td>Core Oracle</td><td>0x214b2Fab2541c9cA8B206e6E3B07fa5c6b7731Bf</td></tr><tr><td>ibLINK</td><td><pre><code>0xb9ea938A795A1765b6Dc1391239a8a4235E9362c
</code></pre></td><td>Aggregator Oracle</td><td>0x71AE1ecd4d7ebfbE8D6df4112fe6867Ca3092428</td></tr><tr><td>ibOHM</td><td><pre><code>0xadba98da5064009a2a9ea22cef2a36a83f1dbed8
</code></pre></td><td>Band Adapter Oracle</td><td>0xA370c6AFceE58564654e55Ff38bd835DaC7AaC4f</td></tr><tr><td>ibUSDC</td><td><pre><code>0x59df20be61e4d74db96f247e6e57e2667bbf0d92
</code></pre></td><td>Chainlink Adapter Oracle</td><td>0x23BF202cB8BABF1c5c63F7b3a0fc4d0692B0E6b4</td></tr><tr><td>ibWBTC</td><td><pre><code>0x55573fa1aa85ee3d4e85156c38a02d4deca95ced
</code></pre></td><td>Ichi Lp Oracle</td><td></td></tr><tr><td>ibWETH</td><td><pre><code>0xcCd438a78376955A3b174be619E50Aa3DdD65469
</code></pre></td><td>Uniswap V3 Adapter Oracle</td><td>0x5b9a09DeC224aF6b88Cd7323827c2dBeFf04d101</td></tr><tr><td>ibFRAX</td><td><pre><code>0xE1a50DdDc74D2cc557781241860f82db2F99f4f4
</code></pre></td><td>Safebox WBTC</td><td>0xdeD213400c9abD2C812Afe5d696B7C385a7B23e2</td></tr><tr><td>ibALCX</td><td><pre><code>0x1413E54AEC40DE7Aab54251B09FA2268b317540c
</code></pre></td><td>Safebox WETH</td><td>0x280b7363B5F93C693fC0094a98AcF0330Ff82283</td></tr><tr><td>ibBAL</td><td><pre><code>0xB0269Bb4c541D84D69fE710B0983C0A833efaAcC
</code></pre></td><td>Safebox USDC</td><td>0x7c6448697CACf6B11dD2161a3ACD8752F4b6d342</td></tr><tr><td>ibCRV</td><td><pre><code>0x6faA7815F6a2f5FBf2e4A49A590206cD94925d57
</code></pre></td><td>Safebox Dai</td><td>0xffC0D6ACc9815E7b794440b48a915c4227521D3C</td></tr><tr><td>ibWSTETH</td><td><code>x8DE384d5407ca3477b338Ee7a392caFFDD889F2D</code></td><td>Safebox ICHI</td><td>0x7AB4461a1FE4EfAea7DAfe1fef3e0f165bf2711e</td></tr><tr><td>HARD_VAULT</td><td><code>0x426aaA5E187BBe327D3A42795316D61DADa006E8</code></td><td>Ichi Spell</td><td></td></tr><tr><td>ChainlinkAdapterOracle</td><td>0xC5CEa3f9C92291335076D4C2eC6Ae72E45Fb8937</td><td>WIchiFarm</td><td></td></tr><tr><td>CurveStableOracle</td><td><code>0x58660E94E910DB4215B57823Be7F32A11Ac69532</code></td><td></td><td></td></tr><tr><td>CurveTricryptoOracle</td><td><code>0x89DCe547640d98491437c7B0D5a4EE2693CbBD0C</code></td><td></td><td></td></tr><tr><td>CurveVolatileOracle</td><td><code>0x74Cdfa37F1CE8050465891DC0fE902aAb60Cc4f4</code></td><td></td><td></td></tr><tr><td>BlueberryVaultOracle</td><td><code>0x265E5c511b09CBE9553A986fbf9e1B965ddFf076</code></td><td></td><td></td></tr><tr><td>SoftVaultOracle</td><td><code>0x34534ddAB3275B854Ae2a63d3B67AbF3E8b4cD83</code></td><td></td><td></td></tr><tr><td>StableBPTOracle</td><td><code>0xA05FE2e46b386398f5a252Aa91e4C4bba73ECb33</code></td><td></td><td></td></tr><tr><td>UniswapV2Oracle</td><td><code>0xf11Ccc7AEBe657491483B17e36102fbfB2c5651A</code></td><td></td><td></td></tr><tr><td>UniswapV3Oracle</td><td><code>0xf449137e8753BCFd636706Be0C74709Fdd12f215</code></td><td></td><td></td></tr><tr><td>WeightedBPTOracle</td><td><code>0xA2f05a35C801c45A1ae735176783CD1C16E1966f</code></td><td></td><td></td></tr><tr><td>AuraSpell</td><td><code>0x2345FC4759dB11269AfDc10b7C9B7c2a91284174</code></td><td></td><td></td></tr><tr><td>ConvexStableSpell</td><td><code>0x15b52F1B28f85935b2a94E9Ed8A962f66D61F28B</code></td><td></td><td></td></tr><tr><td>ConvexTricryptoSpell</td><td><code>0xdF0621a461Bd0a1dB92e903411dC56b753e4D87d</code></td><td></td><td></td></tr><tr><td>ConvexVolatileSpell</td><td><code>0x825c309955BE3d56Ef16DcECA0e9ac972a7012bD</code></td><td></td><td></td></tr><tr><td>BlueberryVaultSpell</td><td><code>0x30fBb43D6392AFE93F840c90D0aeA7ADBc3C287F</code></td><td></td><td></td></tr><tr><td>ShortLongSpell</td><td><code>0x3B1b4af714d7081401B9B65b7258703a2F0885bc</code></td><td></td><td></td></tr></tbody></table>

## Blueberry Money Market (Compound Fork)

<table><thead><tr><th>Contract </th><th>Address</th><th data-hidden>Name</th><th data-hidden>Address</th></tr></thead><tbody><tr><td>Unitroller</td><td>0xcb0D9Ff5BDD34521c6f8CDbeAf15e1A76Fa4dd5D</td><td>Unitroller</td><td>0x5A8D2edcE98cF37d55fF3Eb4BA70D6d240f2aedD</td></tr><tr><td>Comptroller</td><td>0x327e45B3444ccA9Ce1559780CFd44181A175e83c</td><td>Comptroller</td><td>0x37697298481d1B07B0AfFc9Ef5e9cDeec829EFc8</td></tr><tr><td>BTokenAdmin</td><td>0xD94B367B222f72434C70ad36B6A36944561fA5F4</td><td>Price Oracle</td><td></td></tr><tr><td>PriceOracleProxy</td><td>0x16D43cAC32329ec286Dc14431e0c0E805e6F5174</td><td>Price Oracle Proxy</td><td>0x301F4403DDE8948417Ed8375bBdBcD32C34F43A5</td></tr><tr><td>PriceOracleProxyUSD</td><td>0xc29C188E81A0Dede959Beeb1dB181c121f19476D</td><td></td><td></td></tr><tr><td>TrpleSlopeRateModelV2 - (High)</td><td>0xC82151fc8C8f4c8042beea293FeAb8764221d7fD</td><td>BToken Admin</td><td>0x11987d539004c440D76B852FfF6d49005C65709f</td></tr><tr><td>TripleSlopeRateModelV2 - (Minor)</td><td>0x04C5e346Ee1ED50726B8452362A1C8C003abd26E</td><td>Price Oracle Proxy USD</td><td></td></tr><tr><td>bALCX</td><td>0xc5435051ccc67b4BB8DB8D27f9641C3309b320CC</td><td>Compound Lens</td><td>0x6c73798750F4a46B7C6a8296830c931a765Dd50a</td></tr><tr><td>bBAL</td><td>0x864aDa7223542Ec6eF92789ae524263D7fE9fD96</td><td>bWBTC</td><td>0x506c190340F786c65548C0eE17c5EcDbba7807e0</td></tr><tr><td>bCRV</td><td>0xdeBd5D482C2B0feeA5527f9B832F7F894c8303eB</td><td>bWETH</td><td>0x8E09cC1d00c9bd67f99590E1b2433bF4Db5309C3</td></tr><tr><td>bCRVUSD</td><td>0x9BdeCce77c6351b1941a827e25b5FdC73d69b622</td><td>bUSDC</td><td>0xdfd54ac444eEffc121E3937b4EAfc3C27d39Ae64</td></tr><tr><td>bDAI</td><td>0x23388Cca2BdFC994D75999667E09cc0F5fF1cc88</td><td>bDAI</td><td>0xcB5C1909074C7ac1956DdaFfA1C2F1cbcc67b932</td></tr><tr><td>bFRAX</td><td>0xA51406abFc4658c542b69c2f5a8BAbe61e21B416</td><td>bCRV</td><td>0x23ED643A4C4542E223e7c7815d420d6d42556006</td></tr><tr><td>bLINK</td><td>0x65cf55f03e2040D214883f6039FC65fd224E6A47</td><td>bSUSHI</td><td>0x8644e2126776daFE02C661939075740EC378Db00</td></tr><tr><td>bOHM</td><td>0xfB8Ddd624E340204F32905692C3fD7da59335E81</td><td>bICHI</td><td>0xBDf1431c153A2A48Ee05C1F24b9Dc476C93F75aE</td></tr><tr><td>bUSDC</td><td>0xb5A7D8c7f85BB48fcF10AD5C3EFB090a3fE40069</td><td></td><td></td></tr><tr><td>bWBTC</td><td>0x045Cb2fFea4c2cef4e9a754Bd02bD6Bb9E0DF841</td><td></td><td></td></tr><tr><td>bWETH</td><td>0x643d448CEa0D3616F0b32E3718F563b164e7eDd2</td><td></td><td></td></tr><tr><td>bWSTETH</td><td>0xB387fd973358d2DfdE4F3795Bc9d2CCeE6449A40</td><td></td><td></td></tr></tbody></table>


# Audits

Blueberry Protocol is committed to ensuring the highest level of security and transparency. To achieve this, the protocol has undergone and will continue to undergo audits from the following reputable

## Audit #1: Hacken

{% file src="/files/KqvUVsmq81pwrajMe71M" %}

The first completed audit with Hacken passed with a security score of 10 out of 10. Hacken audited the entirety of the Earn section of the protocol, starting in Q4 of 2022 and completing the audit on April 25, 2023.

The first completed audit with Hacken passed with a security score of 10 out of 10. Hacken audited the entirety of the Earn section of the protocol, starting in Q4 of 2022 and completing the audit on April 25, 2023.

About [Hacken](https://hacken.io)

We believe blockchain cybersecurity is not only about asset protection but a whole new way of doing Web3: without scams and hacks, rug pulls, wash trading, and circulation supply manipulations. New Web3 is about respecting your community, being honest with your investors and partners, acting responsibly, and valuing reputation.

## Audit #2 & Updates: Sherlock

Sherlock completed its first audit at the end of March 2023, and the code is being audited a second time on April 25, 2023, with multiple rounds of updates. The audit reports can be found at the following links:

1. [Contest 41](https://audits.sherlock.xyz/contests/41/report)
2. [Contest 69](https://audits.sherlock.xyz/contests/69/report)&#x20;
3. [Contest 77](https://audits.sherlock.xyz/contests/77/report)
4. [Contest 104](https://audits.sherlock.xyz/contests/104/report)

About [Sherlock](https://www.sherlock.xyz/):

Sherlock combines the best aspects of legacy audits and audit contests to create the most secure audit in Web3. Sherlock also provides insurance coverage for audited protocols.

## Audit # 3 : 0x52

0x52 provided an independent audit for the protocol after the completion of the most recent Sherlock audit competition. During multiple update competitions in Sherlock, 0x52 was the Lead Watson. The audit report can be found [here](https://github.com/Blueberryfi/audits/blob/main/BlueberryFixReview.md)\
\- <https://github.com/Blueberryfi/audits/blob/main/BlueberryFixReview.md>

0x52 is a respected independent auditor in the blockchain space, known as the Lead Senior Watson in 25+ Contests.

## Audit # 4 : Cuthalion0x

Cuthalion0x provided an independent audit for the protocol after the protocol was temporarily paused. This included a full audit of the entire protocol with the interworkings between money-market and the leverage portion of the protocol.\
\- <https://github.com/Blueberryfi/audits/blob/main/Blueberry%20Audit%20-%20Cuthalion0x.md>&#x20;

About [Cuthalion0x](https://twitter.com/cuthalion0x)

## Blueberry Staking Audit # 1: Sec3

Sec3 provided a token staking audit for the $BLB token, which was completed on December 13, 2023. The audit report can be found [here](https://github.com/Blueberryfi/audits/blob/main/blueberry-stakevest_report_final.pdf).

About [Sec3](https://www.sec3.dev/):

Sec3 is a security and research firm providing bespoke audits and cutting edge security software to Web3 projects.

## Blueberry Staking Audit #2: Cuthalion0x

<https://github.com/Blueberryfi/audits/blob/main/Staking%20Audit%20Report%20Cuthalion0x.md>

## Blueberry Staking Audit #3: 0x52&#x20;

<https://github.com/Blueberryfi/audits/blob/main/BlueberryStakingAuditReportFinal.md>

## Token  Audit: Black Tokenomics

About [Black Tokenomics](https://blacktokenomics.com/tokenomics-audit/)

Our Audit service for Venture Capitalists and Funds is designed to provide our investment firms partners with the data and insights they need to make informed investment decisions in the web 3.0 space

{% file src="/files/BWMd2iNooOn6SXcJbCyz" %}

## Real-Time Security Monitoring

Blueberry has partnered with [HyperNative](https://www.hypernative.io/), a leading Web3 security firm, to bolster its security posture through real-time threat detection, exploit prevention, and continuous monitoring. HyperNative's advanced solutions enable early identification of potential vulnerabilities, allowing proactive mitigation measures and timely protocol pausing before exploits can occur, thus fortifying Blueberry's defenses against evolving cyber threats.

<br>


# Bug Bounty

## Program Overview

This bug bounty is specifically for Blueberry's smart contract code. The partners will be announced closer to the launch of Blueberry.


# Terms of Service

Last updated and effective date: July 10, 2023

Please read these Terms of Service (“Agreement” or “Terms”) carefully. Your use or access of the Protocol (as defined below) constitutes your consent to this Agreement. This Agreement is between you and Blueberry Protocol Foundation (Panama City, Panama)., for itself and each of their respective affiliates (together with its subsidiaries and affiliates, “Blueberry”, “we”, “our” or “us”), developer of the Blueberry Protocol currently available at [https://www.blueberry.garden](https://blueberry.garden) (the “Protocol”) and applies to your use of the Protocol and use of the borrowing and lending services facilitated by the Protocol (collectively, “Services”).

This Agreement hereby incorporates by this reference any additional terms and conditions with respect to the Protocol or Services posted by Blueberry to the Protocol or otherwise made available to you by Blueberry, including without limitation, during the creation, acquisition, transfer or modification of cryptocurrency, our Services, and software provided on or in connection with those Services.

The Blueberry Protocol Foundation's domicile is Oceania Business Plaza, Tower 1000, 21st Floor, Isaac Hanono Missri Street, Punta Pacifica, Panama City, Republic of Panama.

If you are an individual accessing or using the Protocol or Services on behalf of, or for the benefit of, any corporation, partnership or other entity with which you are associated (“Organization”), then you are agreeing to this Agreement on behalf of yourself and such Organization, and you represent and warrant that you have the legal authority to bind such Organization to this Agreement. References to “you” and “your” in this Agreement will refer to both the individual using the Protocol or Services and to any such Organization.<br>

THIS AGREEMENT CONTAINS A BINDING ARBITRATION CLAUSE AND CLASS ACTION WAIVER THAT IMPACT YOUR RIGHTS ABOUT HOW TO RESOLVE DISPUTES. PLEASE READ IT CAREFULLY.

&#x20;

## Description of the Protocol and Services

Blueberry is a lending and leveraged yield farming machine for risk management and undercollateralized borrowing using decentralized finance on the Ethereum blockchain.

## General Agreement

By accessing or using the Protocol and/or Services, you agree that you have read, understood and accept all of the terms and conditions contained in this Agreement as well as our Privacy Policy. You also represent that you have the legal authority to accept these Terms on behalf of yourself and any party you represent in connection with your use of the Protocol and Services. If you are an individual who is entering into these Terms on behalf of an Organization, you represent and warrant that you have the power to bind that Organization, and you hereby agree on that Organization’s behalf to be bound by these Terms, with the terms “you” and “your” applying to you, that Organization, and other users accessing the Protocol and/or Services on behalf of that Organization.

We may, in our sole and absolute discretion, without liability to you or any third-party, refuse to let you use the Protocol and/or one or more of the Services. Such actions may be taken as a result of a number of factors, including without limitation legal/regulatory requirements or demand, our discretion or your violation of the terms of this Agreement. We may also temporarily suspend your access to the Protocol and/or Services if a technical problem so requires.

## Ownership and Control of Cryptocurrency

Title to your cryptocurrency shall at all times remain with you and shall not transfer to Blueberry. As the owner of your own cryptocurrency, you shall bear all risk related to the cryptocurrency in your wallet(s). Blueberry shall have no liability for value fluctuations of cryptocurrency. None of the cryptocurrency is the property of, or shall or may be loaned to, Blueberry.

Blueberry does not represent or treat any cryptocurrency in your wallet(s) as belonging to Blueberry. Blueberry may not grant a security interest in the cryptocurrency held in your wallet(s). Except as required by a facially valid court order, or except as provided herein, Blueberry will not sell, transfer, loan, hypothecate, or otherwise alienate cryptocurrency unless instructed by you. You control the cryptocurrency held in your wallet(s).

The Protocol is a purely non-custodial application, meaning you are solely responsible for the custody of the cryptographic private keys to the digital asset wallets you hold. This Agreement is not intended to, and does not, create or impose any fiduciary duties on us. To the fullest extent permitted by law, you acknowledge and agree that we owe no fiduciary duties or liabilities to you or any other party, and that to the extent any such duties or liabilities may exist at law or in equity, those duties and liabilities are hereby irrevocably disclaimed, waived, and eliminated. You further agree that the only duties and obligations that we owe you are those set out expressly in this Agreement.

## Wallets

YOU ACKNOWLEDGE AND AGREE THAT (A) BLUEBERRY HAS NO CONTROL OVER ANY WALLET THAT YOU MAY USE IN CONNECTION WITH YOUR USE OF THE PROTOCOL OR SERVICES; (B) ALL WALLETS ARE PROVIDED BY THIRD-PARTIES; (C) BLUEBERRY HAS NO RIGHT OR ABILITY TO CONTROL THIRD-PARTIES WHO PROVIDE WALLETS; (D) ANY DISPUTE BETWEEN YOU AND ANY THIRD-PARTY WALLET PROVIDER IS BETWEEN YOU AND THAT THIRD-PARTY WALLET PROVIDER; AND (E) BLUEBERRY IS NOT LIABLE FOR ANY ISSUES OR LOSSES CAUSED BY USE OF THIRD-PARTY WALLETS.

## Security of Devices and Wallets

You are responsible for maintaining the confidentiality and security of the device(s) that you use to access the Protocol. You are also responsible for maintaining the security of your wallet(s), and for ensuring that no unauthorized person has access to your wallet(s), any private keys, or any devices that you utilize in connection with the Protocol and Services.&#x20;

We will not be liable for any loss or damage arising from your failure to protect your device(s) or your wallet(s).

It is your sole responsibility to provide accurate information to us. You are solely responsible for ensuring the accuracy and completeness of all information and materials that you provide to use in connection with your use of the Protocol.&#x20;

## Fees

The Ethereum blockchain requires the payment of a transaction fee (“Gas Fee”) for every transactionthat occurs on the network. The Gas Fee funds the network of computers that run the blockchain. This means that you will need to pay a Gas Fee for each transaction. Accordingly, you must ensure that you have a sufficient balance of cryptocurrency stored at your wallet to complete any transaction on the applicable blockchain before initiating such transactions. We will make reasonable efforts to notify you of any Gas Fees before initiating any services that require the use of the blockchain network.

You may be subject to certain additional fees and commissions, including fees imposed by Blueberry. While we do not currently charge for the use of any of our Services or access to the Protocol, we reserve the right to levy additional fees in the future, including fees for access to Information or service fees to support the operation of the Protocol. You agree to promptly pay such fees and commissions, as set forth on the Protocol and the transactions and services you receive, which we may modify from time to time. In the event that we add fees to the Protocol or any of our Services, we will alert you in writing prior to any such fees going into effect.

## Cryptocurrency Transactions

You should confirm all information before you make any transfers to any third-party wallet. Blueberry will bear no liability or responsibility if you enter an incorrect blockchain destination address, incorrect Destination Tag/Memo, or send your cryptocurrency to an incompatible or someone else’s wallet. We do not guarantee the identity or value received by a recipient of an outbound transfer of cryptocurrency from the Protocol to third-party wallets.

## Lending and Borrowing Terms

All of the Protocol’s code is novel and experimental. Please use discretion when depositing funds. While we have thoroughly reviewed our code, we are not liable for funds lost due to smart contract exploits. Moreover, crypto assets displayed on the Protocol are exposed to market fluctuations. Your capital might change due to price action and other external factors. Take note that price fluctuations also cause “impermanent loss” when dealing with liquidity pools.

A transaction on the Protocol may fail for several reasons, including without limitation a change in prices, order availability, or technical difficulties experienced by us, decentralized finance counterparties or Ethereum nodes. We make no representation or warrant that any transaction will be executed fully, or at all. We are, under no circumstances, liable for any loss or injury suffered by a failure of a transaction to complete properly or in a timely manner, including dispatching to the blockchain. Further, we are in no way responsible for notifying you of a transaction failure, although you are able to see any such failures on the Protocol. You have full responsibility to determine and inquire into the failure of any transaction which you initiate.

WE MAY REMOVE A CRYPTOCURRENCY FROM LENDING OR BORROWING ON THE PROTOCOL AT ANY TIME, FOR ANY REASON, WITHOUT PRIOR NOTICE. You acknowledge that while we are using commercially reasonable methods to provide lending and borrowing functionality to you through our Protocol and Services, we do not guarantee that the Protocol or Services will be consistently available. You agree that you assume all risks and potential losses associated with cryptocurrency being removed, price fluctuations, or differences in actual versus indicated prices.

We operate as a Protocol provider and do not act as principal or counterparty with respect to any transactions entered on the Protocol. Strategies will generally involve usage of other Ethereum decentralized finance platforms. This will add a layer of counterparty risk.&#x20;

&#x20;

You understand and acknowledge that we do not broker trading orders on your behalf. We also do not facilitate the execution or settlement of your trades, which occur entirely on the Ethereum blockchain. As a result, we do not (and cannot) guarantee market best pricing or best execution through the Protocol. Any references in the Interface to “best price” do not constitute a representation or warranty about pricing available through the Protocol or elsewhere.

You agree and understand that: (a) all trades you submit through the Protocol are considered unsolicited, which means that they are solely initiated by you; (b) you have not received any investment advice from us in connection with any trades; and (c) we do not conduct a suitability review of any trades you submit.

## Taxes

It is your responsibility to determine what, if any, taxes apply to the transactions you make, and to report and remit the correct tax to the appropriate tax authority. We are not responsible for determining whether taxes apply to your transaction, or for collecting, reporting, or remitting any taxes arising from any transaction. We encourage you to speak with your personal tax advisor regarding the tax implications of your use of the Protocol and Services. &#x20;

&#x20;

## Third-Party Services

Blueberry may contract with third-parties, including those providing research analysis or other information related to the Protocol and Services to provide certain data, information, insights, analysis, and articles that are made available through the Protocol and Services, and may also provide links to third-party websites (or other online properties that are not owned or controlled by Blueberry) or services that are not under the control of Blueberry (collectively, “Third-Party Services”). In addition to these Terms, you may be bound by any additional terms required by providers of Third-Party Services. Blueberry makes no representations about, and accept no liability for, any Third-Party Services. Blueberry are not responsible for the accuracy or reliability of any information, data, opinions, advice, or statements contained in Third-Party Services, the services offered thereby or for their privacy and security policies and procedures.

&#x20;

## Acceptable Use

In connection with your use of the Protocol and Services, you will not:<br>

* Violate or assist any party in violating any law, statute, ordinance, regulation or any rule of any self-regulatory or similar organization of which you are or are required to be a member through your use of the Protocol or Services;
* Engage in any lending or borrowing activity which, in our sole discretion, amounts to or may amount to market abuse including without limitation pumping and dumping, entering fictitious transactions, or engaging in disorderly market conduct;
* Infringe upon our or any third-party’s copyright, patent, trademark, or other intellectual property rights;
* Repost, delete, or alter any content or material that Blueberry makes available on the Protocol or Services;
* Restrict or inhibit any other person from legal use of the Protocol or Services;
* Reproduce, modify, adapt, translate, create derivative works of, sell, rent, lease, loan, timeshare, distribute or otherwise exploit any portion of (or any use of) the Protocol or Services except as expressly authorized herein, without Blueberry’s express prior written consent;
* Use the Protocol in an unauthorized manner, including collecting email addresses or Discord usernames of users by electronic or other means for the purpose of sending unsolicited emails or communications;
* Reverse engineer, decipher, decompile or disassemble any portion of the Protocol or Services, except to the extent such restriction is expressly prohibited by applicable law;
* Remove any copyright, trademark or other proprietary rights notice from the Protocol or Services;
* Frame or mirror any portion of the Protocol or Services, or otherwise incorporate any portion of the Protocol or Services into any product or service, without Blueberry’s express prior written consent;
* Engage in any attack, hack, denial-of-service attack, interference, or exploit of any smart contract;
* Systematically download and store content from the Protocol or Services;
* Take any action that imposes an unreasonable or disproportionately large load on our infrastructure or that of our nodes, or detrimentally interfere with, intercept, or expropriate any system, data or information;
* Post, transmit or otherwise make available through or in connection with the Protocol any virus, worm, Trojan horse, Easter egg, time bomb, spyware, ransomware, malware, or other computer code, file or program that is or is potentially harmful or invasive or intended to damage or hijack the operation of, or to monitor the use of, any hardware, software or equipment.
* Otherwise attempt to gain unauthorized access to or use of the Protocol or Services, nodes or computer systems connected to the Protocol or Services;
* Engage in any behavior which violates this Agreement or is otherwise deemed unacceptable by us in our sole discretion; or
* Use any robot, spider, search/retrieval application or other manual or automatic device to retrieve, index, “scrape,” “data mine”, or otherwise gather content on the Protocol or Services (including Submissions), or reproduce or circumvent the navigational structure or presentation of the Protocol or Services, without Blueberry’s express prior written consent. Notwithstanding the foregoing, and subject to compliance with applicable law and any instructions posted in the robots.txt file located in the Protocol’s root directory, Blueberry grants to the operators of public search engines permission to use spiders to copy materials from the Protocol or Services for the sole purpose of (and solely to the extent necessary for) creating publicly available, searchable indices of such materials, but not caches or archives of such materials. Blueberry reserves the right to revoke such permission either generally or in specific cases, at any time and without notice.

## Restricted Jurisdictions

The Protocol and Services are subject to all applicable export control restrictions, and, by using the Protocol and/or Services, you represent that your actions are not in violation of such export control restrictions. Without limiting the foregoing, you may not use the Protocol or Services if you are (i) a resident, national or agent of Crimea, Cuba, Iran, North Korea, Syria or any other country or region to which the United States embargoes goods or imposes similar sanctions (“Restricted Jurisdictions”); (ii) a member of any sanctions list or equivalent maintained by the United States government (“Restricted Persons”); or (iii) you intend to transact with any Restricted Jurisdictions or Restricted Persons.

## Sanctions

By using the Protocol or Services, you further represent and warrant that you are not (i) the subject of sanctions administered or enforced by the United States (including without limitation the U.S. Department of the Treasury’s Office of Foreign Asset Control), the United Kingdom, the European Union or any other governmental authority (Sanctions) or (ii) organized or resident in a country or territory that is the subject of country-wide or territory-wide Sanctions.

## Reservation of Rights

Blueberry reserves the right to bar any transactions on the Protocol, for or with, any user with or without cause, at any time, subject to any limitations imposed by applicable law. In lieu of refusing access to the Protocol or Services, Blueberry may, in its sole and absolute discretion, perform due diligence. You may be subject to due diligence procedures in your use of the Protocol or Services. If you decline to provide requested information or otherwise do not reply timely or substantively with the documentation or data requested, Blueberry has the absolute discretion to immediately suspend or terminate your use of the Protocol and Services.

## Intellectual Property Rights

The Protocol and its entire contents, features, and functionality (including but not limited to all Services, information, software, text, displays, images, video, and audio, and the design, selection, and arrangement thereof and with the exception of User Content), are owned by Blueberry, its licensors, or other providers of such material and are protected by United States and international copyright, trademark, patent, trade secret, and other intellectual property or proprietary rights laws. Blueberry grants you a revocable, non-exclusive, non-transferable, non-sublicensable, royalty-free and worldwide right and license to access and use the Protocol or Services solely in strict compliance with the provisions of this Agreement and as permitted by the functionalities of the Protocol or Services available to you.

Blueberry’s name and all related names, logos, product and service names, designs, and slogans (“Blueberry branding”) are trademarks of Blueberry, its associates, or licensors (collectively, “Associates”). You must not use any Blueberry branding without the prior written permission of Blueberry. All other names, logos, product and service names, designs, and slogans on this Protocol are the trademarks of their respective owners.

## Risk Disclosures

Lending and borrowing cryptocurrency is risky and you should never lend or borrow more than they can afford to lose or pay back. The following list of risks associated with cryptocurrency, the Protocol, and Services is not exhaustive.&#x20;

&#x20;

*Risks of lending and borrowing cryptocurrency*

\
Cryptocurrency prices are highly volatile and lending and borrowing cryptocurrency is extremely risky. In addition, factors beyond our control may affect market liquidity for a particular cryptocurrency, such as regulatory activity, market manipulation, the acts or omissions of the issuer of the cryptocurrency, or unexplainable price volatility. We may also determine it is in the best interest of users to suspend lending or borrowing a cryptocurrency for these reasons. By using the Protocol and Services, you accept the risk of lending or borrowing cryptocurrency. In entering into any transaction, you represent that you have been, are, and will be solely responsible for making your own independent appraisal into the risks of the transaction and the underlying cryptocurrency.&#x20;

&#x20;

Our listing of a cryptocurrency does not indicate approval or disapproval of the cryptocurrency’s merits as an investment or a technology. We give no warranty as to the suitability of a cryptocurrency loaned or borrowed under this Agreement and assume no fiduciary duty in our relations with you. You must conduct your own due diligence when determining whether to lend or borrow a particular cryptocurrency. If you choose wisely, we will not share in any portion of your gains. Likewise, if you choose poorly, we will not bear any portion of your losses. &#x20;

&#x20;

*No brokering transactions or provision of investment advice*

&#x20;

We provide an execution-only service. We do not broker transactions on your behalf, advise on the merits of any particular cryptocurrency, transactions, or associated risks, or provide any other financial, investment or legal advice in connection with the Protocol or Services. To the extent that we do provide data, post market commentary, articles, or make social media posts, the act of doing so is incidental to your relationship with us and such information may not be considered as investment or financial advice and should not be construed as such. ANY DECISION TO LEND OR BORROW CRYPTOCURRENCY IS SOLELY YOUR DECISION AND WE WILL NOT BE LIABLE FOR ANY CONSEQUENT LOSS.&#x20;

&#x20;

*No promise of liquidity*

We make no promises as to the timing or availability of lending or borrowing of cryptocurrency on the Protocol. We reserve the right to change, suspend, or discontinue any aspect of the Protocol or Services at any time and in any jurisdiction, without notice and without liability. This includes, without limitation, the absolute discretion to list and de-list cryptocurrency available for lending or borrowing at any time. We are not required to provide advance notice of delisting. &#x20;

&#x20;

You acknowledge and agree that cryptocurrency and/or Services available in one jurisdiction may not be available, as applicable, in another.

&#x20;

*No guarantee of continuous access to Protocol or Services*

&#x20;

We do not guarantee continuous, uninterrupted or secure access to any part of the Protocol or Services, and operation of our site may be interfered with by numerous factors outside of our control, including regulatory reasons and issues with the blockchain. We will make reasonable efforts to ensure that transactions are processed in a timely manner, but we make no representations or warranties regarding the amount of time needed to complete transactions.

\
Indemnification and Release
---------------------------

Blueberry and its Associates, subsidiaries, parents, affiliates, service providers, and each of their respective officers, directors, agents, joint venturers, employees or representatives (collectively, the “Released Parties”), are not liable for any damages that may arise out of or in connection with your use of the Protocol or Services. This includes, but is not limited to, claims, applications, injuries, delays, direct loss, loss of investments, business, or profits, business interruption costs, loss of goodwill or business profits, loss of cryptocurrency, damage caused by your computer, computer software, systems and programs, and the data thereon or any other direct or indirect, consequential and incidental damages. In addition, the Released Parties are not liable for any losses incurred, either directly or indirectly through your use of the Protocol or any of its functions and features (collectively, all of the foregoing items shall be referred to herein as “losses”). The Released Parties are hereby released by you from liability for any and all losses. These limitations of liability apply whether the liability or losses are based on negligence, contract, tort, or any other basis, even if the Released Parties had been advised or should have known of the possibility of such losses.

&#x20;

You agree to indemnify and hold the Released Parties harmless from any claim or losses (including attorneys’ fees and any losses, fines, fees, or penalties imposed by any regulatory authority) arising out of your breach of this Agreement, or your violation of any law or regulation.

&#x20;

If you have a dispute with one or more users, nodes, issuers of cryptocurrency listed on the Protocol or other third-parties, you release the Released Parties from any and all claims, demands, and damages (actual and consequential) of every kind and nature arising out of or in any way connected with such disputes.

## Limitation of Liability

\
TO THE FULLEST EXTENT PROVIDED BY LAW, IN NO EVENT WILL BLUEBERRY, ITS ASSOCIATES, OR THEIR LICENSORS, SERVICE PROVIDERS, EMPLOYEES, AGENTS, OFFICERS, OR DIRECTORS BE LIABLE FOR DAMAGES OF ANY KIND, UNDER ANY LEGAL THEORY, ARISING OUT OF OR IN CONNECTION WITH YOUR USE, OR INABILITY TO USE, THE PROTOCOL, ANY WEBSITES LINKED TO IT, ANY CONTENT ON THE PROTOCOL OR SUCH OTHER WEBSITES, OR THE SERVICES, INCLUDING ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, OR PUNITIVE DAMAGES, INCLUDING BUT NOT LIMITED TO, PERSONAL INJURY, PAIN AND SUFFERING, EMOTIONAL DISTRESS, LOSS OF REVENUE, LOSS OF PROFITS, LOSS OF BUSINESS OR ANTICIPATED SAVINGS, LOSS OF USE, LOSS OF GOODWILL, LOSS OF DATA, AND WHETHER CAUSED BY TORT (INCLUDING NEGLIGENCE), BREACH OF CONTRACT, OR OTHERWISE, EVEN IF FORESEEABLE. NOTWITHSTANDING ANYTHING TO THE CONTRARY IN THESE TERMS, NOTHING IN THESE TERMS EXCLUDES OR LIMITS LIABILITY FOR FRAUD, FRAUDULENT MISREPRESENTATION, OR FOR DEATH OR PERSONAL INJURY CAUSED BY GROSS NEGLIGENCE.

THE FOREGOING DOES NOT AFFECT ANY LIABILITY THAT CANNOT BE EXCLUDED OR LIMITED UNDER APPLICABLE LAW.

## Disclaimer of Warranties

YOU EXPRESSLY ACKNOWLEDGE AND AGREE THAT YOUR ACCESS TO AND USE OF THE PROTOCOL, SERVICES, AND ANY CONTENT IS AT YOUR SOLE RISK. OTHER THAN AS EXPRESSLY SET OUT IN THESE TERMS, NEITHER BLUEBERRY NOR ITS ASSOCIATES MAKE ANY WARRANTY, EITHER EXPRESS OR IMPLIED, ABOUT THE PROTOCOL OR SERVICES. THE PROTOCOL AND SERVICES ARE PROVIDED ON AN “AS IS” AND “AS AVAILABLE” BASIS, WITHOUT ANY WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. NEITHER BLUEBERRY NOR ITS ASSOCIATES MAKES ANY WARRANTY OR REPRESENTATION WITH RESPECT TO THE COMPLETENESS, SECURITY, RELIABILITY, QUALITY, ACCURACY, OR AVAILABILITY OF THE PROTOCOL OR SERVICES. WITHOUT LIMITING THE FOREGOING, BLUEBERRY AND ITS ASSOCIATES DO NOT REPRESENT OR WARRANT THAT THE PROTOCOL, ITS CONTENT, OR ANY SERVICES OBTAINED THROUGH THE PROTOCOL WILL BE ACCURATE, RELIABLE, ERROR-FREE, OR UNINTERRUPTED, THAT DEFECTS WILL BE CORRECTED, THAT OUR PROTOCOL, SERVICES, OR THE SERVER THAT MAKES THEM AVAILABLE ARE FREE OF VIRUSES OR OTHER HARMFUL COMPONENTS, OR THAT THE PROTOCOL OR ANY SERVICES OBTAINED THROUGH THE PROTOCOL WILL OTHERWISE MEET YOUR NEEDS OR EXPECTATIONS.

THERE MAY BE INADVERTENT TECHNICAL OR FACTUAL INACCURACIES AND TYPOGRAPHICAL ERRORS IN INFORMATION OR MATERIALS ON THE PROTOCOL OR SERVICES, AND BLUEBERRY MAKES NO WARRANTIES REGARDING THE ACCURACY, COMPLETENESS OR TIMELINESS OF SUCH INFORMATION OR MATERIALS. BLUEBERRY PROVIDES NO GUARANTEES AGAINST THE POSSIBILITY OF DELETION, MIS-DELIVERY OR FAILURE TO STORE COMMUNICATIONS, PERSONALIZED SETTINGS, OR OTHER DATA. BLUEBERRY EXPRESSLY DISCLAIMS ALL LIABILITY FOR ERRORS OR OMISSIONS IN, OR THE MISUSE OR MISINTERPRETATION OF, ANY INFORMATION OR MATERIALS CONTAINED ON THE PROTOCOL OR SERVICES.

BLUEBERRY MAKES NO REPRESENTATIONS OR WARRANTIES REGARDING THE LIKELIHOOD OR PROBABILITY THAT YOUR PARTICIPATION ON THE PROTOCOL OR SERVICES WILL ACHIEVE A PARTICULAR OUTCOME OR GOAL. PAST PERFORMANCE IS NOT A GUARANTEE OF FUTURE SUCCESS, AND VOLATILITY MEANS THAT PERFORMANCE IN ANY PERIOD MAY BE FAR DIFFERENT FROM THAT OF PREVIOUS PERIODS. YOU FURTHER ACKNOWLEDGE AND AGREE THAT BLUEBERRY MAKES NO GUARANTEES OR OTHER COMMITMENTS ABOUT YOUR ABILITY TO ACCESS OR USE THE PROTOCOL OR SERVICES.

TO THE MAXIMUM EXTENT PERMITTED BY LAW, BLUEBERRY AND ITS ASSOCIATES ALSO DISCLAIM ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. <br>

SOME STATES OR JURISDICTIONS DO NOT ALLOW THE DISCLAIMER OF IMPLIED WARRANTIES, SO SOME DISCLAIMERS IN THIS SECTION MAY NOT APPLY TO YOU.

We do not guarantee continuous, uninterrupted or secure access to any part of the Protocol or Services, and operation of our Protocol and Services may be interfered with by numerous factors outside of our control, including regulatory reasons and issues with the Protocol. We will make reasonable efforts to ensure that transactions are processed in a timely manner, but we make no representations or warranties regarding the amount of time needed to complete transactions.&#x20;

&#x20;

## Acknowledgment of Risk

Cryptocurrency is not legal tender and is not backed by the government, FDIC, or SIPC protections.&#x20;

&#x20;

You accept and acknowledge each of the following:

* To the extent that you borrow or lend using your cryptocurrency, please be aware that the price of any cryptocurrency is extremely volatile and fluctuations in the price of other cryptocurrency can impact the price of your cryptocurrency both positively and negatively. Given the volatility, cryptocurrency should not be considered an investment. You assume all risks in that regard;&#x20;
* You assume all risks associated with using cryptocurrency and using the Protocol and Services, including, but not limited to, the risk of financial loss, hardware, software and internet issues, the risk of malicious software introduction, and the risk that third parties may obtain unauthorized access to information stored within your device(s) and wallet(s); and
* Cryptocurrency and blockchain technology are relatively new and the regulatory landscape is unsettled. New regulations could negatively impact such technologies impacting the value for your cryptocurrency. You understand and accept all risk in that regard.

Representation & Warranties

You represent and warrant to Blueberry each time you use the Protocol or Services as follows:

* That, if you are an individual user of the Protocol or Services, you are 18 years of age or older;
* That, if you are using the Protocol or Services on behalf of a legal entity (i) such legal entity is duly organized and validly existing under applicable law of the jurisdiction of its organization; and (ii) you are duly authorized by such legal entity to act on its behalf;
* That you are not or residing in a Restricted Jurisdiction;
* That you do not, and will not, use VPN software or any other privacy or anonymization tools or techniques, or other means, to circumvent, or attempt to circumvent, any restrictions that apply;
* That you are not otherwise prohibited by applicable law from using the Protocol and Services;
* That you understand the risks associated with using the Protocol and Services;
* That you have had the opportunity to seek legal, accounting, taxation and other professional advice regarding this Agreement, Protocol, and Services;
* That you will not falsify or materially omit any information or provide misleading or inaccurate information requested by Blueberry in the course of, directly or indirectly relating to, or arising from your activities on the Protocol or use of the Services, including, but not limited to, at registration or during administration or other due diligence processes, and that if any information provided to Blueberry becomes incorrect or outdated, you will promptly provide corrected information to Blueberry;
* That you acknowledge and agree that any wallet you use in connection with the Protocol or Services is wholly controlled and owned by you and that Blueberry does not have any right, title or interest to the wallet, except as otherwise set forth herein;
* That you will not use the Protocol or Services in order to conceal or disguise the origin or nature of proceeds of crime or terrorist financing, or to further, any breach of applicable law, or to deal in any unlawful property, funds, or proceeds;
* That neither you nor any of your affiliates has directly or indirectly offered, promised, given, or authorized any payment, or offered, promised, given, or authorized the giving of anything else of value, including, but not limited to, any cryptocurrency, to a government official or individual employed by another entity in the private sector in violation of any applicable law;
* That you consent to any and all tax and information reporting under applicable law;
* That neither you nor any of your affiliates will use the Services directly or indirectly (i) on behalf of or for the benefit of any person subject to the jurisdiction of a Restricted Jurisdiction; (ii) in violation of or as prohibited, restricted, or penalized under applicable law; or (iii) in any way that would violate, be inconsistent with, penalized under, or cause the omission of filing of any report required under applicable law;
* That you will not falsify or materially omit any information or provide misleading or inaccurate information requested by Blueberry in the course of, directly or indirectly relating to, or arising from your activities on the Protocol, including but not limited to, registration or other due diligence process, and that if any information provided to Blueberry becomes incorrect or outdated, you will promptly provide corrected information to Blueberry; and
* That you will accurately and promptly inform Blueberry if you know or have reason to know whether any of the foregoing representations or warranties no longer is correct or becomes incorrect.

You acknowledge and agree that Blueberry operates and administers the Protocol, but Blueberry is (i) not a counterparty to any lending or borrowing of cryptocurrency by and between you and any third-party, including, but not limited to, the lending or borrowing of cryptocurrency and (ii) is not a counterparty to any Smart Contracts you enter into by and between you and any other user of the Protocol or Services. Blueberry has no financial responsibility or liability for any failure of market participants to honor their financial obligations. There is risk that one or more market participants will renege, default, or otherwise fail to honor their financial obligations or will be unwilling or unable to abide by the terms of their agreements. In the event that risk materializes, other market participants can and likely will incur financial losses. You acknowledge and agree that the holding of cryptocurrency is inherently in risk of the potential for cryptocurrency, and/or wallets, to be lost, stolen, or hacked.

You acknowledge and agree that you have had the opportunity to consult legal counsel in connection with this Agreement even if you chose not to do so. You further acknowledge and agree that this Agreement will not be construed against Blueberry as drafter.

## Data Privacy

You acknowledge that Blueberry may process personal data in relation to you (if you are an individual), and personal data that you have provided or in the future provide to us in relation to your employees and other associated or other individuals, in connection with this Agreement or use of the Protocol or Services. You represent and warrant that any personal data relating to individuals other than yourself was or will be made in accordance with all applicable data protection and data privacy laws, and that data is accurate at the time of disclosure. You further represent and warrant that before providing any such personal data to us, you have read and understood our Privacy Policy, and, in the case of personal data relating to an individual other than yourself, have (or will at the time of disclosure have) provided a copy of that Privacy Policy, to that individual.&#x20;

By accessing or using our Protocol and Services, you consent to the processing, transfer and storage of information about you in and to the United States, European Union, United Kingdom and other countries, where you may not have the same rights and protections as you do under local law.<br>

If you suspect that any of your device(s) or wallet(s) have been compromised, or if you become aware of any fraud or attempted fraud or any other security incident (including a cyber-security attack) affecting you and/or Blueberry, you must notify Blueberry as soon as possible by email and provide accurate information throughout the duration of the incident or breach.

All information we collect on the Protocol and Services is subject to our Privacy Policy. By using the Protocol and/or Services, you consent to all actions taken by us with respect to your information in compliance with our Privacy Policy.

Please note that it is our policy to comply with all facially valid subpoenas, court orders or binding orders issued to us by law enforcement agencies and other government authorities. This may affect your access to our Services. We are not responsible for any losses, whether direct or indirect, that you may incur as a result of our compliance with applicable law, the guidance or direction of any regulatory authority or government authority, or any writ of attachment, lien, levy, subpoena, warrant, or other legal order.

## Comments and Questions

If you choose to provide us with input or suggestions regarding problems with or proposed modifications or improvements to the Protocol or Services (“Feedback”), then you grant to us a non-exclusive, royalty-free, perpetual, irrevocable, transferable, sublicensable, and global right to use and exploit the Feedback in any manner and for any purpose without any restriction, credit, attribution, or fees due to you.

## Governing Law; Venue and Arbitration

You agree to arbitrate any dispute arising from these Terms or your use of the Protocol and Services. Arbitration prevents you from suing in court, litigating through a class action lawsuit, or from having a jury trial. You agree to notify each other in writing of any dispute within sixty days of when it arises.

&#x20;

In addition, you agree:

* To make reasonable attempts for informal resolution prior to any demand for arbitration;
* That any arbitration will occur in the United States;
* That any arbitration will be conducted confidentially by a single arbitrator, selected by a third-party arbitration forum;
* That you cannot litigate any disputes arising from your use or access to the Protocol through class action lawsuits;
* That the state and federal courts in San Francisco, California, United States have exclusive jurisdiction over any appeals of an arbitration award and over any suit between the parties not subject to arbitration;
* That the arbitrator has the authority to grant any remedy that would otherwise be available in court; and
* That the parties shall split the costs and expenses of any arbitration and bear their own legal costs and expenses.

Any dispute between you and Blueberry will be governed by these Terms and the laws of the State of California, without giving effect to any conflict of laws principles that may provide for the application of the law of another jurisdiction.

&#x20;

You will only be permitted to pursue claims against us on an individual basis, not as a plaintiff or class member in any class or representative action or proceeding, and you will only be permitted to seek relief (including monetary, injunctive, and declaratory relief) on an individual basis.

## Class Action Waiver

BY USING THIS SITE AND AGREEING TO THESE TERMS, YOU HEREBY WILLINGLY, EXPRESSLY, AND KNOWINGLY WAIVE ALL RIGHT TO BRING OR PARTICIPATE IN ANY CLASS-ACTION LAWSUIT, CLASS-WIDE ARBITRATION, OR PRIVATE ATTORNEY-GENERAL ACTION BROUGHT UNDER OR IN CONNECTION WITH THIS AGREEMENT OR YOUR USE OF THE PROTOCOL. YOU MAY NOT BRING ANY CLAIM, SUIT, OR OTHER PROCEEDING TO ENFORCE THESE TERMS AS THE MEMBER OF ANY CLASS OR AS PART OF ANY SIMILAR COLLECTIVE OR CONSOLIDATED ACTION.

## Termination and Suspension

These Terms are effective until terminated by us. Blueberry, in its sole discretion, has the right to terminate your access to the Protocol or Services, or any part thereof, immediately at any time. We reserve the right, in our sole and absolute discretion, to restrict, suspend, or terminate your access to all or any part of the Protocol or Service, or to terminate this Agreement at any time without prior notice or liability if you breach any provision of this Agreement or violate the rights of any third-party on or through the Protocol. We reserve the right to change, suspend, or discontinue all or any part of the Protocol at any time without prior notice or liability.

Blueberry is not liable to you or any third-party for termination of your access to the Protocol or Services, or any part thereof. If you object to any of the requirements, statements, or obligations of these Terms, or any subsequent modifications thereto, or become dissatisfied with the Protocol or Services in any way, your only recourse is to immediately discontinue use of the Protocol and/or Services. Upon termination of these Terms, you will cease all use of the Protocol and Services.

## Relationship of the Parties

You agree that no joint venture, partnership, employment or agency relationship exists between you and Blueberry as a result of this Agreement or use of the Protocol or Services.&#x20;

## Force Majeure

We shall have no liability for any failure or delay resulting from any abnormal or unforeseeable circumstances outside our reasonable control, the consequences of which would have been unavoidable despite all efforts to the contrary, including without limitation governmental action or acts of terrorism, war, earthquake, fire, flood, or other acts of God, labor conditions, delays or failures caused by problems with another system or network, mechanical breakdown or data-processing failures or where we are bound by other legal obligations.

## Third-Party Disputes

ANY DISPUTE YOU HAVE WITH ANY THIRD-PARTY, INCLUDING, BUT NOT LIMITED TO, OTHER USERS, IN CONNECTION WITH YOUR USE OF THE PROTOCOL OR SERVICES IS DIRECTLY BETWEEN YOU AND SUCH THIRD-PARTY. ACCORDINGLY, TO THE FULLEST EXTENT PERMITTED BY LAW, YOU IRREVOCABLY RELEASE BLUEBERRY AND ITS ASSOCIATES FROM ANY AND ALL CLAIMS, DEMANDS AND DAMAGES (DIRECT, INDIRECT, AND CONSEQUENTIAL) OF EVERY KIND AND NATURE, KNOWN AND UNKNOWN, ARISING OUT OF OR IN ANY WAY CONNECTED WITH SUCH DISPUTES.

## Assignments

This Agreement will inure to the benefit of our successors and assigns. Blueberry may assign this Agreement, including all its rights hereunder, without restriction. You may not assign this Agreement or any of the rights or licenses granted hereunder without the prior express written consent of Blueberry.

## Amendments

We reserve the right to change this Agreement at any time upon notice. We may give notice by posting the updated Agreement on the Protocol or by any other reasonable means. You can review the most current version of this Agreement at any time. This Agreement in effect at the time of your use of the Protocol apply. Updated versions of the Agreement are binding on you with respect to your use of the Protocol on or after the date indicated in the updated Agreement. If you do not agree to the updated Agreement, you must stop using the Protocol. Your continued use of the Protocol after the date of the updated Agreement will constitute your acceptance of the updated Agreement.

## Survival

The respective indemnities, representations, warranties and agreements of the parties hereto or made by or on behalf of the parties hereto pursuant to this Agreement will survive the termination of this Agreement indefinitely and will remain in full force and effect and all defined terms used therein will survive the termination of this Agreement indefinitely.

## Waiver and Conflict

No waiver of by Blueberry of any term or condition set out in these Terms will be deemed a further or continuing waiver of such term or condition or a waiver of any other term or condition, and any failure of Blueberry to assert a right or provision under these Terms will not constitute a waiver of such right or provision.

If any provision of these Terms is held by a court or other tribunal of competent jurisdiction to be invalid, illegal or unenforceable for any reason, such provision will be eliminated or limited to the minimum extent such that the remaining provisions of the Terms will continue in full force and effect.&#x20;

## Entire Agreement

This Agreement and the Privacy Policy constitute the sole and entire agreement between you and Blueberry with respect to the Protocol and supersede all prior and contemporaneous understandings, agreements, representations and warranties, both written and oral, with respect to the Protocol. This Agreement does not, and will not be construed to, create any partnership, joint venture, employer-employee, agency or franchisor-franchisee relationship between you and Blueberry.

## Third-Party Rights

This Agreement is not intended and shall not be construed to create any rights or remedies in any parties other than you and us and any affiliates which each shall be a third-party beneficiary of this Agreement, and no other person shall assert any rights as a third-party beneficiary hereunder.

## Questions & Comments

If you have any questions or comments about these Terms, please contact us at <info@blueberry.garden>.


# Privacy Policy

Last updated and effective date: July 10, 2023

Blueberry Protocol Foundation., for itself and each of their respective affiliates (together, “Blueberry”, “we”, “us,” “our”), is committed to protecting individual privacy and maintaining the trust of users of the defi lending and borrowing protocol that we developed. (“Users”). It is important to us that we provide transparency regarding our collection, use, and disclosure of the personal information of Users. Personal information as used in this Privacy Policy (this “Policy”) includes information that identifies, relates to, describes, is reasonably capable of being associated with, or could reasonably be linked, directly or indirectly, with a particular individual or household.

To help us meet our commitment to protecting your personal information, we have created this Policy. This Policy governs data protection matters across the Blueberry protocol currently available at blueberry.garden (the “Protocol”). This Privacy Policy, along with our Terms of Use, form an integral and binding part of our relationship with you.

By providing personal information to us or by using our Protocol, you agree to our collection, use, disclosure, and storage of personal information as described in this Privacy Policy. This Policy describes how we use, share, and protect the personal information of individuals who use our Protocol. It also describes your rights and choices regarding the use, access to, and correction of personal information.

1. ## What Our Privacy Policy Covers

   This Policy describes how we use, share, and protect the personal information of our Users. It also describes the rights and choices regarding use, access to, and correction of personal information available.

   \
   Our websites may include links to websites and/or applications operated and maintained by third-parties. Please note that we have no control over the privacy practices of websites or applications that we do not own. We encourage you to review the privacy practices of those third-parties.

2. ## What Personal Information We Collect

   The types of personal information we obtain about you depends on how you interact with us and our products and services. When we use the term “personal information,” we are referring to information that identifies, relates to, describes, or can be associated with you. The following are the categories and specific types of personal information that we collect:\
   \
   **Personal Identifiers**\
   \
   Including your email, social media handles, such as your Discord username and Twitter username or other similar identifiers.\
   \
   **Device Information and Other Unique Identifiers**\
   \
   Including browser type, screen resolution, IP address, unique device identifiers or similar unique identifiers.\
   \
   **Internet or Other Network Activity**\
   \
   Including website(s) visited before browsing our website, how long you spend on a page or screen, navigation paths between pages or screens, date and time of use, pages viewed and links clicked.<br>

3. ## How We Collect Personal Information

   \
   We collect personal information about you from various sources. For example, we collect and obtain information:\
   \
   **Directly from you**\
   \
   We collect personal information that you voluntarily submit to us, such as when you use our website or Protocol or contact us.\
   \
   **Using cookies and other automatic data collection technologies**\
   \
   When you visit our websites, use our Protocol or services, we or third-parties we work with automatically collect certain information using technologies such as cookies, web server logs, and other data collection tools. For more information, please see "Cookies and Similar Tracking Technologies"\
   \
   **From Social Media**\
   \
   If you interact with us on social media in connection with Blueberry, we collect information that you share with us, or that the social media platforms, please review the privacy policies and settings of the social media platforms and networks that you use.\
   \
   **From Other Sources**\
   \
   For example, we may obtain information about you from other sources, such as data analytics providers, marketing or advertising service providers, fraud prevention service providers, vendors that provide services on our behalf, or publicly available sources. We also create information based on our analysis of the information we have collected from you.<br>

4. ## Cookies and Tracking Technologies

   \
   We and our third-party service providers (such as advertising and analytics providers) use cookies and other similar tracking technologies (collectively, “tracking technologies”) to gather information when you interact with our website and Protocol. Some tracking technologies help us maintain the security of our websites and your account, prevent crashes, fix bugs, save your preferences, and assist with basic site functions. These tracking technologies are “required” because we need them for the websites to work properly. We don’t provide the option to opt-out of these tracking technologies, but you can remove these “required” tracking technologies by modifying your browser settings. Please note, some features of our websites may not be available to you as a result.

   \
   We permit third-parties to use tracking technologies on our website and Protocol for analytics to understand how visitors interact with our website and Protocol. For example, we use Google Analytics to evaluate website traffic and usage data to help us improve our products and services. For more information about how Google collects and processes data visit <https://policies.google.com/technologies/partner-sites>.

   \
   For more information about how to opt out of having your information used by Google Analytics, visit <https://tools.google.com/dlpage/gaoptout/>, and for Adobe please visit <https://www.adobe.com/privacy/opt-out.html>.

5. ## How We Use Personal Information

   \
   In general, personal information you submit to us is used either to respond to requests that you make, or to aid us in serving you better. We use your personal information in the following ways:

   \
   **Providing Services**

   \
   We use your personal information to provide the Protocol and services.

   \
   **Communicating With You**

   \
   We use your personal information to communicate with you, such as to send security or maintenance advisories, respond to and/or follow-up on your requests, inquiries, issues or feedback.

   \
   **Analytics**\
   \
   We use personal information to conduct research and analytics, including to improve our services; to understand how you interact with our Protocol.

   \
   **Security and Fraud Prevention**

   \
   We use personal information to detect, investigate, prevent, and take action against potential malicious, deceptive, fraudulent, or illegal activity, including attempts to manipulate or violate our policies, procedures, and terms and conditions, security incidents, and harm to the rights or property of Blueberry and our users, employees, or others.

   \
   **Legal Obligations**\
   \
   We use personal information to comply with our legal or regulatory obligations, to establish or exercise our rights, and to defend against a legal claim.

   \
   **Core Business Functions**\
   \
   We use personal information to support core business functions, including to maintain records related to business process management; loss and fraud prevention, and to collect amounts owing to us; and to provide and maintain the functionality of our Protocol, including identifying and repairing errors or problems.

6. ## How We Share Personal Information

   \
   We disclose personal information only to the third-parties as indicated below, in addition to any specified disclosures described elsewhere in this Policy:

   \
   **Business Affiliates**

   \
   We may share your personal information with our business affiliates, including any affiliated companies, subsidiaries or sister companies. Our business affiliates process personal information as our service providers, where necessary to provide the Protocol and services that you have requested, including to administer our Protocol, or in other circumstances with your consent or as permitted or required by law.

   \
   **Business Transfers**\
   \
   We may disclose personal information to a buyer or successor in the event of a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of Blueberry’s assets, whether as a going concern or as part of bankruptcy, liquidation, receivership, or similar proceeding in which personal information held by Blueberry are among the assets to be transferred.

   \
   **Law Enforcement and Legal Request**

   \
   We may disclose personal information to comply with applicable legal and our regulatory monitoring and reporting obligations (which may include laws outside your country of residence), to respond to requests from public and government authorities (which may include authorities outside your country of residence), to cooperate with law enforcement, or for other legal reasons.

   \
   **Enforcement of Legal Rights**

   \
   We may disclose personal information to the extent they are necessary to enforce or protect our rights, privacy, safety or property, and/or that of our affiliates, you or others, including enforcing our Terms of Use and any other agreements (such as for billing and collection purposes and fraud prevention).

7. ## Personal Information of Minors

   \
   We do not knowingly collect personal information from children under the age of eighteen (18) without authorization by a holder of parental responsibility. If you believe that we may have collected personal information from or about a child under the age of eighteen (18) without such authorization, please contact us at <info@blueberry.garden>.

8. ## How We Protect Personal Information

   \
   We take the protection of your personal information seriously. Blueberry employees who have access to your personal information are made aware of the importance of keeping it confidential. We care about the security of the information and use various administrative, and technological safeguards to preserve the integrity and security of all information collected through our Protocol.

   \
   However, no data security measures can guarantee complete security; we also depend on you to take common sense steps to ensure your personal information remains secure. Unfortunately, the transmission of information via the Internet is not completely secure. Although we do our best to protect your personal information, we cannot guarantee the security of your personal information transmitted to our Protocol. Any transmission of personal information is at your own risk. We are not responsible for circumvention of any privacy settings or security measures contained on our Protocol.

9. ## How Long We Retain Personal Information

   \
   In general, we retain your personal information for only as long as necessary to fulfill the purposes outlined in this Privacy Policy, unless a longer retention period is required or permitted by law. In the event that you make a verifiable request to delete your personal information and no exceptions apply, we will no longer retain your personal information. Please note that in many circumstances we are required to retain all, or a portion, of your personal information to comply with our legal obligations, resolve disputes, enforce our agreements, to protect against fraudulent, deceptive, or illegal activity, or for another one of our business purposes.\
   \
   The criteria used to determine our retention periods includes, without limitation:&#x20;

   * The length of time we have an ongoing relationship with you and provide the Protocol to you;
   * Whether there is a legal obligation to which we are subject (for example, certain laws require us to keep records of your transactions for a certain period of time before we can delete them); or
   * Whether retention is advisable in light of our legal position (such as in regard to applicable statutes of limitations, litigation or regulatory investigations).

10. ## Your Privacy Rights

    \
    Depending on where you reside or applicable law, you may exercise the rights described below. Please note that some of the rights may vary depending on your country, state, or province of residence.

    \
    **Accessing, Updating, Correcting, and Deleting Personal Information**\
    \
    You may have the right to request (1) access to and receive details about the personal information we maintain about you and how we process it; (2) updates your personal information or correct any inaccuracies; (3) a copy of your personal information that we have collected and processed and (4) that we delete your personal information. You may also have the right to withdraw your consent to our processing of your personal information. There may be limitations to these rights based on your specific circumstances and applicable law.

    \
    You can submit a privacy rights request by emailing <info@blueberry.garden>.

11. ## Information for California Residents

    \
    This section of our Privacy Policy is specifically for California residents and explains how we collect, use, and disclose personal information relating to California residents covered by the California Consumer Privacy Act (the “CCPA”). The CCPA defines “personal information” as any information that identifies, relates to, describes, is capable of being associated with, or could reasonably be linked, directly or indirectly, with a particular California resident or household.&#x20;

    \
    **Categories of Personal Information We Collect and Our Purposes for Collection and Use**

    \
    You can find a list of the categories of personal information that we collect in Section 2 above. For details regarding the sources form which we obtain personal information, please see Section 3 above. We collect and use personal information for the business or commercial purposes described in Section 5 above.

    \
    Blueberry does not collect any sensitive personal information for any individuals.&#x20;

    \
    **Categories of Personal Information Disclosed and Categories of Recipients**

    \
    We disclose the following categories of personal information for business or commercial purposes to the categories of recipients as described in Section 6 above.\
    \
    **Sale of Personal Information / Do Not Sell**\
    \
    Blueberry does not sell, trade, or rent out personal information for compensation that would constitute a sale under California law, nor have we done so in the preceding 12 months. In the event that Blueberry sells, trades, or rents out personal information that would constitute a sale, Blueberry will provide disclosures in this section of the Policy as well as the option to opt out of the sale of personal information using global privacy controls.

    \
    **Retention of Personal Information**\
    \
    Blueberry retains personal information for only as long as necessary to provide you with access to the Protocol and the services or until you have made a verifiable request to delete your personal information, unless a longer retention period is required or permitted by law. For additional information about retention of your personal information, please see section 9 above.

    \
    **Your California Rights**\
    \
    California residents are entitled to contact us to request information about whether we have disclosed personal information to third-parties for direct marketing purposes. Currently, Blueberry does not disclose personal information to third-parties for direct marketing purposes. Upon receipt of such a request by a California resident, we will either (1) respond with a confirmation that we have not disclosed any personal information to third-parties in the previous calendar year; or (2) if our practices have changed, we will provide the categories of personal information that has been shared in the past 12 months and categories of third-parties to whom such personal information was disclosed, whichever is relevant.

    \
    California residents have the right to:

    * Request disclosure of the categories and specific pieces of personal information that Blueberry has collected about you;
    * Request disclosure of the categories of third-party sources, if any, from which Blueberry has collected personal information about you;
    * Disclosure of the business or commercial purpose(s) for which your personal information has been collected by Blueberry;
    * Receive a list of the categories of third-parties with whom Blueberry has shared your personal information;
    * Request that Blueberry delete any personal information that it has collected from you (subject to exceptions);&#x20;
    * Request that Blueberry correct any inaccurate personal information held about you;&#x20;
    * Opt out of the sharing or disclosure of your personal information and sensitive personal information to third-parties; and
    * Not be discriminated against by Blueberry (e.g., charged different rates, provided different levels of service, denied goods or services, or suggested any of the preceding) for exercising any of the individual rights granted above.

    \
    To exercise any of your rights as a California resident, you can submit a request to <info@blueberry.garden>.\
    \
    Before complying with your request, we will need to verify that it is you that is making the request. To accomplish this, you may be requested to (1) confirm specific personal information that we already know about you; or (2) provide us with appropriate identification and documentation. California residents are limited to two requests for personal information per 12-month period. Only you or an authorized agent may make a verifiable data subject request related to your personal information. The verifiable data subject request must provide sufficient information and documentation to allow us to verify that you (or an authorized agent) are the person about whom we collected personal information. We will not provide you with personal information if we cannot verify your identity and/or authority to make the data subject request and confirm the personal information belongs to you or the represented individual. Making a verifiable data subject request does not require you to create an account with us. We use personal information provided in a verifiable data subject request solely to verify the requestor's identity or authority to make the request.

    \
    We will respond to a verifiable data subject request within 45 days of its receipt. If we require more time (up to 90 days), we will inform you of the reason and extension period. If you have an account with us, we will deliver our response to the email address for that account. If you do not have an account with us, we will deliver our response by US mail or electronically at the email address in your request, at your option. All disclosures we provide will only cover the 12-month period preceding the verifiable employee request's receipt. The response we provide will also explain the reasons we cannot comply with a request, if applicable.

    \
    We do not charge a fee to process or respond to your verifiable data subject request unless it is excessive, repetitive, or manifestly unfounded. If we determine that the request warrants a fee, we will tell you why we made that decision and provide you with a cost estimate before completing your request.

    <br>

12. ## Information for EU Residents

    This section of the Policy applies only to users who use the Protocol from a country that is a Member State of the European Union (“EU Users”) and supplements the information in the Privacy Policy.

    \
    Blueberry is the data controller for processing of personal information or personal data as defined under applicable data protection law. For purposes of this Policy, personal information and personal data are used synonymously.\
    \
    Under the General Data Protection Regulation (“GDPR”) (and subject to any relevant exceptions) you have the right to access, correct, change, delete, restrict, exercise your right to data portability, or object to the processing of personal information.

    \
    **Legal Basis for Processing**\
    \
    We process personal information for the purposes set out in this Privacy Policy, as described above. Our legal bases to process personal information includes processing that is:<br>

    * Necessary for the performance of the contract between you and Blueberry (for example, to provide you with the products and services you request and to identify and authenticate you so you may use the Protocol);&#x20;
    * Necessary to comply with legal requirements (for example, to comply with applicable accounting rules and to make mandatory disclosures to law enforcement);&#x20;
    * Necessary for our legitimate interests (for example, to manage our relationship with you and to improve the Websites and our products and services); and&#x20;
    * Based on consent by our customers (for example, to communicate with you about our products and services and provide you with marketing information), which may subsequently be withdrawn at any time without affecting the lawfulness of processing based on consent before its withdrawal.

    &#x20;\
    You are not required, as a necessity to enter into a contract, to provide us with personal information for processing as described above.

    \
    **Your EU Rights**\
    \
    As an individual residing in, or located in, the European Union or European Economic Area, you can exercise your GDPR rights. We may first request verification of your identity prior to facilitating the exercise of your rights.

    \
    If you wish to confirm that Blueberry is processing your personal information, or to have access to the personal information Blueberry may have about you, please contact us at <info@blueberry.garden>.

    \
    You may also request information about: the purpose of the processing; the categories of personal information concerned; who else outside Blueberry might have received the data from Blueberry; what the source of the information was (if you didn’t provide it directly to Blueberry); and how long it will be stored. You have a right to correct (rectify) the record of your personal information maintained by Blueberry if it is inaccurate. You may request that Blueberry erase that data or cease processing it, subject to certain exceptions. You may also request that we cease using your data for direct marketing purposes. In many countries, you have a right to lodge a complaint with the appropriate data protection authority if you have concerns about how Blueberry processes your personal information. When technically feasible, Blueberry will—at your request—provide your personal information to you or transmit it directly to another controller.\
    \
    Reasonable access to your personal information will be provided at no cost upon request. If access cannot be provided within a reasonable time frame, we will provide you with a date when the information will be provided. If for some reason access is denied, we will provide an explanation as to why access has been denied.

    \
    For questions or complaints concerning the processing of your personal information, you can contact us. Alternatively, if you are located in the European Union, you can also have recourse to the European Data Protection Supervisor or with your nation’s data protection authority.

13. ## Communicating With Us

    \
    If you have any questions or complaints related to our practices with respect to the collection, use, or disclosure of personal information, or if you would like to update your information, please contact us at <info@blueberry.garden>.<br>

14. ## Updates to the Privacy Policy

    It is our intent to post any changes we make to our Privacy Policy on this page, with a notice that it has been updated on our main homepage. If we make material changes to how we treat your personal information, we will notify you through a notice on the homepage. The date that this Privacy Policy was last revised is listed at the top of the page. You are responsible for visiting our website and this Privacy Policy to check for any changes.

##


# Risks

## General Risks

All DeFi protocols, including Blueberry, come with risks, which are important to understand before depositing significant amounts of crypto. Some of the main risks involved in using Blueberry are outlined here.

**Smart Contract and UI Risk**\
\
There is a risk that the smart contract or UI has a bug or exploit for unexpected behavior resulting in loss of funds. This risk is inherent to all smart contracts and relies upon the discipline of the development community, core contributors, and auditors.\
\
**Blockchain Risk**\
\
The Ethereum blockchain remains under development, which creates technological, uncertain, and security risks that Blueberry has no control over. The cost of transacting on the Ethereum blockchain is variable and may increase or decrease at any time causing an impact on any activities taking place on the Ethereum blockchain, which may result in losses, price fluctuations, or increased costs.\
\
**Oracle Risk**\
\
Blueberry relies on Chainlink for its main price feeds to power liquidations. There is a risk that these oracles report incorrect prices which can result in wrongful liquidations and loss of all funds.\
\
**Levered/Social Loss Risk**\
\
In the event of sharp price movements, traders with levered positions can lose more than their collateral value. In this event, these losses may be socialized across market participants.\
\
**Liquidation Risk**\
\
Blueberry offers both leveraged yield positions and borrow/lend. For leveraged yield positions, there is a risk of liquidation when a user's profit and losses are approaching the total collateral they have posted.\
\
**100% Utilization Risk**\
\
When an asset is fully utilized (100% of the supply is lent out), there will be no tokens left in the pool, which means withdrawals and borrows will fail for that asset. Users will have to wait until the utilization rate goes down, either through some users repaying their loans or depositing new funds before they can withdraw or borrow.\
\
A user is more likely to be affected by this if their deposit represents a large share of the pool, or if the asset has extremely high borrow demand.

## Risks as Stated By Hacken Audit

● The system highly relies on the Blueberry Money Market and ICHI Farm functionality which is out of the audit scope. The mentioned systems receive access to user funds.&#x20;

● The system uses prices received from Band Protocol, Chainlink, Uniswap (at previous blocks), and possibly other sources. The data providers may affect user position states. Check if the sources are stable and do not have disclosed vulnerabilities.&#x20;

● IchiVaultOracle highly relies on IchiVault. In case the IchiVault reserves could be manipulated, the resulting price may be affected and some positions become at risk of liquidation. It is recommended to check that the used IchiVault instances do not have disclosed vulnerabilities and could not be significantly affected by any third party.&#x20;

● The AggregatorOracle contract receives data from several sources and checks if the deviation of the price is within bounds. However, in case only one source responds with a price, that value is used. In case some of the sources are unstable or vulnerable, an attacker may manipulate the resulting price. It is recommended to ensure that the contract relies on stable data providers.&#x20;

● According to the documentation, only the CoreOracle contract should be used for providing prices to the target contracts (BlueberryBank, IchiSpell, etc.). In case another oracle is used, important price validations may be missed.&#x20;

● The oracles highly depend on the owner. The owner is able to manipulate token prices received by the project.&#x20;

● The Admin of BlueBerryBank may disable/enable actions for users at any time: lend, withdraw, repay, borrow.&#x20;

● The Admin of BlueBerryBank may de-whitelist previously whitelisted tokens and spells.&#x20;

● The system may be vulnerable to uncommon ERC20 tokens such as tokens with floating decimals (and 19+ decimals), fee-on-transfer tokens, or tokens with a non-failing approve function implemented (which in case of error returns false instead of reverting the transaction).&#x20;

● The IchiSpell contract allows the Admin to add strategies with custom vault addresses. The pool address received from the vault contract is able to drain any allowances to the IchiSpell contract.


