# Belugas Protocol Documentation

Belugas Protocol Documentation provides developers the detailed Belugas Protocol logic, Belugas.js library descriptions and security details.

{% content-ref url="/pages/Ee9iH8tuqBi6eLj4Xg2w" %}
[Getting Started](/getting-started)
{% endcontent-ref %}

{% content-ref url="/pages/pt2SiB8hniwuQ3FQrkxc" %}
[BTokens](/atokens)
{% endcontent-ref %}

{% content-ref url="/pages/thQFESRnhJvaiMxutkFR" %}
[Comptroller](/comptroller)
{% endcontent-ref %}

{% content-ref url="/pages/CxSuvMhvVtOICrYNndT8" %}
[Governance](/governance)
{% endcontent-ref %}

{% content-ref url="/pages/n6IuvjpaMDcUkDn8emGh" %}
[LP Staking](/lp-staking)
{% endcontent-ref %}

{% content-ref url="/pages/tN0E2oPwMxM8X25VrBhA" %}
[API](/api)
{% endcontent-ref %}

{% content-ref url="/pages/6WtcdX5wgYOAaRwqZY8p" %}
[Belugas.js](/aquarius.js)
{% endcontent-ref %}

{% content-ref url="/pages/o4T2qQ7AJR49lDtNMFHQ" %}
[Security](/security)
{% endcontent-ref %}

{% content-ref url="/pages/FnWrJV5EAkJ9GYw2o9to" %}
[Terms of Service](/terms-of-service)
{% endcontent-ref %}


# Getting Started

These docs are a comprehensive guide to the Belugas protocol, based on the Belugas Whitepaper (Mar 2024). The protocol is hosted on [Github](https://github.com/Belugas-Protocol) and maintained by the community.

Please join the #development room in the Belugas community [Telegram channel](https://t.me/officialbelugas); our team, and members of the community, look forward to helping you build an application on top of Belugas. Your questions help us improve, so please don't hesitate to ask if you can't find what you are looking for here.


# Networks

The Belugas Protocol is currently deployed on the following networks:

{% tabs %}
{% tab title="Sei DevNet" %}

| Contract      | Type   | ABI  | Address                                    |
| ------------- | ------ | ---- | ------------------------------------------ |
| bUSDT         | bToken | JSON | 0x83165E4e0B77ed5503f4B37C15C598852fb82c14 |
| bUSDC         | bToken | JSON | 0x00159a95C36717e583826D89e9631cc512e189Ac |
| bWBTC         | bToken | JSON | 0xB6a4716F2731CCd436Dbb5f27A534c3104710c76 |
| bWETH         | bToken | JSON | 0x32F472Ce830DDB441D92e807ef3FaB6a235816A8 |
| bSEI          | bToken | JSON | 0xD3a8c68a78c26117639Cf7A672a40528F094Ef2c |
| Comptroller   |        | JSON | 0xA514E7Cf87ea3AE6564d836bC8ACeEAb2Dbe4c9d |
| Governance    |        | JSON | 0x90C74908656c5387697E24d66E9Edd72aE178F17 |
| Timelock      |        | JSON | 0xF9b83f37BdAba59B68c6cF60A158f6Bcbc9bdb9B |
| {% endtab %}  |        |      |                                            |
| {% endtabs %} |        |      |                                            |


# Protocol Math

The Belugas protocol contracts use a system of exponential math, [Exponential.sol](https://github.com/Belugas-Protocol/belugas-protocol/blob/main/contracts/Exponential.sol), in order to represent fractional quantities with sufficient precision.

Most numbers are represented as a mantissa, an unsigned integer scaled by `1 * 10 ^ 18`, in order to perform basic math at a high level of precision.

{% content-ref url="/pages/6SlR0ihkrR4rYq4VrOs8" %}
[bToken and Underlying Decimals](/getting-started/protocol-math/atoken-and-underlying-decimals)
{% endcontent-ref %}

{% content-ref url="/pages/fV5PUK3lmLqhbVNxt8Ze" %}
[Interpreting Exchange Rates](/getting-started/protocol-math/interpreting-exchange-rates)
{% endcontent-ref %}

{% content-ref url="/pages/YnRXEggYfTGV4RDI03tC" %}
[Calculating Accrued Interest](/getting-started/protocol-math/calculating-accrued-interest)
{% endcontent-ref %}

{% content-ref url="/pages/kpc5gRjO6fvt8FKdK5Qh" %}
[Calculating the APY Using Rate Per Block](/getting-started/protocol-math/calculating-the-apy-using-rate-per-block)
{% endcontent-ref %}


# bToken and Underlying Decimals

Prices and exchange rates are scaled by the decimals unique to each asset; bTokens are ERC-20 tokens with 8 decimals, while their underlying tokens vary, and have a public member named *decimals*.

| bToken | bToken Decimals | Underlying | Underlying Decimals |
| ------ | --------------- | ---------- | ------------------- |
| bUSDT  | 8               | USDT       | 6                   |
| bUSDC  | 8               | USDC       | 6                   |
| bWBTC  | 8               | WBTC       | 8                   |
| bWETH  | 8               | WETH       | 18                  |


# Interpreting Exchange Rates

The bToken [Exchange Rate](/atokens/exchange-rate) is scaled by the difference in decimals between the bToken and the underlying asset.

```javascript
const oneBTokenInUnderlying = exchangeRateCurrent / (1 * 10 ^ (18 + underlyingDecimals - bTokenDecimals))
```

Here is an example of finding the value of 1 bWETH in WETH with Web3.js JavaScript.

```javascript
const bTokenDecimals = 8; // all bTokens have 8 decimal places
const underlying = new web3.eth.Contract(erc20Abi, ethAddress);
const bToken = new web3.eth.Contract(bTokenAbi, bEthAddress);
const underlyingDecimals = await underlying.methods.decimals().call();
const exchangeRateCurrent = await bToken.methods.exchangeRateCurrent().call();
const mantissa = 18 + parseInt(underlyingDecimals) - bTokenDecimals;
const oneBTokenInUnderlying = exchangeRateCurrent / Math.pow(10, mantissa);
console.log('1 bWETH can be redeemed for', oneBTokenInUnderlying, 'WETH');
```

There is no underlying contract for SEI, so to do this with bSEI, set `underlyingDecimals` to 18.

To find the number of underlying tokens that can be redeemed for bTokens, multiply the number of bTokens by the above value `oneBTokenInUnderlying`.

```javascript
const underlyingTokens = bTokenAmount * oneBTokenInUnderlying
```


# Calculating Accrued Interest

Interest rates for each market update on any block in which the ratio of borrowed assets to supplied assets in the market has changed. The amount interest rates are changed depends on the interest rate model smart contract implemented for the market, and the amount of change in the ratio of borrowed assets to supplied assets in the market.

Historical interest rates can be retrieved from the [MarketHistoryService API](/api/markethistoryservice).

Interest accrues to all suppliers and borrowers in a market when any Sei address interacts with the market’s bToken contract, calling one of these functions: mint, redeem, borrow, or repay. Successful execution of one of these functions triggers the accrueInterest method, which causes interest to be added to the underlying balance of every supplier and borrower in the market. Interest accrues for the current block, as well as each prior block in which the accrueInterest method was not triggered (no user interacted with the bToken contract). Interest belugas only during blocks in which the bToken contract has one of the aforementioned methods invoked.

Here is an example of supply interest accrual:

Alice supplies 1 ETH to the Belugas protocol. At the time of supply, the `supplyRatePerBlock` is 37893605 Wei, or 0.000000000037893605 ETH per block. No one interacts with the cEther contract for 3 Ethereum blocks. On the subsequent 4th block, Bob borrows some ETH. Alice’s underlying balance is now 1.000000000151574420 ETH (which is 37893605 Wei times 4 blocks, plus the original 1 ETH). Alice’s underlying ETH balance in subsequent blocks will have interest accrued based on the new value of 1.000000000151574420 ETH instead of the initial 1 ETH. Note that the `supplyRatePerBlock` value may change at any time.


# Calculating the APY Using Rate Per Block

The Annual Percentage Yield (APY) for supplying or borrowing in each market can be calculated using the value of `supplyRatePerBlock` (for supply APY) or `borrowRatePerBlock` (for borrow APY) in this formula:

```
Rate = bToken.supplyRatePerBlock(); // Integer
Rate = 37893566
ETH Mantissa = 1 * 10 ^ 18 (ETH has 18 decimal places)
Blocks Per Day = 20 * 60 * 24 (based on 20 blocks occurring every minute)
Days Per Year = 365

APY = ((((Rate / ETH Mantissa * Blocks Per Day + 1) ^ Days Per Year - 1)) - 1) * 100
```

Here is an example of calculating the supply and borrow APY with Web3.js JavaScript:

```javascript
const ethMantissa = 1e18;
const blocksPerDay = 20 * 60 * 24;
const daysPerYear = 365;

const bToken = new web3.eth.Contract(sEthAbi, sEthAddress);
const supplyRatePerBlock = await bToken.methods.supplyRatePerBlock().call();
const borrowRatePerBlock = await bToken.methods.borrowRatePerBlock().call();
const supplyApy = (((Math.pow((supplyRatePerBlock / ethMantissa * blocksPerDay) + 1, daysPerYear))) - 1) * 100;
const borrowApy = (((Math.pow((borrowRatePerBlock / ethMantissa * blocksPerDay) + 1, daysPerYear))) - 1) * 100;
console.log(`Supply APY for ETH ${supplyApy} %`);
console.log(`Borrow APY for ETH ${borrowApy} %`);
```


# Gas Costs

The gas usage of the protocol functions may fluctuate by market and user. External calls, such as to underlying ERC-20 tokens, may use an arbitrary amount of gas. Any calculations that involve checking [account liquidity](/comptroller/get-account-liquidity), have gas costs that increase with the number of [entered markets](/comptroller/enter-markets). Thus, while it can be difficult to provide any guarantees about costs, we provide the table below for guidance:

| Function         | Typical Gas Cost                     |
| ---------------- | ------------------------------------ |
| Mint             | < 150K, aUSDC < 300k                 |
| Redeem, Transfer | < 250K if borrowing, otherwise < 90K |
| Borrow           | < 300K                               |
| Repay Borrow     | < 90K                                |
| Liquidate Borrow | < 400K                               |


# BTokens

Each asset supported by the Belugas Protocol is integrated through a bToken contract, which is an [EIP-20](https://eips.ethereum.org/EIPS/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 interacting with the Belugas Protocol; when a user mints, redeems, borrows, repays a borrow, liquidates a borrow, or transfers bTokens, she will do so using the bToken contract.

There are currently two types of bTokens: BErc20 and CEther. Though both types expose the EIP-20 interface, BErc20 wraps an underlying ERC-20 asset, while CEther simply wraps Ether itself. As such, the core functions which involve transferring an asset into the protocol have slightly different interfaces depending on the type, each of which is shown below.

## How do bTokens earn interest?

Each [market](https://app.belugas.io/market) has its own Supply interest rate (APR). Interest isn't distributed; instead, simply by holding bTokens, you'll earn interest.

bTokens accumulates interest through their exchange rate — over time, each bToken becomes convertible into an increasing amount of it's underlying asset, even while the number of bTokens in your wallet stays the same.

## Can you walk me through an example?

Let’s say you supply 1,000 USDC to the Belugas protocol, when the exchange rate is 0.020070; you would receive 49,825.61 bUSDC (1,000/0.020070).

A few months later, you decide it’s time to withdraw your USDC from the protocol; the exchange rate is now 0.021591:

* Your 49,825.61 bUSDC is now equal to 1,075.78 USDC (49,825.61 \* 0.021591)
* You could withdraw 1,075.78 USDC, which would redeem all 49,825.61 bUSDC
* Or, you could withdraw a portion, such as your original 1,000 USDC, which would redeem 46,315.59 bUSDC (keeping 3,510.01 bUSDC in your wallet)

## How do I view my bTokens?

Each bToken is visible on [Seitrace](https://seitrace.com/), and you should be able to view them in the list of tokens associated with your address

bToken balances have been integrated into [Coinbase Wallet](https://itunes.apple.com/us/app/coinbase-wallet/id1278383455) and MetaMask; other wallets may add bToken support

## Can I transfer bTokens?

Yes, but exercise caution! By transferring bTokens, you’re transferring your balance of the underlying asset inside the Belugas protocol. If you send a bToken to your friend, your balance (viewable in the [Belugas Interface](https://app.belugas.io)) will decline, and your friend will see their balance increase.

A bToken transfer will fail if the account has [entered](/comptroller/enter-markets) that bToken market and the transfer would have put the account into a state of negative [liquidity](/comptroller/get-account-liquidity).


# Mint

The mint function transfers an asset into the protocol, which begins accumulating interest based on the current [Supply Rate](/atokens/supply-rate) for the asset. The user receives a quantity of bTokens equal to the underlying tokens supplied, divided by the current [Exchange Rate](/atokens/exchange-rate).

**BErc20**

```
function mint(uint mintAmount) returns (uint)
```

* `msg.sender`: The account which shall supply the asset, and own the minted bTokens.
* `mintAmount`: The amount of the asset to be supplied, in units of the underlying asset.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

Before supplying an asset, users must first [approve](https://eips.ethereum.org/EIPS/eip-20#approve) the bToken to access their token balance.

**CEther**

```
function mint() payable
```

* `msg.value` *\[payable]*: The amount of ether to be supplied, in wei.
* `msg.sender`: The account which shall supply the ether, and own the minted bTokens.
* `RETURN`: No return, reverts on error.

**Solidity**

```
Erc20 underlying = Erc20(0xToken...);     // get a handle for the underlying asset contract
BErc20 bToken = BErc20(0x3FDA...);        // get a handle for the corresponding bToken contract
underlying.approve(address(bToken), 100); // approve the transfer
assert(bToken.mint(100) == 0);            // mint the bTokens and assert there is no error
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
await bToken.methods.mint().send({from: myAccount, value: 50});
```


# Redeem

The redeem function converts a specified quantity of bTokens into the underlying asset, and returns them to the user. The amount of underlying tokens received is equal to the quantity of bTokens redeemed, multiplied by the current [Exchange Rate](/atokens/exchange-rate). The amount redeemed must be less than the user's [Account Liquidity](/comptroller/get-account-liquidity) and the market's available liquidity.

**BErc20 / CEther**

```
function redeem(uint redeemTokens) returns (uint)
```

* `msg.sender`: The account to which redeemed funds shall be transferred.
* `redeemTokens`: The number of bTokens to be redeemed.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

**Solidity**

```
CEther bToken = CEther(0x3FDB...);
require(bToken.redeem(7) == 0, "something went wrong");
```

**Web3 1.0**

```javascript
const bToken = BErc20.at(0x3FDA...);
bToken.methods.redeem(1).send({from: ...});
```


# Redeem Underlying

The redeem underlying function converts bTokens into a specified quantity of the underlying asset, and returns them to the user. The amount of bTokens redeemed is equal to the quantity of underlying tokens received, divided by the current [Exchange Rate](/atokens/exchange-rate). The amount redeemed must be less than the user's [Account Liquidity](https://github.com/aquariusloan/aquarius-docs/tree/294e07fcebce7997c93709b5b9f8bbdb7e8271af/atokens/comptroller/get-account-liquidity.md) and the market's available liquidity.

**BErc20 / CEther**

```
function redeemUnderlying(uint redeemAmount) returns (uint)
```

* `msg.sender`: The account to which redeemed funds shall be transferred.
* `redeemAmount`: The amount of underlying to be redeemed.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

**Solidity**

```
CEther bToken = CEther(0x3FDB...);
require(bToken.redeemUnderlying(50) == 0, "something went wrong");
```

**Web3 1.0**

```javascript
const bToken = BErc20.at(0x3FDA...);
bToken.methods.redeemUnderlying(10).send({from: ...});
```


# Borrow

The borrow function transfers an asset from the protocol to the user, and creates a borrow balance which begins accumulating interest based on the [Borrow Rate](/atokens/borrow-rate) for the asset. The amount borrowed must be less than the user's [Account Liquidity](/comptroller/get-account-liquidity) and the market's available liquidity.

To borrow Ether, the borrower must be 'payable' (solidity).

**BErc20 / CEther**

```
function borrow(uint borrowAmount) returns (uint)
```

* `msg.sender`: The account to which borrowed funds shall be transferred.
* `borrowAmount` : The amount of the underlying asset to be borrowed.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

**Solidity**

```
BErc20 bToken = BErc20(0x3FDA...);
require(bToken.borrow(100) == 0, "got collateral?");
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
await bToken.methods.borrow(50).send({from: 0xMyAccount});
```


# Repay Borrow

The repay function transfers an asset into the protocol, reducing the user's borrow balance.

**BErc20**

```
function repayBorrow(uint repayAmount) returns (uint)
```

* `msg.sender`: The account which borrowed the asset, and shall repay the borrow.
* `repayAmount`: The amount of the underlying borrowed asset to be repaid. A value of -1 (i.e. 2 ^ 256 - 1) can be used to repay the full amount.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

Before repaying an asset, users must first [approve](https://eips.ethereum.org/EIPS/eip-20#approve) the bToken to access their token balance.

**CEther**

```
function repayBorrow() payable
```

* `msg.value` *\[payable]*: The amount of ether to be repaid, in wei.
* `msg.sender`: The account which borrowed the asset, and shall repay the borrow.
* `RETURN`: No return, reverts on error.

**Solidity**

```
CEther bToken = CEther(0x3FDB...);
require(bToken.repayBorrow.value(100)() == 0, "transfer approved?");
```

**Web3 1.0**

```javascript
const bToken = BErc20.at(0x3FDA...);
bToken.methods.repayBorrow(10000).send({from: ...});
```


# Repay Borrow Behalf

The repay function transfers an asset into the protocol, reducing the target user's borrow balance.

**BErc20**

```
function repayBorrowBehalf(address borrower, uint repayAmount) returns (uint)
```

* `msg.sender`: The account which shall repay the borrow.
* `borrower`: The account which borrowed the asset to be repaid.
* `repayAmount`: The amount of the underlying borrowed asset to be repaid. A value of -1 (i.e. 2 ^ 256 - 1) can be used to repay the full amount.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

Before repaying an asset, users must first [approve](https://eips.ethereum.org/EIPS/eip-20#approve) the bToken to access their token balance.

**CEther**

```
function repayBorrowBehalf(address borrower) payable
```

* `msg.value` *\[payable]*: The amount of ether to be repaid, in wei.
* `msg.sender`: The account which shall repay the borrow.
* `borrower`: The account which borrowed the asset to be repaid.
* `RETURN`: No return, reverts on error.

**Solidity**

```
CEther bToken = CEther(0x3FDB...);
require(bToken.repayBorrowBehalf.value(100)(0xBorrower) == 0, "transfer approved?");
```

**Web3 1.0**

```javascript
const bToken = BErc20.at(0x3FDA...);
await bToken.methods.repayBorrowBehalf(0xBorrower, 10000).send({from: 0xPayer});
```


# Transfer

Transfer is an ERC-20 method that allows accounts to send tokens to other Ethereum addresses. A bToken transfer will fail if the account has [entered](/comptroller/enter-markets) that bToken market and the transfer would have put the account into a state of negative [liquidity](/comptroller/get-account-liquidity).

**BErc20 / CEther**

```
function transfer(address recipient, uint256 amount) returns (bool)
```

* `recipient`: The transfer recipient address.
* `amount`: The amount of bTokens to transfer.
* `RETURN`: Returns a boolean value indicating whether or not the operation succeeded.

**Solidity**

```
CEther bToken = CEther(0x3FDB...);
bToken.transfer(0xABCD..., 100000000000);
```

**Web3 1.0**

```javascript
const bToken = BErc20.at(0x3FDA...);
await bToken.methods.transfer(0xABCD..., 100000000000).send({from: 0xSender});
```


# Liquidate Borrow

A user who has negative account liquidity is subject to liquidation by other users of the protocol to return his/her account liquidity back to positive (i.e. above the collateral requirement). When a liquidation occurs, a liquidator may repay some or all of an outstanding borrow on behalf of a borrower and in return receive a discounted amount of collateral held by the borrower; this discount is defined as the liquidation incentive.

A liquidator may close up to a certain fixed percentage (i.e. close factor) of any individual outstanding borrow of the underwater account. Unlike in v1, liquidators must interact with each bToken contract in which they wish to repay a borrow and seize another asset as collateral. When collateral is seized, the liquidator is transferred bTokens, which they may redeem the same as if they had supplied the asset themselves. Users must approve each bToken contract before calling liquidate (i.e. on the borrowed asset which they are repaying), as they are transferring funds into the contract.

**BErc20**

```
function liquidateBorrow(address borrower, uint amount, address collateral) returns (uint)
```

* `msg.sender`: The account which shall liquidate the borrower by repaying their debt and seizing their collateral.
* `borrower`: The account with negative [account liquidity](/comptroller/get-account-liquidity) that shall be liquidated.
* `repayAmount`: The amount of the borrowed asset to be repaid and converted into collateral, specified in units of the underlying borrowed asset.
* `bTokenCollateral`: The address of the bToken currently held as collateral by a borrower, that the liquidator shall seize.
* `RETURN`: 0 on success, otherwise an [Error code](/atokens/error-codes)

Before supplying an asset, users must first [approve](https://eips.ethereum.org/EIPS/eip-20#approve) the bToken to access their token balance.

**CEther**

```
function liquidateBorrow(address borrower, address bTokenCollateral) payable
```

* `msg.value` *\[payable]*: The amount of ether to be repaid and converted into collateral, in wei.
* `msg.sender`: The account which shall liquidate the borrower by repaying their debt and seizing their collateral.
* `borrower`: The account with negative [account liquidity](/comptroller/get-account-liquidity) that shall be liquidated.
* `bTokenCollateral`: The address of the bToken currently held as collateral by a borrower, that the liquidator shall seize.
* `RETURN`: No return, reverts on error.

**Solidity**

```
CEther bToken = CEther(0x3FDB...);
BErc20 bTokenCollateral = BErc20(0x3FDA...);
require(bToken.liquidateBorrow.value(100)(0xBorrower, bTokenCollateral) == 0, "borrower underwater??");
```

**Web3 1.0**

```javascript
const bToken = BErc20.at(0x3FDA...);
const bTokenCollateral = CEther.at(0x3FDB...);
await bToken.methods.liquidateBorrow(0xBorrower, 33, bTokenCollateral).send({from: 0xLiquidator});
```


# Key Events

| Event                                                                                                                 | Description                                                              |
| --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `Mint(address minter, uint mintAmount, uint mintTokens)`                                                              | Emitted upon a successful [Mint](/atokens/mint).                         |
| `Redeem(address redeemer, uint redeemAmount, uint redeemTokens)`                                                      | Emitted upon a successful [Redeem](/atokens/redeem).                     |
| `Borrow(address borrower, uint borrowAmount, uint accountBorrows, uint totalBorrows)`                                 | Emitted upon a successful [Borrow](/atokens/borrow).                     |
| `RepayBorrow(address payer, address borrower, uint repayAmount, uint accountBorrows, uint totalBorrows)`              | Emitted upon a successful [Repay Borrow](/atokens/repay-borrow).         |
| `LiquidateBorrow(address liquidator, address borrower, uint repayAmount, address aTokenCollateral, uint seizeTokens)` | Emitted upon a successful [Liquidate Borrow](/atokens/liquidate-borrow). |


# Error Codes

| Code | Name                             | Description                                                                                                                                                                    |
| ---- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 0    | `NO_ERROR`                       | Not a failure.                                                                                                                                                                 |
| 1    | `UNAUTHORIZED`                   | The sender is not authorized to perform this action.                                                                                                                           |
| 2    | `BAD_INPUT`                      | An invalid argument was supplied by the caller.                                                                                                                                |
| 3    | `COMPTROLLER_REJECTION`          | The action would violate the comptroller policy.                                                                                                                               |
| 4    | `COMPTROLLER_CALCULATION_ERROR`  | An internal calculation has failed in the comptroller.                                                                                                                         |
| 5    | `INTEREST_RATE_MODEL_ERROR`      | The interest rate model returned an invalid value.                                                                                                                             |
| 6    | `INVALID_ACCOUNT_PAIR`           | The specified combination of accounts is invalid.                                                                                                                              |
| 7    | `INVALID_CLOSE_AMOUNT_REQUESTED` | The amount to liquidate is invalid.                                                                                                                                            |
| 8    | `INVALID_COLLATERAL_FACTOR`      | The collateral factor is invalid.                                                                                                                                              |
| 9    | `MATH_ERROR`                     | A math calculation error occurred.                                                                                                                                             |
| 10   | `MARKET_NOT_FRESH`               | Interest has not been properly accrued.                                                                                                                                        |
| 11   | `MARKET_NOT_LISTED`              | The market is not currently listed by its comptroller.                                                                                                                         |
| 12   | `TOKEN_INSUFFICIENT_ALLOWANCE`   | 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. |
| 13   | `TOKEN_INSUFFICIENT_BALANCE`     | Caller does not have sufficient balance in the ERC-20 contract to complete the desired action.                                                                                 |
| 14   | `TOKEN_INSUFFICIENT_CASH`        | The market does not have a sufficient cash balance to complete the transaction. You may attempt this transaction again later.                                                  |
| 15   | `TOKEN_TRANSFER_IN_FAILED`       | Failure in ERC-20 when transfering token into the market.                                                                                                                      |
| 16   | `TOKEN_TRANSFER_OUT_FAILED`      | Failure in ERC-20 when transfering token out of the market.                                                                                                                    |


# Failure Info

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


# Exchange Rate

Each bToken is convertible into an ever increasing quantity of the underlying asset, as interest accrues in the market. The exchange rate between a bToken and the underlying asset is equal to:

```
exchangeRate = (getCash() + totalBorrows() - totalReserves()) / totalSupply()
```

**BErc20 / CEther**

```
function exchangeRateCurrent() returns (uint)
```

* `RETURN`: The current exchange rate as an unsigned integer, scaled by 1e18.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint exchangeRateMantissa = bToken.exchangeRateCurrent();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const exchangeRate = (await bToken.methods.exchangeRateCurrent().call()) / 1e18;
```

Tip: note the use of call vs. send to invoke the function from off-chain without incurring gas costs.


# Get Cash

Cash is the amount of underlying balance owned by this bToken contract. One may query the total amount of cash currently available to this market.

**BErc20 / CEther**

```
function getCash() returns (uint)
```

* `RETURN`: The quantity of underlying asset owned by the contract.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint cash = bToken.getCash();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const cash = (await bToken.methods.getCash().call());
```


# Total Borrow

Total Borrows is the amount of underlying currently loaned out by the market, and the amount upon which interest is accumulated to suppliers of the market.

**BErc20 / CEther**

```
function totalBorrowsCurrent() returns (uint)
```

* `RETURN`: The total amount of borrowed underlying, with interest.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint borrows = bToken.totalBorrowsCurrent();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const borrows = (await bToken.methods.totalBorrowsCurrent().call());
```


# Borrow Balance

A user who borrows assets from the protocol is subject to accumulated interest based on the current [borrow rate](/atokens/borrow-rate). Interest is accumulated every block and integrations may use this function to obtain the current value of a user's borrow balance with interest.

**BErc20 / CEther**

```
function borrowBalanceCurrent(address account) returns (uint)
```

* `account`: The account which borrowed the assets.
* `RETURN`: The user's current borrow balance (with interest) in units of the underlying asset.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint borrows = bToken.borrowBalanceCurrent(msg.caller);
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const borrows = await bToken.methods.borrowBalanceCurrent(account).call();
```


# Borrow Rate

At any point in time one may query the contract to get the current borrow rate per block.

**BErc20 / CEther**

```
function borrowRatePerBlock() returns (uint)
```

* `RETURN`: The current borrow rate as an unsigned integer, scaled by 1e18.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint borrowRateMantissa = bToken.borrowRatePerBlock();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const borrowRate = (await bToken.methods.borrowRatePerBlock().call()) / 1e18;
```


# Total Supply

Total Supply is the number of tokens currently in circulation in this bToken market. It is part of the EIP-20 interface of the bToken contract.

**BErc20 / CEther**

```
function totalSupply() returns (uint)
```

* `RETURN`: The total number of tokens in circulation for the market.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint tokens = bToken.totalSupply();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const tokens = (await bToken.methods.totalSupply().call());
```


# Underlying Balance

The user's underlying balance, representing their assets in the protocol, is equal to the user's bToken balance multiplied by the [Exchange Rate](/atokens/exchange-rate).

**BErc20 / CEther**

```
function balanceOfUnderlying(address account) returns (uint)
```

* `account`: The account to get the underlying balance of.
* `RETURN`: The amount of underlying currently owned by the account.

**Solidity**

<pre><code><strong>BErc20 bToken = BToken(0x3FDA...);
</strong>uint tokens = bToken.balanceOfUnderlying(msg.caller);
</code></pre>

**Web3 1.0**

```
const bToken = CEther.at(0x3FDB...);
const tokens = await bToken.methods.balanceOfUnderlying(account).call();
```


# Supply Rate

At any point in time one may query the contract to get the current supply rate per block. The supply rate is derived from the [borrow rate](/atokens/borrow-rate), [reserve factor](/atokens/reserve-factor) and the amount of [total borrows](/atokens/total-borrow).

**BErc20 / CEther**

```
function supplyRatePerBlock() returns (uint)
```

* `RETURN`: The current supply rate as an unsigned integer, scaled by 1e18.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint supplyRateMantissa = bToken.supplyRatePerBlock();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const supplyRate = (await bToken.methods.supplyRatePerBlock().call()) / 1e18;
```


# Total Reserves

Reserves are an accounting entry in each bToken contract that represents a portion of historical interest set aside as [cash](/atokens/get-cash) which can be withdrawn or transferred through the protocol's governance. A small portion of borrower interest accrues into the protocol, determined by the [reserve factor](/atokens/reserve-factor).

**BErc20 / CEther**

```
function totalReserves() returns (uint)
```

* `RETURN`: The total amount of reserves held in the market.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint reserves = bToken.totalReserves();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const reserves = (await bToken.methods.totalReserves().call());
```


# Reserve Factor

The reserve factor defines the portion of borrower interest that is converted into [reserves](/atokens/total-reserves).

**BErc20 / CEther**

```
function reserveFactorMantissa() returns (uint)
```

* `RETURN`: The current reserve factor as an unsigned integer, scaled by 1e18.

**Solidity**

```
BErc20 bToken = BToken(0x3FDA...);
uint reserveFactorMantissa = bToken.reserveFactorMantissa();
```

**Web3 1.0**

```javascript
const bToken = CEther.at(0x3FDB...);
const reserveFactor = (await bToken.methods.reserveFactorMantissa().call()) / 1e18;
```


# Comptroller

The Comptroller is the risk management layer of the Belugas protocol; it determines how much collateral a user is required to maintain, and whether (and by how much) a user can be liquidated. Each time a user interacts with a bToken, the Comptroller is asked to approve or deny the transaction.

The Comptroller maps user balances to prices (via the Price Oracle) to risk weights (called [Collateral Factors](/comptroller/collateral-factor)) to make its determinations. Users explicitly list which assets they would like included in their risk scoring, by calling [Enter Markets](/comptroller/enter-markets) and [Exit Market](/comptroller/exit-market).

## Architecture

The Comptroller is implemented as an upgradeable proxy. The Unitroller proxies all logic to the Comptroller implementation, but storage values are set on the Unitroller. To call Comptroller functions, use the Comptroller ABI on the Unitroller address.


# Enter Markets

Enter into a list of markets - it is not an error to enter the same market more than once. In order to supply collateral or borrow in a market, it must be entered first.

**Comptroller**

```
function enterMarkets(address[] calldata bTokens) returns (uint[] memory)
```

* `msg.sender`: The account which shall enter the given markets.
* `bTokens`: The addresses of the bToken markets to enter.
* `RETURN`: For each market, returns an error code indicating whether or not it was entered. Each is 0 on success, otherwise an [Error code](/comptroller/error-codes).

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
BToken[] memory bTokens = new BToken[](2);
bTokens[0] = BErc20(0x3FDA...);
bTokens[1] = CEther(0x3FDB...);
uint[] memory errors = troll.enterMarkets(bTokens);
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const bTokens = [BErc20.at(0x3FDA...), CEther.at(0x3FDB...)];
const errors = await troll.methods.enterMarkets(bTokens).send({from: ...});
```


# Exit Market

Exit a market - it is not an error to exit a market which is not currently entered. Exited markets will not count towards account liquidity calculations.

**Comptroller**

```
function exitMarket(address bToken) returns (uint)
```

* `msg.sender`: The account which shall exit the given market.
* `bTokens`: The addresses of the bToken market to exit.
* `RETURN`: 0 on success, otherwise an [Error code](/comptroller/error-codes).

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
uint error = troll.exitMarket(BToken(0x3FDA...));
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const errors = await troll.methods.exitMarket(CEther.at(0x3FDB...)).send({from: ...});
```


# Get Assets In

Get the list of markets an account is currently entered into. In order to supply collateral or borrow in a market, it must be entered first. Entered markets count towards [account liquidity](/comptroller/get-account-liquidity) calculations.

**Comptroller**

```
function getAssetsIn(address account) view returns (address[] memory)
```

* `account`: The account whose list of entered markets shall be queried.
* `RETURN`: The address of each market which is currently entered into.

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
address[] memory markets = troll.getAssetsIn(0xMyAccount);
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const markets = await troll.methods.getAssetsIn(bTokens).call();
```


# Collateral Factor

A bToken's collateral factor can range from 0-90%, and represents the proportionate increase in liquidity (borrow limit) that an account receives by minting the bToken.

Generally, large or liquid assets have high collateral factors, while small or illiquid assets have low collateral factors. If an asset has a 0% collateral factor, it can't be used as collateral (or seized in liquidation), though it can still be borrowed.

Collateral factors can be increased (or decreased) through Belugas Governance, as market conditions change.

**Comptroller**

```
function markets(address bTokenAddress) view returns (bool, uint, bool)
```

* `bTokenAddress`: The address of the bToken to check if listed and get the collateral factor for.
* `RETURN`: Tuple of values (isListed, collateralFactorMantissa, isComped); isListed represents whether the comptroller recognizes this bToken; collateralFactorMantissa, scaled by 1e18, is multiplied by a supply balance to determine how much value can be borrowed. The isComped boolean indicates whether or not suppliers and borrowers are distributed BUL tokens.

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
(bool isListed, uint collateralFactorMantissa, bool isComped) = troll.markets(0x3FDA...);
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const result = await troll.methods.markets(0x3FDA...).call();
const {0: isListed, 1: collateralFactorMantissa, 2: isComped} = result;
```


# Get Account Liquidity

Account Liquidity represents the USD value borrowable by a user, before it reaches liquidation. Users with a shortfall (negative liquidity) are subject to liquidation, and can’t withdraw or borrow assets until Account Liquidity is positive again.

For each market the user has [entered](/comptroller/enter-markets) into, their supplied balance is multiplied by the market’s [collateral factor](/comptroller/collateral-factor), and summed; borrow balances are then subtracted, to equal Account Liquidity. Borrowing an asset reduces Account Liquidity for each USD borrowed; withdrawing an asset reduces Account Liquidity by the asset’s collateral factor times each USD withdrawn.

Because the Belugas Protocol exclusively uses unsigned integers, Account Liquidity returns either a surplus or shortfall.

**Comptroller**

```
function getAccountLiquidity(address account) view returns (uint, uint, uint)
```

* `account`: The account whose liquidity shall be calculated.
* `RETURN`: Tuple of values (error, liquidity, shortfall). The error shall be 0 on success, otherwise an [error code](/comptroller/error-codes). A non-zero liquidity value indicates the account has available [account liquidity](/comptroller/get-account-liquidity). A non-zero shortfall value indicates the account is currently below his/her collateral requirement and is subject to liquidation. At most one of liquidity or shortfall shall be non-zero.

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
(uint error, uint liquidity, uint shortfall) = troll.getAccountLiquidity(msg.caller);
require(error == 0, "join the Discord");
require(shortfall == 0, "account underwater");
require(liquidity > 0, "account has excess collateral");
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const result = await troll.methods.getAccountLiquidity(0xBorrower).call();
const {0: error, 1: liquidity, 2: shortfall} = result;
```


# Close Factor

The percent, ranging from 0% to 100%, of a liquidatable account's borrow that can be repaid in a single liquidate transaction. If a user has multiple borrowed assets, the closeFactor applies to any single borrowed asset, not the aggregated value of a user’s outstanding borrowing.

**Comptroller**

```
function closeFactorMantissa() view returns (uint)
```

* `RETURN`: The closeFactor, scaled by 1e18, is multiplied by an outstanding borrow balance to determine how much could be closed.

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
uint closeFactor = troll.closeFactorMantissa();
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const closeFactor = await troll.methods.closeFactoreMantissa().call();
```


# Liquidation Incentive

The additional collateral given to liquidators as an incentive to perform liquidation of underwater accounts. For example, if the liquidation incentive is 1.1, liquidators receive an extra 10% of the borrowers collateral for every unit they close.

**Comptroller**

```
function liquidationIncentiveMantissa() view returns (uint)
```

* `RETURN`: The liquidationIncentive, scaled by 1e18, is multiplied by the closed borrow amount from the liquidator to determine how much collateral can be seized.

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
uint closeFactor = troll.liquidationIncentiveMantissa();
```

**Web3 1.0**

```javascript
const troll = Comptroller.at(0xABCD...);
const closeFactor = await troll.methods.liquidationIncentiveMantissa().call();
```


# Key Events

| Event                                           | Description                                                           |
| ----------------------------------------------- | --------------------------------------------------------------------- |
| `MarketEntered(BToken bToken, address account)` | Emitted upon a successful [Enter Market](/comptroller/enter-markets). |
| `MarketExited(BToken bToken, address account)`  | Emitted upon a successful [Exit Market](/comptroller/exit-market).    |


# Error Codes

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


# Failure Info

| Code | Name                                          |
| ---- | --------------------------------------------- |
| 0    | `ACCEPT_ADMIN_PENDING_ADMIN_CHECK`            |
| 1    | `ACCEPT_PENDING_IMPLEMENTATION_ADDRESS_CHECK` |
| 2    | `EXIT_MARKET_BALANCE_OWED`                    |
| 3    | `EXIT_MARKET_REJECTION`                       |
| 4    | `SET_CLOSE_FACTOR_OWNER_CHECK`                |
| 5    | `SET_CLOSE_FACTOR_VALIDATION`                 |
| 6    | `SET_COLLATERAL_FACTOR_OWNER_CHECK`           |
| 7    | `SET_COLLATERAL_FACTOR_NO_EXISTS`             |
| 8    | `SET_COLLATERAL_FACTOR_VALIDATION`            |
| 9    | `SET_COLLATERAL_FACTOR_WITHOUT_PRICE`         |
| 10   | `SET_IMPLEMENTATION_OWNER_CHECK`              |
| 11   | `SET_LIQUIDATION_INCENTIVE_OWNER_CHECK`       |
| 12   | `SET_LIQUIDATION_INCENTIVE_VALIDATION`        |
| 13   | `SET_MAX_ASSETS_OWNER_CHECK`                  |
| 14   | `SET_PENDING_ADMIN_OWNER_CHECK`               |
| 15   | `SET_PENDING_IMPLEMENTATION_OWNER_CHECK`      |
| 16   | `SET_PRICE_ORACLE_OWNER_CHECK`                |
| 17   | `SUPPORT_MARKET_EXISTS`                       |
| 18   | `SUPPORT_MARKET_OWNER_CHECK`                  |


# BUL Distribution Speeds


# Claim BUL


# Market Metadata

The Comptroller contract has an array called `allMarkets` that contains the addresses of each bToken contract. Each address in the `allMarkets` array can be used to fetch a metadata struct in the Comptroller’s markets constant. See the [Comptroller Storage contract](https://github.com/Belugas-Protocol/belugas-protocol/blob/main/contracts/ComptrollerStorage.sol) for the Market struct definition.

**Comptroller**

```
BToken[] public allMarkets;
```

**Solidity**

```
Comptroller troll = Comptroller(0xABCD...);
BToken bTokens[] = troll.allMarkets();
```

**Web3 1.2.6**

```javascript
const comptroller = new web3.eth.Contract(comptrollerAbi, comptrollerAddress);
const bTokens = await comptroller.methods.allMarkets().call();
const bToken = bTokens[0]; // address of a bToken
```


# Governance

The Belugas protocol is governed and upgraded by BUL token-holders, using three distinct components; the BUL token, governance module (Governor Bravo), and Timelock. Together, these contracts allow the community to propose, vote, and implement changes through the administrative functions of a bToken or the Comptroller. Proposals can include changes like adjusting an interest rate model, to adding support for a new asset.

Any address with more than 10,000,000 BUL delegated to it may propose governance actions, which are executable code. When a proposal is created, the community can submit their votes during a 3 day voting period. If a majority, and at least 20,000,000 votes are cast for the proposal, it is queued in the Timelock, and can be implemented after 2 days.

## BUL

BUL is an [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) token that allows the owner to delegate voting rights to any address, including their own address. Changes to the owner’s token balance automatically adjust the voting rights of the delegate.


# Delegate

Delegate votes from the sender to the delegatee. Users can delegate to 1 address at a time, and the number of votes added to the delegatee’s vote count is equivalent to the balance of BUL in the user’s account. Votes are delegated from the current block and onward, until the sender delegates again, or transfers their BUL.

**BUL**

```
function delegate(address delegatee)
```

* `delegatee`: The address in which the sender wishes to delegate their votes to.
* `msg.sender`: The address of the BUL token holder that is attempting to delegate their votes.
* `RETURN`: No return, reverts on error.

**Solidity**

```
BUL bul = BUL(0x123...); // contract address
bul.delegate(delegateeAddress);
```

**Web3 1.2.6**

```javascript
const tx = await bul.methods.delegate(delegateeAddress).send({ from: sender });
```


# Delegate By Signature

Delegate votes from the signatory to the delegatee. This method has the same purpose as Delegate but it instead enables offline signatures to participate in Belugas governance vote delegation. For more details on how to create an offline signature, review [EIP-712](https://eips.ethereum.org/EIPS/eip-712).

**BUL**

```
function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s)
```

* `delegatee`: The address in which the sender wishes to delegate their votes to.
* `nonce`: The contract state required to match the signature. This can be retrieved from the contract’s public nonces mapping.
* `expiry`: The time at which to expire the signature. A block timestamp as seconds since the unix epoch (uint).
* `v`: The recovery byte of the signature.
* `r`: Half of the ECDSA signature pair.
* `s`: Half of the ECDSA signature pair.
* `RETURN`: No return, reverts on error.

**Solidity**

```
BUL bul = BUL(0x123...); // contract address
bul.delegateBySig(delegateeAddress, nonce, expiry, v, r, s);
```

**Web3 1.2.6**

```javascript
const tx = await bul.methods.delegateBySig(delegateeAddress, nonce, expiry, v, r, s).send({});
```


# Get Current Votes

Gets the balance of votes for an account as of the current block.

**BUL**

```
function getCurrentVotes(address account) returns (uint96)
```

* `account`: Address of the account in which to retrieve the number of votes.
* `RETURN`: The number of votes (integer).

**Solidity**

```
BUL bul = BUL(0x123...); // contract address
uint votes = bul.getCurrentVotes(0xabc...);
```

**Web3 1.2.6**

```javascript
const account = '0x123...'; // contract address
const votes = await bul.methods.getCurrentVotes(account).call();
```


# Get Prior Votes

Gets the prior number of votes for an account at a specific block number. The block number passed must be a finalized block or the function will revert.

**BUL**

```
function getPriorVotes(address account, uint blockNumber) returns (uint96)
```

* `account`: Address of the account in which to retrieve the prior number of votes.
* `blockNumber`: The block number at which to retrieve the prior number of votes.
* `RETURN`: The number of prior votes.

**Solidity**

```
BUL bul = BUL(0x123...); // contract address
uint priorVotes = bul.getPriorVotes(account, blockNumber);
```

**Web3 1.2.6**

```javascript
const priorVotes = await bul.methods.getPriocrVotes(account, blockNumber).call();
```


# Key Events

| Event                                                                                                                                                                      | Description                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate)`                                                                     | An event thats emitted when an account changes its [delegate](/governance/delegate).                               |
| `DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance)`                                                                                    | An event thats emitted when a delegate account's vote balance changes.                                             |
| `ProposalCreated(uint id, address proposer, address[] targets, uint[] values, string[] signatures, bytes[] calldatas, uint startBlock, uint endBlock, string description)` | An event emitted when a new [proposal](/governance/propose) is created.                                            |
| `VoteCast(address voter, uint proposalId, bool support, uint votes)`                                                                                                       | An event emitted when a [vote has been cast](/governance/cast-vote) on a proposal.                                 |
| `ProposalCanceled(uint id)`                                                                                                                                                | An event emitted when a proposal has been [canceled](/governance/cancel).                                          |
| `ProposalQueued(uint id, uint eta)`                                                                                                                                        | An event emitted when a proposal has been [queued](/governance/queue) in the [Timelock](/governance/timelock).     |
| `ProposalExecuted(uint id)`                                                                                                                                                | An event emitted when a proposal has been [executed](/governance/execute) in the [Timelock](/governance/timelock). |


# Governor Bravo

Governor Bravo is the governance module of the protocol; it allows addresses with more than 10,000,000 BUL to propose changes to the protocol. Addresses that held voting weight, at the start of the proposal, invoked through the getpriorvotes function, can submit their votes during a 3 day voting period. If a majority, and at least 20,000,000 votes are cast for the proposal, it is queued in the Timelock, and can be implemented after 2 days.


# Quorum Votes

The required minimum number of votes in support of a proposal for it to succeed.

**Governor Bravo**

```
function quorumVotes() public pure returns (uint)
```

* `RETURN`: The minimum number of votes required for a proposal to succeed.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint quorum = gov.quorumVotes();
```

**Web3 1.2.6**

```javascript
const quorum = await gov.methods.quorumVotes().call();
```


# Proposal Threshold

The minimum number of votes required for an account to create a proposal.

**Governor Bravo**

```
function proposalThreshold() returns (uint)
```

* `RETURN`: The minimum number of votes required for an account to create a proposal.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint threshold = gov.proposalThreshold();
```

**Web3 1.2.6**

```javascript
const threshold = await gov.methods.proposalThreshold().call();
```


# Proposal Max Operations

The maximum number of actions that can be included in a proposal. Actions are functions calls that will be made when a proposal succeeds and executes.

**Governor Bravo**

```
function proposalMaxOperations() returns (uint)
```

* `RETURN`: The maximum number of actions that can be included in a proposal.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint operations = gov.proposalMaxOperations();
```

**Web3 1.2.6**

```javascript
const operations = await gov.methods.proposalMaxOperations().call();
```


# Voting Delay

The number of SEI blocks to wait before voting on a proposal may begin. This value is added to the current block number when a proposal is created.

**Governor Bravo**

```
function votingDelay() returns (uint)
```

* `RETURN`: Number of blocks to wait before voting on a proposal may begin.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint blocks = gov.votingDelay();
```

**Web3 1.2.6**

```javascript
const blocks = await gov.methods.votingDelay().call();
```


# Voting Period

The duration of voting on a proposal, in SEI blocks.

**Governor Bravo**

```
function votingPeriod() returns (uint)
```

* `RETURN`: The duration of voting on a proposal, in Bravo blocks.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint blocks = gov.votingPeriod();
```

**Web3 1.2.6**

```javascript
const blocks = await gov.methods.votingPeriod().call();
```


# Propose

Create a Proposal to change the protocol. E.g., A proposal can set a bToken's interest rate model or risk parameters on the Comptroller.

Proposals will be voted on by delegated voters. If there is sufficient support before the voting period ends, the proposal shall be automatically enacted. Enacted proposals are queued and executed in the Belugas Timelock contract.

The sender must hold more BUL than the current proposal threshold (`proposalThreshold()`) as of the immediately previous block. If the threshold is 10,000,000 BUL, the sender must have been delegated more than 1% of all BUL in order to create a proposal. The proposal can have up to 10 actions (based on `proposalMaxOperations()`).

The proposer cannot create another proposal if they currently have a pending or active proposal. It is not possible to queue two identical actions in the same block (due to a restriction in the Timelock), therefore actions in a single proposal must be unique, and unique proposals that share an identical action must be queued in different blocks.

**Governor Bravo**

```
function propose(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) returns (uint)
```

* `targets`: The ordered list of target addresses for calls to be made during proposal execution. This array must be the same length as all other array parameters in this function.
* `values`: The ordered list of values (i.e. msg.value) to be passed to the calls made during proposal execution. This array must be the same length as all other array parameters in this function.
* `signatures`: The ordered list of function signatures to be passed during execution. This array must be the same length as all other array parameters in this function.
* `calldatas`: The ordered list of data to be passed to each individual function call during proposal execution. This array must be the same length as all other array parameters in this function.
* `description`: A human readable description of the proposal and the changes it will enact.
* `RETURN`: The ID of the newly created proposal.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint proposalId = gov.propose(targets, values, signatures, calldatas, description);
```

**Web3 1.2.6**

```javascript
const tx = gov.methods.propose(targets, values, signatures, calldatas, description).send({ from: sender });
```


# Queue

After a proposal has succeeded, any address can call the queue method to move the proposal into the Timelock queue. A proposal can only be queued if it has succeeded.

**Governor Bravo**

```
function queue(uint proposalId)
```

* `proposalId`: ID of a proposal that has succeeded.
* `RETURN`: No return, reverts on error.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
gov.queue(proposalId);
```

**Web3 1.2.6**

```javascript
const tx = gov.methods.queue(proposalId).send({ from: sender });
```


# Execute

After the Timelock delay period, any account may invoke the execute method to apply the changes from the proposal to the target contracts. This will invoke each of the actions described in the proposal.

This function is payable so the Timelock contract can invoke payable functions that were selected in the proposal. E.g., A proposal can add reserves to a market like bSEI, set a bToken's interest rate model, or set risk parameters on the Comptroller.

**Governor Bravo**

```
function execute(uint proposalId) payable returns (uint)
```

* `proposalId`: ID of a succeeded proposal to execute.
* `RETURN`: No return, reverts on error.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
gov.execute(proposalId).value(999).gas(999)();
```

**Web3 1.2.6**

```javascript
const tx = gov.methods.execute(proposalId).send({ from: sender, value: 1 });
```


# Cancel

Cancel a proposal that has not yet been executed. The Guardian is the only one who may execute this unless the proposer does not maintain the delegates required to create a proposal. If the proposer does not have more delegates than the proposal threshold, anyone can cancel the proposal.

**Governor Bravo**

```
function cancel(uint proposalId)
```

* `proposalId`: ID of a proposal to cancel. The proposal cannot have already been executed.
* `RETURN`: No return, reverts on error.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
gov.cancel(proposalId);
```

**Web3 1.2.6**

```javascript
const tx = gov.methods.cancel(proposalId).send({ from: sender });
```


# Get Actions

Gets the actions of a selected proposal. Pass a proposal ID and get the targets, values, signatures and calldatas of that proposal.

**Governor Bravo**

```
function getActions(uint proposalId) returns (uint proposalId) public view returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas)
```

* `proposalId`: ID of a proposal in which to get its actions.
* `RETURN`: Reverts if the proposal ID is invalid. If successful, the following 4 references are returned. 1. Array of addresses of contracts the proposal calls. 2. Array of unsigned integers the proposal uses as values. 3. Array of strings of the proposal’s signatures. 4. Array of calldata bytes of the proposal.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
uint proposalId = 123;
(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) = gov.getActions(proposalId);
```

**Web3 1.2.6**

```javascript
const {0: targets, 1: values, 2: signatures, 3: calldatas} = gov.methods.getActions(proposalId).call();
```


# Get Receipt

Gets a proposal ballot receipt of the indicated voter.

**Governor Bravo**

```
function getReceipt(uint proposalId, address voter) returns (Receipt memory)
```

* `proposalId`: ID of the proposal in which to get a voter’s ballot receipt.
* `voter`: Address of the account of a proposal voter.
* `RETURN`: Reverts on error. If successful, returns a Receipt struct for the ballot of the voter address.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
Receipt ballot = gov.getReceipt(proposalId, voterAddress);
```

**Web3 1.2.6**

```javascript
const proposalId = 11;
const voterAddress = '0x123...';
const result = await gov.methods.getReceipt(proposalId, voterAddress).call();
const { hasVoted, support, votes } = result;
```


# State

Gets the proposal state for the specified proposal. The return value, `ProposalState` is an enumerated type defined in the Governor Bravo contract.

**Governor Bravo**

```
function state(uint proposalId) returns (ProposalState)
```

* `proposalId`: ID of a proposal in which to get its state.
* `RETURN`: Enumerated type ProposalState. The types are Pending, Active, Canceled, Defeated, Succeeded, Queued, Expired, andExecuted.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
GovernorBravo.ProposalState state = gov.state(123);
```

**Web3 1.2.6**

```javascript
const proposalStates = ['Pending', 'Active', 'Canceled', 'Defeated', 'Succeeded', 'Queued', 'Expired', 'Executed'];
const proposalId = 123;
result = await gov.methods.state(proposalId).call();
const proposalState = proposalStates[result];
```


# Cast Vote

Cast a vote on a proposal. The account's voting weight is determined by the number of votes the account had delegated to it at the time the proposal state became active.

**Governor Bravo**

```
function castVote(uint proposalId, uint8 support)
```

* `proposalId`: ID of a proposal in which to cast a vote.
* `support`: An integer of 0 for against, 1 for in-favor, and 2 for abstain.
* `RETURN`: No return, reverts on error.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
gov.castVote(proposalId, 1);
```

**Web3 1.2.6**

```javascript
const tx = gov.methods.castVote(proposalId, 0).send({ from: sender });
```


# Cast Vote With Reason

Cast a vote on a proposal with a reason attached to the vote.

**Governor Bravo**

```
function castVoteWithReason(uint proposalId, uint8 support, string calldata reason)
```

* `proposalId`: ID of a proposal in which to cast a vote.
* `support`: An integer of 0 for against, 1 for in-favor, and 2 for abstain.
* `reason`: A string containing the voter's reason for their vote selection.
* `RETURN`: No return, reverts on error.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
gov.castVoteWithReason(proposalId, 2, "I think...");
```

**Web3 1.2.6**

```javascript
const tx = gov.methods.castVoteWithReason(proposalId, 2, "I think ...").send({ from: sender });;
```


# Cast Vote By Signature

Cast a vote on a proposal. The account's voting weight is determined by the number of votes the account had delegated at the time that proposal state became active. This method has the same purpose as Cast Vote but it instead enables offline signatures to participate in Belugas governance voting. For more details on how to create an offline signature, review [EIP-712](https://eips.ethereum.org/EIPS/eip-712).

**Governor Bravo**

```
function castVoteBySig(uint proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s)
```

* `proposalId`: ID of a proposal in which to cast a vote.
* `support`: An integer of 0 for against, 1 for in-favor, 2 for abstain.
* `v`: The recovery byte of the signature.
* `r`: Half of the ECDSA signature pair.
* `s`: Half of the ECDSA signature pair.
* `RETURN`: No return, reverts on error.

**Solidity**

```
GovernorBravo gov = GovernorBravo(0x123...); // contract address
gov.castVoteBySig(proposalId, 0, v, r, s);
```

**Web3 1.2.6**

```javascript
const tx = await gov.methods.castVoteBySig(proposalId, 0, v, r, s).send({});
```


# Timelock

Each bToken contract and the Comptroller contract allow the Timelock address to modify them. The Timelock contract can modify system parameters, logic, and contracts in a 'time-delayed, opt-out' upgrade pattern.

The Timelock has a hard-coded minimum delay of 2 days, which is the least amount of notice possible for a governance action. Each proposed action will be published at a minimum of 2 days in the future from the time of announcement. Major upgrades, such as changing the risk system, may have a 14 day delay.


# Pause Guardian

The Comptroller contract designates a Pause Guardian address capable of disabling protocol functionality. Used only in the event of an unforeseen vulnerability, the Pause Guardian has one and only one ability: to disable a select set of functions: Mint, Borrow, Transfer, and Liquidate. The Pause Guardian cannot unpause an action, nor can it ever prevent users from calling Redeem, or Repay Borrow to close positions and exit the protocol.

BUL token-holders designate the Pause Guardian address, which is currently held by Belugas and SeiDAO Team.


# LP Staking

Lock BUL LP, activate emissions!

In exchange for users enhancing the utility of Belugas Protocol by staking DragonSwap LP tokens, there are two primary rewards:

1. Activate $BUL emissions on deposits & borrows
2. Share in platform fees comprised of assets such as USDT, USDC and WETH

{% content-ref url="/pages/kUoOrYmkoSgnKzZEVwCP" %}
[LP Utility](/lp-staking/lp-utility)
{% endcontent-ref %}

{% content-ref url="/pages/wSWlERQ1sRWJcxaZMq5a" %}
[LP Staking Options](/lp-staking/lp-staking-options)
{% endcontent-ref %}

{% content-ref url="/pages/KAmuk4bTsLA4SsUo4jn8" %}
[Zapping LP](/lp-staking/zapping-lp)
{% endcontent-ref %}

{% content-ref url="/pages/9rujRQ8KG4AsSIwxZjeu" %}
[Maintaining Eligibility Status](/lp-staking/maintaining-eligibility-status)
{% endcontent-ref %}

{% content-ref url="/pages/UEZzbEzMoeUNNmWgi9MW" %}
[Broken mention](broken://pages/UEZzbEzMoeUNNmWgi9MW)
{% endcontent-ref %}


# LP Utility

{% hint style="info" %}
**To trigger** BUL **emissions on both deposits and borrows, you must lock at least 5% of your deposit's USD value in LP tokens.**
{% endhint %}

**Example 1** : If you deposit $1M USDC but have zero LP tokens locked, you will earn the basic APY but won't qualify for additional BUL emissions.

**Example 2 :** Deposit $1,000 USDC and lock $50 in LP tokens. Now you're eligible for BUL emissions, thanks to hitting that 5% threshold.

The requirement to lock liquidity tokens in LP form serves the Belugas Protocol money market in multiple ways:

1. Long-Term Participation : Locking LP tokens effectively commits users to a set period, increasing the likelihood that they'll maintain their deposited collateral.
2. BUL Emissions Activation : This commitment enables BUL emissions, rewarding those who are invested in the protocol's long-term vision.
3. Attracting New Users : The above dynamics make the Belugas Protocol money market mode appealing to potential liquidity providers, thereby stimulating both growth and development.

This strategic cycle not only sustains long-term liquidity but also catalyzes new inflows, making it a win-win for both individual users and the protocol at large.&#x20;


# LP Staking Options

cLiquidity pool is essential to many DeFi protocols. They allow users to provide liquidity (in the form of a pair, BUL & SEI, in exchange for a share of the pool's potential yield.)

LP tokens can be locked through the protocol to activate BUL emissions in the money market, receive protocol revenue.

Belugas Protocol currently offers a locked liquidity pool, **DragonSwap** (50% BUL & 50% SEI)


# Zapping LP

Automated 1-click liquidity formation

### What is Zapping?

Say you have SEI and want a position in the BUL-SEI pool. Well, it's a painful process to get into that position.

First, you must supply BUL & SEI in the appropriate proportions, which takes four transactions.

Zapping allows you to do in one click.

### Which assets can be Zapped?

We've expanded zapping capabilities to make your experience more convenient.

|      |
| ---- |
| USDT |
| USDC |
| BUL  |

#### How it Works

When you zap using one of these assets, the system will automatically sell it for SEI behind the scenes. This SEI is then  paired with BUL to create and lock the LP

This feature aims to provide you with greater flexibility in how you engate with Belugas Protocol's money market, giving you more ways to earn and lock LP.

### How to Zap via Belugas Protocol UI

First, connect you wallet to Belugas Protocol

Go to [LP Locking Page](https://app.belugas.io/stake).

<figure><img src="/files/xuaaA9EbG8DEeY1n0BOM" alt=""><figcaption><p>Zapping LP</p></figcaption></figure>

Or you zap LP from your vested BUL.

<figure><img src="/files/EKVx0ENKQMWxbQYxfz2b" alt=""><figcaption><p>Zap LP from vested BUL rewards</p></figcaption></figure>


# Maintaining Eligibility Status

{% hint style="info" %}
Remember : a minimum 5% ratio between your total deposit value and LP value must be maintained at all times to remain eligible!
{% endhint %}

As a risk asset, pricing volatility may swing users in and out of eligibility.

Example :&#x20;

1. John has $5 of LP and $100 of USDC deposits, which means John has met the 5% requirement (eligible for emissions)
2. The price of SEI declines 5%, thus taking the value of LP down below $5, and John is now below the 5% threshold required to earn emissions

{% hint style="info" %}
The protocol needs to check the eligibility state constantly to determine "who is in, who is out."
{% endhint %}

When you are eligible, banners at the top of each page will indicate "Emissions active."

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

If you fall out of eligibility, a "Emission inactive" notification is visible at the top of LP staking page and indicates the amount of LP required to regain eligibility. Click "Zap into LP" and follow the prompts to resume receiving $BUL emissions.

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

{% hint style="info" %}
If a money market participant wishes to increase the likelihood of remaining eligible for BUL emissions, consider **maintaining a buffer zone above the 5% threshold** to account for volatility.
{% endhint %}

Example:

Carl deposits $1,000 USDC in the money market and needs to lock at least $50 of LP to quality for BUL emissions.

Carl decides to lock $60 LP (10% above the threshold) to maintain eligibility status in the event of volatility.

Additionally, users can enable auto-compound & auto-relock from the manage Belugas Protocol page to increase the likelihood of retaining eligibility status.


# API

The Belugas API input and output formats are specified by [Protocol Buffers](https://developers.google.com/protocol-buffers/), known colloquially as protobufs. Unlike typical protobufs endpoints, the Belugas endpoints support JSON for input and output in addition to the protobufs binary format. To use JSON in both the input and the output, specify the headers "`Content-Type: application/json`" and "`Accept: application/json`" in the request.


# BTokenService


# GET: /btoken


# MarketHistoryService

The market history service retrieves historical information about a market. You can use this API to find out the values of interest rates at a certain point in time. Its especially useful for making charts and graphs of the time-series values.

```
// Returns 10 buckets of market data
fetch("https://api.belugas.io/api/market_history/graph?asset=0xf5dce57282a584d2746faf1593d3121fcac444dc&type=1day");
```

{% content-ref url="/pages/wJeuUwVxy0JoJVnP5gN3" %}
[GET: /market\_history/graph](/api/markethistoryservice/get-graph)
{% endcontent-ref %}


# GET: /market\_history/graph

**MarketHistoryGraphRequest**

The market history graph API returns information about a market between two timestamps. The requestor can choose the asset and number of buckets to return within the range. For example:

```
{
 "asset": "0xf5dce57282a584d2746faf1593d3121fcac444dc",
 "type": "1day",
 "offset": 0,
 "limit": 100
}
```

| Type   | Key      | Description                               |
| ------ | -------- | ----------------------------------------- |
| bytes  | `asset`  | The requested asset                       |
| string | `type`   | Graph log interval. `Enum["1day", "1hr"]` |
| uint32 | `offset` | Offset of pagination. `Default: 0`        |
| uint32 | `limit`  | Limit of pagination. `Max: 365`           |

**MarketHistoryGraphResponse**

The market history graph API response contains the rates for both suppliers and borrowers, as well as the sequence of total supply and borrows for the given market.

| Type                   | Key      | Description                                      |
| ---------------------- | -------- | ------------------------------------------------ |
| bool                   | `status` | If set false, indicates an error returning data. |
| MarketHistoryGraphData | `data`   | Market history graph data.                       |

**MarketHistoryGraphData**

| Type   | Key      | Description                   |
| ------ | -------- | ----------------------------- |
| uint32 | `limit`  | Limit of pagination           |
| uint32 | `total`  | Total count of data           |
| array  | `result` | Array of `MarketHistoryGraph` |

**MarketHistoryGraph**

| Type     | Key                | Description                   |
| -------- | ------------------ | ----------------------------- |
| uuid     | `id`               | History id                    |
| string   | `asset`            | Asset address                 |
| uint32   | `blockNumber`      | Block number of graph history |
| uint32   | `blockTimestamp`   | Unix block timestamp          |
| string   | `borrowApy`        | Borrow apy                    |
| string   | `supplyApy`        | Supply apy                    |
| string   | `borrowBelugasApy` | Borrow BUL apy                |
| string   | `supplyBelugasApy` | Supply BUL apy                |
| string   | `exchangeRate`     | Exchange rate                 |
| string   | `priceUSD`         | USD price of asset            |
| string   | `totalBorrow`      | Total borrow amount           |
| string   | `totalSupply`      | Total supply amount           |
| datetime | `createdAt`        | Created timestamp             |
| datetime | `updatedAt`        | Updated timestamp             |


# ProposalService

{% content-ref url="/pages/UTZCQKDlTz3GcjY5adGi" %}
[GET: /proposals](/api/proposal-service/get-proposals)
{% endcontent-ref %}

{% content-ref url="/pages/47djPvLvv8Hlfqlo5Hxd" %}
[GET: /proposals/:id](/api/proposal-service/get-proposals-by-id)
{% endcontent-ref %}

{% content-ref url="/pages/AZDOiCn9lNNsL09YIpkZ" %}
[GET: /proposals/statistics](/api/proposal-service/get-proposals-statistics)
{% endcontent-ref %}


# GET: /proposals

{% content-ref url="/pages/jPY6HzOhF0bnUgOFKrFa" %}
[GET: /governance/proposals](/api/governanceservice/get-governance-proposals)
{% endcontent-ref %}


# GET: /proposals/:id

Get proposal info by id.

**ProposalsResponse**‌

The API response contains the proposal data of the given proposal id.

| Type     | Key      | Description                                      |
| -------- | -------- | ------------------------------------------------ |
| bool     | `status` | If set false, indicates an error returning data. |
| Proposal | `data`   | Proposal data.                                   |

**Proposal**

| Type   | Key                 | Description                                                                                          |
| ------ | ------------------- | ---------------------------------------------------------------------------------------------------- |
| uint32 | `id`                | Unique id for looking up a proposal                                                                  |
| string | `description`       | A description of the actions the proposal will take if successful                                    |
| bytes  | `targets`           | The address to send the calldata to                                                                  |
| string | `values`            | The value of ETH to send with the transaction                                                        |
| string | `signatures`        | The function signature of the function to call at the target address                                 |
| string | `calldatas`         | The encoded argument data for the action                                                             |
| uint32 | `createdBlock`      | Created block number                                                                                 |
| string | `createdTxHash`     | Created transaction hash                                                                             |
| uint32 | `createdTimestamp`  | Created block timestamp                                                                              |
| uint32 | `startBlock`        | Started block number                                                                                 |
| string | `startTxHash`       | Started transaction hash                                                                             |
| uint32 | `startTimestamp`    | Started block timestamp                                                                              |
| uint32 | `cancelBlock`       | Canceled block number                                                                                |
| string | `cancelTxHash`      | Canceled transaction hash                                                                            |
| uint32 | `cancelTimestamp`   | Canceled block timestamp                                                                             |
| uint32 | `endBlock`          | End block number                                                                                     |
| string | `endTxHash`         | End transaction hash                                                                                 |
| uint32 | `endTimestamp`      | End block timestamp                                                                                  |
| uint32 | `queuedBlock`       | Queued block number                                                                                  |
| string | `queuedTxHash`      | Queued transaction hash                                                                              |
| uint32 | `queuedTimestamp`   | Queued block timestamp                                                                               |
| uint32 | `executedBlock`     | Executed block number                                                                                |
| string | `executedTxHash`    | Executed transaction hash                                                                            |
| uint32 | `executedTimestamp` | Executed block timestamp                                                                             |
| bytes  | `proposer`          | Proposer address                                                                                     |
| uint32 | `eta`               | eta                                                                                                  |
| string | `forVotes`          | The number of votes in support of the proposal                                                       |
| string | `againstVotes`      | The number of votes in opposition to this proposal                                                   |
| bool   | `canceled`          | Set true if canceled                                                                                 |
| bool   | executed            | Set true if executed                                                                                 |
| string | `state`             | State of `"Pending", "Active", "Canceled", "Defeated", "Succeeded", "Queued", "Expired", "Executed"` |
| uint32 | `voterCount`        | Voter count                                                                                          |
| uint32 | `blockNumber`       | Last calculated block number                                                                         |


# GET: /proposals/statistics

The proposals statistics API returns information about proposals count based on state.

**ProposalStatisticsRequest**

This API has no request parameters.

**ProposalStatisticsResponse**

The API response contains the proposal counts for states.

| Type                   | Key      | Description                                      |
| ---------------------- | -------- | ------------------------------------------------ |
| bool                   | `status` | If set false, indicates an error returning data. |
| ProposalStatisticsData | `data`   | Proposal statistics data.                        |

**ProposalStatisticsData**

| Type   | Key      | Description           |
| ------ | -------- | --------------------- |
| uint32 | `active` | Active proposal count |
| uint32 | `passed` | Passed proposal count |
| uint32 | `failed` | Failed proposal count |


# VoterService

The voter history service retrieves account and historical information about votes. You can use this API to find out the vote account or vote history.

```
// Retreives a list of vote accounts
fetch("https://api.belugas.io/api/voters/accounts");

// Retreives a detail information of vote account
fetch("https://api.belugas.io/api/voters/accounts/:address");

// Retreives a history of vote account
fetch("https://api.belugas.io/api/voters/history/:address");

// Retreives a vote data by proposal index
fetch("https://api.belugas.io/api/voters/:proposalId");
```


# GET: /voters/accounts

## VoterAccountsRequest

The voter accounts API returns information about all accounts participating in the vote.

| Type   | Key      | Description                        |
| ------ | -------- | ---------------------------------- |
| uint32 | `offset` | Offset of pagination. `Default: 0` |
| uint32 | `limit`  | Limit of pagination. `Max: 100`    |

**VoterAccountsResponse**

| Type              | Key      | Description                                      |
| ----------------- | -------- | ------------------------------------------------ |
| bool              | `status` | If set false, indicates an error returning data. |
| voterAccountsData | `data`   | Voter Account data.                              |

**VoterAccountsData**

| Type   | Key      | Description              |
| ------ | -------- | ------------------------ |
| uint32 | `offset` | Offset of pagination     |
| int32  | `limit`  | Limit of pagination      |
| uint32 | `total`  | Total count of data      |
| array  | `result` | Array of `VoterAccounts` |

**VoterAccounts**

| Type     | Key             | Description            |
| -------- | --------------- | ---------------------- |
| uuid     | `id`            | Voter account id       |
| string   | `address`       | Voter address          |
| float    | `voteWeight`    | Vote weight            |
| uint32   | `proposalVoted` | Proposal count to vote |
| string   | `votes`         | Votes                  |
| datetime | `createdAt`     | Created timestamp      |
| datetime | `updatedAt`     | Updated timestamp      |


# GET: /voters/accounts/:address

## VoterAccountsRequest

The request to the Voter accounts API can retrieve information about the certain account.

| Type   | Key       | Description                     |
| ------ | --------- | ------------------------------- |
| string | `address` | Address to retrieve. `required` |

**VoterResponse**

| Type      | Key      | Description                                      |
| --------- | -------- | ------------------------------------------------ |
| bool      | `status` | If set false, indicates an error returning data. |
| voterData | `data`   | Voter data.                                      |

**VoterData**

| Type   | Key             | Description                               |
| ------ | --------------- | ----------------------------------------- |
| uint32 | `delegateCount` | Delegate count of address                 |
| uint32 | `votes`         | Current votes of address                  |
| uint32 | `balance`       | BToken balance of address                 |
| array  | `delegates`     | Array of `Delegates`                      |
| array  | `txs`           | Array of `Transfer and vote transactions` |


# GET: /voters/history/:address

## VoterHistoryRequest

The request to the Voter History API can retrieve the vote history of the address.

| Type   | Key       | Description                     |
| ------ | --------- | ------------------------------- |
| string | `address` | Address to retrieve. `required` |

**VoterResponse**

| Type      | Key      | Description                                      |
| --------- | -------- | ------------------------------------------------ |
| bool      | `status` | If set false, indicates an error returning data. |
| voterData | `data`   | Voter data.                                      |

**VoterData**

| Type   | Key      | Description         |
| ------ | -------- | ------------------- |
| uint32 | `offset` | Limit of pagination |
| int32  | `limit`  | Limit of pagination |
| uint32 | `total`  | Total count of data |
| array  | `result` | Array of `Voters`   |

**Voters**

| Type     | Key              | Description         |
| -------- | ---------------- | ------------------- |
| uuid     | `id`             | Voter id            |
| string   | `address`        | Voter address       |
| int8     | `hasVoted`       | Vote status         |
| int8     | `support`        | Support status      |
| int20    | `proposalId`     | Vote proposal Index |
| datetime | `blockNumber`    | Block Number        |
| datetime | `blocktimestamp` | Block timestamp     |
| datetime | `createdAt`      | Created timestamp   |
| datetime | `updatedAt`      | Updated timestamp   |


# GET: /voters/:proposalId

## VoterProposalRequest

The request to the Voter Proposal API can specify a number of filters, such as which accounts to retrieve information about.

| Type   | Key      | Description                        |
| ------ | -------- | ---------------------------------- |
| uint32 | `offset` | Offset of pagination. `Default: 0` |
| uint32 | `limit`  | Limit of pagination. `Max: 100`    |
| string | `filter` | Filter for support                 |

**VoterProposalResponse**

| Type      | Key      | Description                                      |
| --------- | -------- | ------------------------------------------------ |
| bool      | `status` | If set false, indicates an error returning data. |
| voterData | `data`   | Voter data.                                      |

**VoterData**

| Type   | Key      | Description          |
| ------ | -------- | -------------------- |
| int32  | `limit`  | Limit of pagination  |
| uint32 | `total`  | Total count of data  |
| array  | `result` | Array of `Voters`    |
| string | sumVotes | The sum of all votes |

**Voters**

| Type     | Key              | Description         |
| -------- | ---------------- | ------------------- |
| uuid     | `id`             | Voter id            |
| string   | `address`        | Voter address       |
| int8     | `hasVoted`       | Vote status         |
| int8     | `support`        | Support status      |
| int20    | `proposalId`     | Vote proposal Index |
| datetime | `blockNumber`    | Block Number        |
| datetime | `blocktimestamp` | Block timestamp     |
| datetime | `createdAt`      | Created timestamp   |
| datetime | `updatedAt`      | Updated timestamp   |


# GovernanceService

Note: This service is experimental (alpha) and subject to change.

The Governance Service includes three endpoints to retrieve information about BUL accounts, governance proposals, and proposal vote receipts. You can use the APIs below to pull data about the Belugas governance system:

```
  // Retreives a list of governance proposals
  fetch("https://api.belugas.io/api/governance/proposals");

  // Retreives a list of governance proposal vote receipts
  fetch("https://api.belugas.io/api/governance/proposal_vote_receipts");

  // Retreives a list of BUL accounts
  fetch("https://api.belugas.io/api/governance/accounts");
```

{% content-ref url="/pages/jPY6HzOhF0bnUgOFKrFa" %}
[GET: /governance/proposals](/api/governanceservice/get-governance-proposals)
{% endcontent-ref %}

{% content-ref url="get-governance-proposal:vote:receipts.md" %}
<get-governance-proposal:vote:receipts.md>
{% endcontent-ref %}

{% content-ref url="/pages/8XpElQjrJdUcA8AzdEeM" %}
[GET: /governance/accounts](/api/governanceservice/get-governance-accounts)
{% endcontent-ref %}


# GET: /governance/belugas


# GET: /governance/proposals

**ProposalRequest**

The request to the Proposal API can specify a number of filters, such as which ids to retrieve information about or state of proposals.

| Type   | Key            | Description                                                                                                                               |
| ------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| uint32 | `proposal_ids` | List of ids to filter on, e.g.:?proposal\_ids\[]=23,25                                                                                    |
| string | `state`        | The state of the proposal to filter on, (e.g.: "Pending", "Active", "Canceled", "Defeated", "Succeeded", "Queued", "Expired", "Executed") |
| uint32 | `offset`       | Offset of pagination, default is 0                                                                                                        |
| uint32 | `limit`        | Number of proposals to include in the response, default is 100                                                                            |

**ProposalResponse**

The Proposal API returns a list of proposals that match the given filters on the request in descending order by proposal\_id.

| Type     | Key      | Description                                         |
| -------- | -------- | --------------------------------------------------- |
| bool     | `status` | If set false, indicates an error returning data.    |
| uint32   | `offset` | Offset of pagination                                |
| uint32   | `limit`  | Limit of pagination                                 |
| uint32   | `total`  | Total count of matching proposals                   |
| Proposal | `data`   | The list of proposals matching the requested filter |

**Proposal**

| Type   | Key                 | Description                                                                                          |
| ------ | ------------------- | ---------------------------------------------------------------------------------------------------- |
| uint32 | `id`                | Unique id for looking up a proposal                                                                  |
| string | `description`       | A description of the actions the proposal will take if successful                                    |
| bytes  | `targets`           | The address to send the calldata to                                                                  |
| string | `values`            | The value of ETH to send with the transaction                                                        |
| string | `signatures`        | The function signature of the function to call at the target address                                 |
| string | `calldatas`         | The encoded argument data for the action                                                             |
| uint32 | `createdBlock`      | Created block number                                                                                 |
| string | `createdTxHash`     | Created transaction hash                                                                             |
| uint32 | `createdTimestamp`  | Created block timestamp                                                                              |
| uint32 | `startBlock`        | Started block number                                                                                 |
| string | `startTxHash`       | Started transaction hash                                                                             |
| uint32 | `startTimestamp`    | Started block timestamp                                                                              |
| uint32 | `cancelBlock`       | Canceled block number                                                                                |
| string | `cancelTxHash`      | Canceled transaction hash                                                                            |
| uint32 | `cancelTimestamp`   | Canceled block timestamp                                                                             |
| uint32 | `endBlock`          | End block number                                                                                     |
| string | `endTxHash`         | End transaction hash                                                                                 |
| uint32 | `endTimestamp`      | End block timestamp                                                                                  |
| uint32 | `queuedBlock`       | Queued block number                                                                                  |
| string | `queuedTxHash`      | Queued transaction hash                                                                              |
| uint32 | `queuedTimestamp`   | Queued block timestamp                                                                               |
| uint32 | `executedBlock`     | Executed block number                                                                                |
| string | `executedTxHash`    | Executed transaction hash                                                                            |
| uint32 | `executedTimestamp` | Executed block timestamp                                                                             |
| bytes  | `proposer`          | Proposer address                                                                                     |
| uint32 | `eta`               | eta                                                                                                  |
| string | `forVotes`          | The number of votes in support of the proposal                                                       |
| string | `againstVotes`      | The number of votes in opposition to this proposal                                                   |
| bool   | `canceled`          | Set true if canceled                                                                                 |
| bool   | executed            | Set true if executed                                                                                 |
| string | `state`             | State of `"Pending", "Active", "Canceled", "Defeated", "Succeeded", "Queued", "Expired", "Executed"` |
| uint32 | `voterCount`        | Voter count                                                                                          |
| uint32 | `blockNumber`       | Last calculated block number                                                                         |


# GET: /governance/proposal\_vote\_receipts

**ProposalVoteReceiptRequest**

The request to the Proposal Vote Receipt API can specify a number of filters, such as which id to retrieve information about or which account.

| Type   | Key                  | Description                                                                                                                                                                                                       |
| ------ | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| uint32 | `proposal_id`        | A proposal id to filter on, e.g.?proposal\_id=23                                                                                                                                                                  |
| bytes  | `account`            | Filter for proposals receipts for the given account                                                                                                                                                               |
| bool   | `support`            | <p>Filter for proposals receipts by for votes withsupport=true</p><p>or against votes withsupport=false</p><p>. If support not specified, response will return paginated votes for both for and against votes</p> |
| bool   | `with_proposal_data` | <p>Will populate a proposal object on the vote receipt when request submitted withwith\_proposal\_data=true</p><p>, default is false</p>                                                                          |
| uint32 | `limit`              | Number of proposal vote receipts to include in the response, default is 100                                                                                                                                       |
| uint32 | `offset`             | Pagination number for proposal vote receipts in the response, default is 0                                                                                                                                        |

**ProposalVoteReceiptResponse**

The Proposal Vote Receipt API returns a list of proposal vote receipts that match the given filters on the request

| Type                    | Key      | Description                                                       |
| ----------------------- | -------- | ----------------------------------------------------------------- |
| bool                    | `status` | If set false, indicates an error returning data.                  |
| ProposalVoteReceiptData | `data`   | The list of proposal vote receipts matching the requested filter. |

**ProposalVoteReceiptData**

| Type                | Key      | Description                                                      |
| ------------------- | -------- | ---------------------------------------------------------------- |
| uint32              | `offset` | Offset of pagination                                             |
| uint32              | `limit`  | Limit of pagination                                              |
| uint32              | `total`  | Total count of matching data                                     |
| ProposalVoteReceipt | `result` | The list of proposal vote receipts matching the requested filter |

**ProposalVoteReceipt**

| Type   | Key              | Description                                    |
| ------ | ---------------- | ---------------------------------------------- |
| uuid   | `id`             | Unique id for looking up a voteReceipt         |
| string | `address`        | The address that describes the proposer        |
| bool   | `hasVoted`       | Flag that indicates voted                      |
| bool   | `support`        | Whether or not the voter supports the proposal |
| uint32 | `blockNumber`    | Voted block number                             |
| uint32 | `blockTimestamp` | Voted block timestamp                          |
| string | `votes`          | The number of votes cast by the voter          |


# GET: /governance/accounts

**GovernanceAccountRequest**

The request to the Governance Account API can specify a number of filters, such as which accounts to retrieve information about.

| Type   | Key            | Description                                                                                                           |
| ------ | -------------- | --------------------------------------------------------------------------------------------------------------------- |
| bytes  | `addresses`    | A list of accounts to filter on, e.g.:?addresses=0x...                                                                |
| string | `order_by`     | Filter for accounts by. E.g. “votes” \| “balance” \| “proposals\_created” (`reserved`)                                |
| bool   | `with_history` | Will populate a list of transaction history for the accounts when request is submittedwith\_history=true (`reserved`) |
| uint32 | `limit`        | Number of accounts to include in the response, default is 100                                                         |
| uint32 | `offset`       | Pagination offset for accounts in the response, default is 0                                                          |

**GovernanceAccountResponse**

The Governance Account API returns a list of accounts that match the given filters on the request

| Type               | Key      | Description                                                   |
| ------------------ | -------- | ------------------------------------------------------------- |
| bool               | `status` | If set false, indicates an error returning data.              |
| BelugasAccountData | `data`   | The list of governance accounts matching the requested filter |

Belugas**AccountData**

| **Type**       | Key      | Description                                                   |
| -------------- | -------- | ------------------------------------------------------------- |
| uint32         | `offset` | Offset of pagination                                          |
| uint32         | `limit`  | Limit of pagination                                           |
| uint32         | `total`  | Total count of pagination                                     |
| BelugasAccount | `result` | The list of governance accounts matching the requested filter |

Belugas**Account**

| Type     | Key              | Description                                                       |
| -------- | ---------------- | ----------------------------------------------------------------- |
| uuid     | `id`             | Unique id of BelugasAccount                                       |
| bytes    | `address`        | The address of the given BUL account                              |
| float    | `voteWeight`     | The percentage of voting weight of total BUL                      |
| uint32   | `proposalsVoted` | The number of proposals voted on in the Belugas Governance System |
| string   | `votes`          | Voting power                                                      |
| datetime | `createdAt`      | Created timestamp                                                 |
| datetime | `updatedAt`      | Updated timestamp                                                 |


# Shared Data Types

Custom data types that are shared between services.

**Pagination Summary**

Used for paginating results.

| Type   | Key      | Description                                                |
| ------ | -------- | ---------------------------------------------------------- |
| uint32 | `offset` | The current offset                                         |
| uint32 | `limit`  | The number of entries to show per page.                    |
| uint32 | `total`  | The number of items matching the request across all pages. |

**Precise**

For non-negative numbers only.

| Type   | Key     | Description                                                                                                                                        |
| ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| string | `value` | The full UNSIGNED number in string form. max value is 2^257 - 1,aka 231584178474632390847141970017375815706539969331281128078915168015826259279871 |


# Belugas.js

Belugas.js is a JavaScript SDK for Ethereum and the Belugas Protocol. It wraps around Ethers.js, which is its only dependency. It is designed for both the web browser and Node.js.

The SDK is currently in open beta. For bugs reports and feature requests, either create an issue in the GitHub repository or send a message in the Development channel of the Belguas Discord.


# Belugas Constructor

Creates an instance of the Belugas.js SDK.

* `[provider]` (Provider | string) Optional Ethereum network provider. Defaults to Ethers.js fallback mainnet provider.
* `[options]` (object) Optional provider options.
* `RETURN` (object) Returns an instance of the Belugas.js SDK.

```
var belugas = new Belugas(window.ethereum); // web browser

var belugas = new Belugas('http://127.0.0.1:8545'); // HTTP provider

var belugas = new Belugas(); // Uses Ethers.js fallback mainnet (for testing only)

var belugas = new Belugas('ropsten'); // Uses Ethers.js fallback (for testing only)

// Init with private key (server side)
var belugas = new Belugas('https://mainnet.infura.io/v3/_your_project_id_', {
  privateKey: '0x_your_private_key_', // preferably with environment variable
});

// Init with HD mnemonic (server side)
var belugas = new Belugas('mainnet' {
  mnemonic: 'clutch captain shoe...', // preferably with environment variable
});
```


# API Methods

These methods facilitate HTTP requests to the [Aquarius API](/api).

{% content-ref url="/pages/NQF4wtMwpqPx5c9WPfxZ" %}
[Account](/aquarius.js/api-methods/account)
{% endcontent-ref %}

{% content-ref url="/pages/cLHJvsQLMMM0xrJh0edr" %}
[bToken](/aquarius.js/api-methods/atoken)
{% endcontent-ref %}

{% content-ref url="/pages/WuA7WHNFCBzX1WusQV0m" %}
[Market History](/aquarius.js/api-methods/market-history)
{% endcontent-ref %}

{% content-ref url="/pages/Nqk9jug1tjwOol5Ki00m" %}
[Governance](/aquarius.js/api-methods/governance)
{% endcontent-ref %}


# Account

Makes a request to the AccountService API. The Account API retrieves information for various accounts which have interacted with the protocol. For more details, see the Belugas API documentation.

* `options` (object) A JavaScript object of API request parameters.
* `RETURN` (object) Returns the HTTP response body or error.

```
(async function() {
  const account = await Belugas.api.account({
    "addresses": "0xB61C5971d9c0472befceFfbE662555B78284c307",
    "network": "ropsten"
  });

  let usdtBorrowBalance = 0;
  if (Object.isExtensible(account) && account.accounts) {
    account.accounts.forEach((acc) => {
      acc.tokens.forEach((tok) => {
        if (tok.symbol === Belugas.bUSDT) {
          usdtBorrowBalance = +tok.borrow_balance_underlying.value;
        }
      });
    });
  }

  console.log('usdtBorrowBalance', usdtBorrowBalance);
})().catch(console.error);
```


# bToken

Makes a request to the BTokenService API. The bToken API retrieves information about bToken contract interaction. For more details, see the Belugas API documentation.

* `options` (object) A JavaScript object of API request parameters.
* `RETURN` (object) Returns the HTTP response body or error.

```
(async function() {
  const sEthData = await Belugas.api.bToken({
    "addresses": Belugas.util.getAddress(Belugas.bBNB)
  });

  console.log('sEthData', sEthData); // JavaScript Object
})().catch(console.error);
```


# Market History

Makes a request to the MarketHistoryService API. The market history service retrieves information about a market. For more details, see the Belugas API documentation.

* `options` (object) A JavaScript object of API request parameters.
* `RETURN` (object) Returns the HTTP response body or error.

```
(async function() {
  const sUsdcMarketData = await Belugas.api.marketHistory({
    "asset": Belugas.util.getAddress(Belugas.bUSDC),
    "min_block_timestamp": 1559339900,
    "max_block_timestamp": 1598320674,
    "num_buckets": 10,
  });

  console.log('sUsdcMarketData', sUsdcMarketData); // JavaScript Object
})().catch(console.error);
```




---

[Next Page](/llms-full.txt/1)

