# Blueberry Bank Contract

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

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

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

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

### Functions

#### initialize

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

#### EXECUTOR

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

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

**Parameters:**

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

#### setAllowContractCalls

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters**

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

#### whitelistContract

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

#### whitelistSpells

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

#### whitelistTokens

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

#### whitelistERC1155

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

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

**Parameters:**

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

#### **addBank**

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

#### setBankStatus

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Modifiers**

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

**Return**

* None

#### isBorrowerAllowed

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

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

#### isRepayAllowed

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

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

#### isLendAllowed

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

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

#### isWithdrawLendAllowed

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

* None

**Modifiers:**

* None

**Return:**

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

#### accrue

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

#### accrueAll

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Modifiers:**

* None

**Return:**

* None

#### \_borrowBalanceStored

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Modifiers:**

* None

**Return:**

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

#### currentPositionDebt

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters**:

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

**Return:**

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

#### getPositionDebt

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Modifiers:**

* None

**Returns:**

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

#### getBankInfo

{% code overflow="wrap" %}

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

{% endcode %}

This function returns the bank information for the specified token.

**Parameters:**

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

**Modifiers:**

* None

**Returns:**

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

#### getPositionInfo

{% code overflow="wrap" %}

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

{% endcode %}

This function returns the information of the specified position.

**Parameters:**

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

**Modifiers:**

* None

**Returns:**

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

#### getCurrentPositionInfo

{% code overflow="wrap" %}

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

{% endcode %}

This function returns the information about the current position

**Returns:**

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

**Modifiers:**

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

#### getPositionValue

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters**

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

**Return:**

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

#### getDebtValue

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Return:**

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

#### getIsolatedCollateralValue

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Return:**

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

#### getPositionRisk

{% code overflow="wrap" %}

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

{% endcode %}

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

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

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

**Parameters:**

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

**Returns:**

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

#### isLiquidatable

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### liquidate

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Details:**

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

#### execute

{% code overflow="wrap" %}

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

{% endcode %}

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

**Modifiers**

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

**Parameters**

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

**Return:**

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

#### lend

{% code overflow="wrap" %}

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

{% endcode %}

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

**Modifiers:**

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

**Parameters**

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

#### withdrawLend

{% code overflow="wrap" %}

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

{% endcode %}

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

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

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

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

**Modifiers:**

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

**Parameters:**

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

#### borrow

{% code overflow="wrap" %}

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

{% endcode %}

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

**Modifiers:**

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

**Parameters:**

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

**Return:**

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

#### repay

{% code overflow="wrap" %}

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

{% endcode %}

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

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

**Modifiers:**

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

**Parameters:**&#x20;

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

#### \_repay

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### putCollateral

{% code overflow="wrap" %}

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

{% endcode %}

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

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

**Modifiers:**&#x20;

* `inExec` Can only be called during execution

**Parameters:**

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

#### takeCollateral

{% code overflow="wrap" %}

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

{% endcode %}

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

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

**Modifiers:**&#x20;

* `inExec` Can only be called during execution

**Parameters:**

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

#### \_doBorrow

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### \_doRepay

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### \_doERC20TransferIn

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### \_doERC1155TransferIn

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### \_isSoftVault

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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

**Returns:**

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

#### \_ensureApprove

{% code overflow="wrap" %}

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

{% endcode %}

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

**Parameters:**

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://v1.docs.blueberry.garden/developer-guides/contracts/blueberry-bank/blueberry-bank-contract.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
