> For the complete documentation index, see [llms.txt](https://v0.docs.hifi.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://v0.docs.hifi.finance/smart-contracts/balancesheet.md).

# BalanceSheet

## Introduction

The BalanceSheet is the global debt registry of Hifi. All users who borrow fyTokens have to first open a vault bespoke to that fyToken contract. All vaults are recorded in and managed via the BalanceSheet.

## Gas Costs

Gas usage is not deterministic due to requisite calls to third-party Erc20 tokens. We provide the table below for guidance only:

| Action              | Typical Gas Cost                 |
| ------------------- | -------------------------------- |
| Deposit Collateral  | <70K                             |
| Free Collateral     | <110K if partial, <40K otherwise |
| Lock Collateral     | <40K                             |
| Open Vault          | <50K                             |
| Withdraw Collateral | <40K                             |

## Storage Properties

### Fintroller

The unique Fintroller associated with this contract.

```javascript
FintrollerInterface public fintroller;
```

## Constant Functions <a href="#constant-functions" id="constant-functions"></a>

### Get Clutchable Collateral <a href="#getstream" id="getstream"></a>

Determines the amount of collateral that can be clutched when liquidating a borrow according to the formula:

$$
clutchedCollateral = \frac {repayAmount \* liquidationIncentive \* underlyingPriceUsd} {collateralPriceUsd}
$$

```javascript
function getClutchableCollateral(FyTokenInterface fyToken, uint256 repayAmount) external view returns (uint256)
```

* `fyToken`: The fyToken to make the query against.
* `repayAmount`: The amount of fyTokens to repay (must be non-zero).
* `RETURN`: The amount of clutchable collateral as uint256, specified in the collateral's decimal system.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
uint256 repayAmount = 10000000000000000000;
uint256 clutchableCollateral = balanceSheet.getClutchableCollateral(fyToken, repayAmount);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const repayAmount = "10000000000000000000";
const clutchableCollateral = await balanceSheet.getClutchableCollateral(fyToken, repayAmount);‌
```

### Get Current Collateralization Ratio <a href="#cancel-stream" id="cancel-stream"></a>

Determines the current collateralization ratio for the given borrower account.

```javascript
function getCurrentCollateralizationRatio(FyTokenInterface fyToken, address borrower) public view returns (uint256)
```

* `fyToken`: The fyToken to make the query against.
* `borrower`: The borrower account to make the query against.
* `RETURN`: A quotient if locked collateral is non-zero, otherwise zero.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
uint256 currentCollateralizationRatio = balanceSheet.getCurrentCollateralizationRatio(fyToken, borrower);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const currentCollateralizationRatio = await balanceSheet.getCurrentCollateralizationRatio(fyToken, borrower);‌
```

### Get Hypothetical Collateralization Ratio <a href="#cancel-stream" id="cancel-stream"></a>

Determines the hypothetical collateralization ratio for the given locked collateral and debt, at the current prices provided by the oracle according to the formula:

$$
collateralizationRatio = \frac {lockedCollateralValueUsd} {debtValueUsd}
$$

```javascript
function getHypotheticalCollateralizationRatio(FyTokenInterface fyToken, address borrower, uint256 lockedCollateral, uint256 debt) public view returns (uint256)
```

* `fyToken`: The fyToken to make the query against.
* `borrower`: The borrower account to make the query against.
* `lockedCollateral`: The hypothetical locked collateral.
* `debt`: The hypothetical debt.
* `RETURN`: The hypothetical collateralization ratio as a percentage mantissa if locked collateral is non-zero, otherwise zero.

{% hint style="warning" %}
Requirements

* The vault must be open.
* "debt" must be non-zero.
* The oracle prices must be non-zero.
  {% endhint %}

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
address lockedCollateral = 10000000000000000000;
address debt = 5000000000000000000;
uint256 hypotheticalCollateralizationRatio = balanceSheet.getHypotheticalCollateralizationRatio(fyToken, borrower, lockedCollateral, debt);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const lockedCollateral = "10000000000000000000";
const debt = "5000000000000000000";
const hypotheticalCollateralizationRatio = await balanceSheet.getHypotheticalCollateralizationRatio(fyToken, borrower, lockedCollateral, debt);
```

### Get Vault <a href="#cancel-stream" id="cancel-stream"></a>

Reads all the properties of a vault.

```javascript
function getVault(FyTokenInterface fyToken, address borrower) external view returns (uint256, uint256, uint256, bool)
```

* `fyToken` : The fyToken to make the query against.
* `borrower` : The borrower account to make the query against.
* `RETURN`: The vault with all its properties.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
(uint256 debt, uint256 freeCollateral, uint256 lockedCollateral, bool isOpen) = balanceSheet.getVault(fyToken, borrower);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const vault = await balanceSheet.getVault(fyToken, borrower);‌
```

### Get Vault Debt <a href="#cancel-stream" id="cancel-stream"></a>

Reads the debt held by the given account.

```javascript
function getVaultDebt(FyTokenInterface fyToken, address borrower) external view returns (uint256)
```

* `fyToken` : The fyToken to make the query against.
* `borrower` : The borrower account to make the query against.
* `RETURN`: The debt held by the borrower, as an uint256.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
uint256 vaultDebt = balanceSheet.getVaultDebt(fyToken, borrower);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const vaultDebt = await balanceSheet.getVaultDebt(fyToken, borrower);‌
```

### Get Vault Locked Collateral <a href="#cancel-stream" id="cancel-stream"></a>

Reads the amount of collateral that the given borrower account locked in the vault.

```javascript
function getVaultLockedCollateral(FyTokenInterface fyToken, address borrower) external view returns (uint256)
```

* `fyToken`: The fyToken to make the query against.
* `borrower`: The borrower account to make the query against.
* `RETURN`: The collateral locked in the vault by the borrower, as an uint256.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
uint256 vaultLockedCollateral = balanceSheet.getVaultLockedCollateral(fyToken, borrower);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const vaultLockedCollateral = await balanceSheet.getVaultLockedCollateral(fyToken, borrower);‌
```

### Is Account Underwater <a href="#cancel-stream" id="cancel-stream"></a>

Checks whether the borrower account can be liquidated or not.

```javascript
function isAccountUnderwater(FyTokenInterface fyToken, address borrower) external view returns (bool)
```

* `fyToken`: The fyToken to make the query against.
* `borrower`: The borrower account to make the query against.
* `RETURN`: true = is underwater, otherwise not.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
uint256 isAccountUnderwater = balanceSheet.isAccountUnderwater(fyToken, borrower);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const isAccountUnderwater = await balanceSheet.isAccountUnderwater(fyToken, borrower);‌
```

### Is Vault Open <a href="#cancel-stream" id="cancel-stream"></a>

Checks whether the borrower account has a vault opened for a particular fyToken.

```javascript
function isVaultOpen(FyTokenInterface fyToken, address borrower) external view returns (bool)
```

* `fyToken`: The fyToken to make the query against.
* `borrower`: The borrower account to make the query against.
* `RETURN`: true = is open, otherwise not.

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
address borrower = 0x1234;
uint256 isVaultOpen = balanceSheet.isVaultOpen(fyToken, borrower);
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const borrower = 0x1234;
const isVaultOpen = await balanceSheet.isVaultOpen(fyToken, borrower);‌
```

## Non-Constant Functions <a href="#non-constant-functions" id="non-constant-functions"></a>

### Clutch Collateral <a href="#getstream" id="getstream"></a>

Transfers the collateral from the borrower's vault to the liquidator account. Emits a "ClutchCollateral" event.

```javascript
function clutchCollateral(FyTokenInterface fyToken, address liquidator, address borrower, uint256 collateralAmount ) external returns (bool)
```

* `fyToken`: The address of the fyToken contract.
* `liquidator`: The account who repays the borrower's debt and receives the collateral.
* `borrower`: The account who fell underwater and is liquidated.
* `collateralAmount`: The amount of collateral to clutch, specified in the collateral's decimal system.
* `RETURN`: true = success, otherwise it reverts

{% hint style="warning" %}
Requirements:

* Can only be called by the fyToken contract.
* There must be enough collateral in the borrower's vault.
  {% endhint %}

{% hint style="info" %}
We didn't write code snippets for this function because it is not meant to be called directly. Only the fyToken contract is allowed to call "clutchCollateral".
{% endhint %}

### Deposit Collateral <a href="#getstream" id="getstream"></a>

Deposits collateral into the account's vault. Emits a "DepositCollateral" event.

```javascript
function depositCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external returns (bool)
```

* `fyToken` : The address of the fyToken contract.
* `collateralAmount` : The amount of collateral to deposit.
* `RETURN`: true = success, otherwise it reverts.

{% hint style="warning" %}
Requirements:

* The vault must be open.
* The amount to deposit cannot be zero.
* The Fintroller must allow this action to be performed.
* The caller must have allowed this contract to spend "collateralAmount" tokens.
  {% endhint %}

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheetInterface(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
uint256 collateralAmount = 10000000000000000000;
bool success = balanceSheet.depositCollateral(fyToken, collateralAmount);
require(success, "something went wrong");
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const collateralAmount = "10000000000000000000";
const depositCollateralTx = await balanceSheet.depositCollateral(fyToken, collateralAmount);
await depositCollateralTx.wait();
```

### Free Collateral <a href="#getstream" id="getstream"></a>

Frees a portion or all of the locked collateral. Emits a "FreeCollateral" event.

```javascript
function freeCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external returns (bool)
```

* `fyToken`: The address of the fyToken contract.
* `collateralAmount`: The amount of locked collateral to free.
* `RETURN`: true = success, otherwise it reverts.

{% hint style="warning" %}
Requirements:

* The vault must be open.
* The amount to free cannot be zero.
* There must be enough locked collateral.
* The borrower account cannot fall below the collateralization ratio.
  {% endhint %}

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheetInterface(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
uint256 collateralAmount = 10000000000000000000;
bool success = balanceSheet.freeCollateral(fyToken, collateralAmount);
require(success, "something went wrong");
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const collateralAmount = "10000000000000000000";
const freeCollateralTx = await balanceSheet.freeCollateral(fyToken, collateralAmount);
await freeCollateralTx.wait();
```

### Lock Collateral <a href="#getstream" id="getstream"></a>

Locks a portion or all of the free collateral to make it eligible for borrowing. Emits a "LockCollateral" event.

```javascript
function lockCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external returns (bool)
```

* `fyToken`: The address of the fyToken contract.
* `collateralAmount`: The amount of free collateral to lock.
* `RETURN`: true = success, otherwise it reverts.

{% hint style="warning" %}
Requirements:

* The vault must be open.
* The amount to lock cannot be zero.
* There must be enough free collateral.
  {% endhint %}

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheetInterface(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
uint256 collateralAmount = 10000000000000000000;
bool success = balanceSheet.lockCollateral(fyToken, collateralAmount);
require(success, "something went wrong");
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const collateralAmount = "10000000000000000000";
const lockCollateralTx = await balanceSheet.lockCollateral(fyToken, collateralAmount);
await lockCollateralTx.wait();
```

### Open Vault <a href="#getstream" id="getstream"></a>

Opens a Vault for the caller. Emits an "OpenVault" event.

```javascript
function openVault(FyTokenInterface fyToken) external returns (bool)
```

* `fyToken`: The address of the fyToken contract for which to open the vault.
* `RETURN`: true = success, otherwise it reverts.

{% hint style="warning" %}
Requirements:

* The vault cannot be already open.
* The fyToken must pass the inspection.
  {% endhint %}

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheetInterface(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
bool success = balanceSheet.openVault(fyToken);
require(success, "something went wrong");
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const openVaultTx = await balanceSheet.openVault(fyToken);
await openVaultTx.wait();
```

### Set Vault Debt <a href="#getstream" id="getstream"></a>

Updates the debt accrued by a particular borrower account. Emits a "SetVaultDebt" event.

```javascript
function setVaultDebt(FyTokenInterface fyToken, address borrower, uint256 newVaultDebt) external returns (bool)
```

* `fyToken`: The address of the fyToken contract.
* `borrower`: The borrower account for which to update the debt.
* `newVaultDebt`: The new debt to assign to the borrower account.
* `RETURN`: true = success, otherwise it reverts.

{% hint style="warning" %}
Requirements:

* Can only be called by the fyToken.
  {% endhint %}

{% hint style="info" %}
We didn't write code snippets for this function because it is not meant to be called directly. Only the fyToken contract is allowed to call "setVaultDebt".
{% endhint %}

### Withdraw Collateral <a href="#getstream" id="getstream"></a>

Withdraws a portion or all of the free collateral. Emits a "WithdrawCollateral" event.

```javascript
function withdrawCollateral(FyTokenInterface fyToken, uint256 collateralAmount) external returns (bool)
```

* `fyToken`: The address of the fyToken contract.
* `collateralAmount`: The amount of collateral to withdraw.
* `RETURN`: true = success, otherwise it reverts.

{% hint style="warning" %}
Requirements

* The vault must be open.
* The amount to withdraw cannot be zero.
* There must be enough free collateral in the vault.
  {% endhint %}

#### Solidity <a href="#solidity-5" id="solidity-5"></a>

```javascript
‌BalanceSheet balanceSheet = BalanceSheet(0xabcd...);
FyTokenInterface fyToken = FyTokenInterface(0xbcde...);
uint256 collateralAmount = 10000000000000000000;
bool success = balanceSheet.withdrawCollateral(fyToken, collateralAmount);
require(success, "something went wrong");
```

#### Ethers.js <a href="#ethers-js-5" id="ethers-js-5"></a>

```javascript
const balanceSheet = new ethers.Contract(0xabcd..., balanceSheetABI, signer);
const fyToken = new ethers.Contract(0xbcde..., fyTokenInterfaceABI, signer);
const collateralAmount = "10000000000000000000";
const withdrawCollateralTx = await balanceSheet.withdrawCollateral(fyToken, collateralAmount);
await withdrawCollateralTx.wait();
```
