# Cauldron V2

Second version of the cauldrons, which changed the way fees and liquidations are accounted. The way the user interacts with it hasn't changed and no new functions were introduced.

It is deployed directly and then used as a masterContract to deploy each market, as clones, following the minimal proxy pattern.

You can find the full contract [here](https://github.com/Abracadabra-money/magic-internet-money/blob/main/archive/contracts/cauldrons/CauldronV2.sol).

### constructor nonpayable (address) <a href="#constructor-nonpayable-address" id="constructor-nonpayable-address"></a>

This will create the masterContract that will be used by all the clones (markets).

<table><thead><tr><th width="355">Parameter</th><th>Description</th></tr></thead><tbody><tr><td><strong>bentoBox_</strong></td><td>The address of the BentoBox</td></tr><tr><td><strong>magicInternetMoney_</strong></td><td>The address of MIM.</td></tr></tbody></table>

## Write Functions

### accrue

```solidity
function accrue() public
```

Accrues the interest on the borrowed tokens and handles the accumulation of fees.

### updateExchangeRate

```solidity
function updateExchangeRate() public returns (bool updated, uint256 rate)
```

Gets the exchange rate, ie how much collateral to buy 1e18 asset. Invoked if needed since Oracle queries can be expensive.

**Returns**

| Name      | Type    | Description                                                          |
| --------- | ------- | -------------------------------------------------------------------- |
| `updated` | bool    | boolean determining if the exchange rate has been updated yet or not |
| `rate`    | uint256 | the new exchange rate that was fetched                               |

### addCollateral

```solidity
function addCollateral(
        address to,
        bool skim,
        uint256 share
    ) public
```

Adds `share` amount of collateral from `msg.sender` to the account `to`.

**Parameters**

| Name    | Type    | Description                                                                                                                                                            |
| ------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `to`    | address | receiver of the tokens                                                                                                                                                 |
| `skim`  | bool    | <p>True if the amount should be skimmed from the deposit balance of msg.sender.<br>False if tokens from msg.sender in <code>bentoBox</code> should be transferred.</p> |
| `share` | uint256 | amount of shares to add for `to`                                                                                                                                       |

### removeCollateral

```solidity
function removeCollateral(address to, uint256 share) public solvent
```

Calls `_removeCollateral`, which removes the amount `share` of collateral and transfers it to the account `to`.

**Parameters**

| Name    | Type    | Description              |
| ------- | ------- | ------------------------ |
| `to`    | address | receiver of the shares   |
| `share` | uint256 | amount of shares to send |

### borrow

```solidity
function borrow(address to, uint256 amount) public solvent returns (uint256 part, uint256 share)
```

Calls `_borrow`, which allows the sender to borrow `amount` and transfer to `to`.

**Parameters**

| Name     | Type    | Description                     |
| -------- | ------- | ------------------------------- |
| `to`     | address | receiver of the borrowed assets |
| `amount` | uint256 | amount of assets to borrow      |

**Returns**

| Name    | Type    | Description                          |
| ------- | ------- | ------------------------------------ |
| `part`  | uint256 | total part of debt held by borrowers |
| `share` | uint256 | total amount in shares borrowed      |

### repay

```solidity
function repay(
        address to,
        bool skim,
        uint256 part
    ) public returns (uint256 amount)
```

Calls `_repay`, which repays a loan.

**Parameters**

| Name   | Type    | Description                                                             |
| ------ | ------- | ----------------------------------------------------------------------- |
| `to`   | address | address of user payment should go to                                    |
| `skim` | bool    | true if amount should be skimmed from the deposit balance of msg.sender |
| `part` | uint256 | amount to repay                                                         |

**Returns**

| Name     | Type    | Description          |
| -------- | ------- | -------------------- |
| `amount` | uint256 | total amount repayed |

### cook

```solidity
function cook(
        uint8[] calldata actions,
        uint256[] calldata values,
        bytes[] calldata datas
    ) external payable returns (uint256 value1, uint256 value2)
```

Executes a set of actions and allows composability (contract calls) to other contracts.

The cook function allows to bundle functionality within one contract call while passing return values from one call to the next one.\
Actions are defined by a numeric identifier and can return two values, value1 and value2 to the next function. The input arrays actions, values and datas define the sequential actions. In the Value array the ether value of a call may be defined.

Whereas calling functions like borrow that have the solvent modifier requires solvency at the end of the function, solvency only needs to be guaranteed at the end of the cook function, thereby allowing more complicated operations such as leveraging within one call.

For certain parameters either an external value can be passed in or the identifier USE\_VALUE1 (-1) or USE\_\_VALUE2 (-2) to access either of the local variables. The following variables are marked ***in bold italic*** in the table below. If an action returns one value it is saved as value1, if two are returned they are saved as value1 and value2 respectively. Any action can access these values during the whole duration of the cook call.

The call data for the actions is ABI encoded as listed below.

<table><thead><tr><th width="277">Action Name</th><th width="64">ID</th><th width="172">parameter names</th><th>ABI encoding</th><th>returnValues</th></tr></thead><tbody><tr><td>ACTION_REPAY</td><td>2</td><td><em><strong>share</strong></em>, to, skim</td><td>int256, address, bool</td><td></td></tr><tr><td>ACTION_REMOVE_COLLATERAL</td><td>4</td><td><em><strong>fraction</strong></em>, to</td><td>int256, address</td><td></td></tr><tr><td>ACTION_BORROW</td><td>5</td><td><em><strong>amount</strong></em>, to</td><td>int256, address</td><td>part, share</td></tr><tr><td>ACTION_GET_REPAY_SHARE</td><td>6</td><td><em><strong>part</strong></em></td><td>int256</td><td></td></tr><tr><td>ACTION_GET_REPAY_PART</td><td>7</td><td><em><strong>amount</strong></em></td><td>int256</td><td></td></tr><tr><td>ACTION_ACCRUE</td><td>8</td><td></td><td></td><td></td></tr><tr><td>ACTION_ADD_COLLATERAL</td><td>10</td><td><strong>share</strong>, to, skim</td><td>int256, address, bool</td><td></td></tr><tr><td>ACTION_UPDATE_EXCHANGE_RATE</td><td>11</td><td>must_update, minRate, maxRate</td><td>bool, uint256, uint256</td><td></td></tr><tr><td>ACTION_BENTO_DEPOSIT</td><td>20</td><td>token, to, amount, share</td><td>IERC20, address, int256, int256</td><td>amountOut, shareOut</td></tr><tr><td>ACTION_BENTO_WITHDRAW</td><td>21</td><td>token, to, amount, share</td><td>IERC20, address, int256, int256</td><td>amountOut, shareOut</td></tr><tr><td>ACTION_BENTO_TRANSFER</td><td>22</td><td>token, to, share</td><td>IERC20, address, int256</td><td></td></tr><tr><td>ACTION_BENTO_TRANSFER_MULTIPLE</td><td>23</td><td>token, tos, shares</td><td>IERC20, address[], uint256[]</td><td></td></tr><tr><td>ACTION_BENTO_SETAPPROVAL</td><td>24</td><td>user, _masterContract, approved, v, r, s</td><td>address, address, bool, uint8, bytes32, bytes32</td><td></td></tr><tr><td>ACTION_CALL</td><td>30</td><td>callee, callData, useValue1, useValue2, returnValues</td><td>address, bytes, bool, bool, uint8</td><td></td></tr></tbody></table>

```solidity
// Functions that need accrue to be called
uint8 internal constant ACTION_REPAY = 2;
uint8 internal constant ACTION_REMOVE_COLLATERAL = 4;
uint8 internal constant ACTION_BORROW = 5;
uint8 internal constant ACTION_GET_REPAY_SHARE = 6;
uint8 internal constant ACTION_GET_REPAY_PART = 7;
uint8 internal constant ACTION_ACCRUE = 8;

// Functions that don't need accrue to be called
uint8 internal constant ACTION_ADD_COLLATERAL = 10;
uint8 internal constant ACTION_UPDATE_EXCHANGE_RATE = 11;

// Function on BentoBox
uint8 internal constant ACTION_BENTO_DEPOSIT = 20;
uint8 internal constant ACTION_BENTO_WITHDRAW = 21;
uint8 internal constant ACTION_BENTO_TRANSFER = 22;
uint8 internal constant ACTION_BENTO_TRANSFER_MULTIPLE = 23;
uint8 internal constant ACTION_BENTO_SETAPPROVAL = 24;

// Any external call (except to BentoBox)
uint8 internal constant ACTION_CALL = 30;

int256 internal constant USE_VALUE1 = -1;
int256 internal constant USE_VALUE2 = -2;
```

**Parameters**

| Name      | Type       | Description                                                                           |
| --------- | ---------- | ------------------------------------------------------------------------------------- |
| `actions` | uint8\[]   | array with sequence of actions to execute                                             |
| `values`  | uint256\[] | one-to-one mapped array to `actions`, ETH amounts to send along with the actions      |
| `datas`   | bytes\[]   | one-to-one mapped array to `actions`, contains abi encoded data of function arguments |

**Returns**

| Name     | Type    | Description                                                                                               |
| -------- | ------- | --------------------------------------------------------------------------------------------------------- |
| `value1` | uint256 | may contain first positioned return value of last executed action (if applicable)                         |
| `value2` | uint256 | may contain second positioned return value of last executed action which returns 2 values (if applicable) |

### liquidate

```solidity
function liquidate(
        address[] calldata users,
        uint256[] calldata maxBorrowParts,
        address to,
        ISwapper swapper,
    ) public
```

Handles the liquidation of users' balances once the users' amount of collateral is too low.

**Parameters**

| Name             | Type       | Description                                                                                                    |
| ---------------- | ---------- | -------------------------------------------------------------------------------------------------------------- |
| `users`          | address\[] | array of user addresses                                                                                        |
| `maxBorrowParts` | uint256\[] | one-to-one mapping to `users`, contains maximum (partial) borrow amounts (to liquidate) of the respective user |
| `to`             | address    | address of the receiver in open liquidations if `swapper` is zero                                              |
| `swapper`        | ISwapper   | contract address of the `ISwapper` implementation, swappers are restricted for closed liquidations             |

### withdrawFees

```solidity
function withdrawFees() public
```

Withdraw the fees accumulated to the feeTo address.

### setFeeTo

```solidity
function setFeeTo(address newFeeTo) public onlyOwner
```

Sets the beneficiary of fees accrued in liquidations. Can only be called by the owner of the contract.

**Parameters**

| Name       | Type    | Description                |
| ---------- | ------- | -------------------------- |
| `newFeeTo` | address | address of the beneficiary |

### reduceSupply

```solidity
function reduceSupply(uint256 amount) public 
```

Reduces the supply of MIM

**Parameters**

| Name   | Type    | Description                                           |
| ------ | ------- | ----------------------------------------------------- |
| amount | uint256 | amount to reduce supply by (in native representation) |

## View Functions

### BORROW\_OPENING\_FEE

Returns the opening fee (charged instantly, added to user debt upon borrowing) in Basis Points.

### COLLATERIZATION\_RATE

Returns the Collateralization Rate (maximum % borrowable with this collateral) in Basis Points.\
\&#xNAN;*eg: 75000 = 75%*

### LIQUIDATION\_MULTIPLIER

Returns the liquidation fee in Basis Points.\
\&#xNAN;*eg: 112000 would add 12% (it's a multiplier, so the value is 112%)*

### accrueInfo[​](https://smart-docs.vercel.app/contract#accrueInfo)

**Return values**

| Name                      | Type      | Description                                                  |
| ------------------------- | --------- | ------------------------------------------------------------ |
| **lastAccrued**           | `uint64`  | Timestamp of the last accrue() call.                         |
| **feesEarned**            | `uint128` | Fees accrue between the last withdrawal and the last accrue. |
| **INTEREST\_PER\_SECOND** | `uint64`  |                                                              |

### bentoBox

**Return values**

| Name  | Type      | Description                                                                                         |
| ----- | --------- | --------------------------------------------------------------------------------------------------- |
| **/** | `address` | <p>Address of the bentoBox the cauldron is deployed on.<br>Set by constructor of masterContract</p> |

### collateral

**Return values**

| Name  | Type      | Description                                      |
| ----- | --------- | ------------------------------------------------ |
| **/** | `address` | Address of the collateral used by this cauldron. |

### exchangeRate

**Return values**

| Name  | Type      | Description                   |
| ----- | --------- | ----------------------------- |
| **/** | `uint256` | Current cached exchange rate. |

### feeTo[​](https://smart-docs.vercel.app/contract#feeTo) <a href="#feeto" id="feeto"></a>

**Return values**

| Name  | Type      |                                                                                                                |
| ----- | --------- | -------------------------------------------------------------------------------------------------------------- |
| **/** | `address` | Recipient of the Fees (controlled by masterContract, which is why regular cauldrons have a feeTo zero address) |

### magicInternetMoney <a href="#magicinternetmoney" id="magicinternetmoney"></a>

**Return values**

| Name  | Type      | Description                                          |
| ----- | --------- | ---------------------------------------------------- |
| **/** | `address` | Address of MIM, set by constructor of masterContract |

### masterContract <a href="#mastercontract" id="mastercontract"></a>

**Return values**

| Name  | Type      | Description             |
| ----- | --------- | ----------------------- |
| **/** | `address` | masterContract address. |

### oracle[​](https://smart-docs.vercel.app/contract#oracle) <a href="#oracle" id="oracle"></a>

**Return values**

| Name  | Type      | Description     |
| ----- | --------- | --------------- |
| **/** | `address` | Oracle Address. |

### oracleData[​](https://smart-docs.vercel.app/contract#oracleData) <a href="#oracledata" id="oracledata"></a>

**Return values**

| Name  | Type    | Description                   |
| ----- | ------- | ----------------------------- |
| **/** | `bytes` | Oracle data used to query it. |

#### owner <a href="#owner" id="owner"></a>

**Return values**

| Name  | Type      |                                                                                                                                       |
| ----- | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **/** | `address` | <p>Owner of the Cauldron<br>(controlled by masterContract, which is why regular cauldrons have <em>zeroAddress</em> as an owner).</p> |

### pendingOwner[​](https://smart-docs.vercel.app/contract#pendingOwner) <a href="#pendingowner" id="pendingowner"></a>

When transferring ownership, the future owner is pending until they claims ownership.

**Return values**

| Name  | Type      | Description                   |
| ----- | --------- | ----------------------------- |
| **/** | `address` | Address of the pending owner. |

### totalBorrow[​](https://smart-docs.vercel.app/contract#totalBorrow)

Returns the total amounts borrowed from the cauldron.

**Return values**

| Name        | Type      | Description                          |
| ----------- | --------- | ------------------------------------ |
| **elastic** | `uint128` | Amount of MIM borrowed by users.     |
| **base**    | `uint128` | Amount of borrowParts held by users. |

### totalCollateralShare[​](https://smart-docs.vercel.app/contract#totalCollateralShare) <a href="#totalcollateralshare" id="totalcollateralshare"></a>

Returns the amount (in shares) of the token `collateral` used as collateral in this cauldron.

**Return values**

| Name  | Type      | Description                                                 |
| ----- | --------- | ----------------------------------------------------------- |
| **/** | `uint256` | Amount of shares of collateral deposited into the Cauldron. |

### userBorrowPart

Returns the amount of borrowParts held by a user.\
To convert that amount into a numerical MIM debt amount, you must do totalBorrow\.elastic / totalBorrow\.base \* borrowParts.

**Parameters**

| Name  | Type      | Description   |
| ----- | --------- | ------------- |
| **/** | `address` | User address. |

**Return values**

| Name  | Type      | Description                 |
| ----- | --------- | --------------------------- |
| **/** | `uint256` | Amount of borrowParts held. |

### userCollateralShare[​](https://smart-docs.vercel.app/contract#userCollateralShare) <a href="#usercollateralshare" id="usercollateralshare"></a>

Amount (in shares) of the token `collateral` used as collateral by the user.

**Parameters**

| Name  | Type      | Description   |
| ----- | --------- | ------------- |
| **/** | `address` | User address. |

**Return values**

| Name  | Type      | Description                     |
| ----- | --------- | ------------------------------- |
| **/** | `uint256` | Shares of collateral deposited. |
