# Introduction

[**Abracadabra.money** ](https://abracadabra.money)is a lending platform that uses interest-bearing tokens (ibTKNs) as collateral to borrow a USD pegged stablecoin (Magic Internet Money - **MIM**), that can be used as any other traditional stablecoin.

Currently, a lot of assets, such as yVaults have locked in capital that can't be put to further use. **Abracadabra** offers an opportunity to use it.


# Security & Vulnerability

How to approach a vulnerability you've found.

If you've found a vulnerability in our codebase, please contact the security address immediately in order for our team to take action as quickly as possible.

Please do not disclose the vulnerability while the team is taking action to prevent damage.

The security team can be reached at: <security@abracadabra.money>


# Architecture Overview

How the different smart contracts of Abracadabra work together

Abracadabra.Money as a protocol is a very modular set of smart contracts deployed on public blockchains allowing users to deposit collateral, earn yield on it and borrow MIM, a USD-pegged stablecoin.

It is built on top of BentoBox and KASHI technology, an infrastructure created by BoringCrypto and adapted by our team.

The two core contracts enabling the magic behind Abracadabra are the DegenBox (our version of the BentoBox) and Cauldrons (the actual isolated markets)

{% embed url="<https://www.youtube.com/watch?v=zKAgEp9vHms>" fullWidth="false" %}
Here is a video going into detail of how Abracadabra works as a whole. Thanks Owen for allowing us to post it here!
{% endembed %}

## Core Contracts.

### DegenBox.

DegenBox is our version of the BentoBox. It is a smart contract vault handling user funds, their transfer and strategies.

It's where the funds will be stored, in a non-custodial way, on behalf of the users and smart contracts.\
When using Abracadabra, the DegenBox will store the collateral deposited, enable strategies to earn interest on it, and store the MIM until borrowed by the user.

The DegenBox uses the concept of 'Share' to represent amounts of token. Because tokens can vary in amounts (because yield strategies are earning interest on them for example), using shares of the total pool of tokens allow the management of yield for the users.\
*It is similar to other vaults like yearn shares.*

### Cauldrons.

The Cauldrons are isolated markets. They are based on KASHI technology and handle all the computation related to the borrowing of MIM, the solvency of the users and their liquidation.

One Cauldron is deployed per collateral accepted on Abracadabra. Each instance of a Cauldron is a clone of a MasterContract, following the minimal proxy standard. It has parameters such as fees, fee recipient and Loan to Value, controlled by the MasterContract.

To make MIM available for users to borrow, the MIM Multisig mints MIM and deposits it into the Cauldron's account within DegenBox. While they can appear as circulating, until borrowed by users those MIM can't move, they are out of circulation.

The Cauldron is the entry-point for the user, they interact with it to deposit collateral, leverage it or borrow MIM.\
It is also the entry-point for liquidators, interacting with it to check the solvency of a user and liquidate the position if needed.

Cauldrons have the ability to bundle several "Actions" (deposit tokens, add it as collateral, borrow, leverage…) into one transaction, saving our users time and gas while supporting complex sequences of operations atomically, like leverage.

### Oracles.

Oracles are key to Abracadabra's stability. To keep MIM backed by collateral, the smart contracts need to know at all times the price, in USD *(as MIM is pegged to USD)* of each collateral.\
Therefore, for every market, we have an oracle pricing the relevant collateral in USD. It is connected to the Cauldron itself.

For the vast majority of the markets, ChainLink oracles are used, either directly (when the collateral is 'naked', like ETH for example) or indirectly (when the collateral is wrapped, like yearn vaults for example).

To allow for upgradability, and because you can't change the oracle of a Cauldron, we sometimes use Proxy Oracles, that point to a 'real' Oracle. The oracle the proxy points to can be changed by the Owner of the Proxy Oracle.

### Strategies.

Strategies enable the deployments of funds sitting in the DegenBox into various yielding strategies, enabling the user to earn interests on the collateral deposited while borrowing.

Strategies are connected to the DegenBox itself and allow for the deployment of some percentage of the funds (known as the targetPercent) into a strategy.

Being connected to the DegenBox, the strategy is based on tokens, not cauldrons. While multiple cauldrons can exist with the same collateral, one strategy will manage one token.

When earning a profit, the Strategy increases the value of a Share of the token, distributing it equally across all deposits.

## Periphery Contracts.

While basic functionalities of abracadabra can be achieved with the core contracts, the periphery contracts allow more advanced functionalities, like leveraging, handling some specific collateral types, fee distribution, and Cauldron parameters management.

### Swappers.

Swappers are special contracts allowing the swap of one token for another one. In Abracadabra's case, they are used to enable leveraging and deleveraging in an atomic way (as one of the 'Actions' of the transaction to the Cauldron).

They can be 'simple', using a pre-defined hard coded route, or more advanced, using aggregators like the 0x protocol.

They are not connected directly to either DegenBox or Cauldron, but is added as one of the actions when sending a transaction to the cauldron.

### Wrappers.

Because some token have specific non-standard functionalities, like claimable rewards, or rebasing tokens, they can't be used directly within abracadabra while maintaining their functionalities. For that reason, we use Wrappers on some collateral types to adapt Abracadabra to those types of collateral. *(some examples of those are Convex LP positions or GLP positons)*

The use of wrappers mean that from the Cauldron's perspective, the collateral is the wrapped token. From a user-flow perspective, it means that the user has to wrap their tokens to use them, either seamlessly via an action when they call the Cauldron or via a separate transaction before interacting with the cauldron.

### Withdrawers.

Withdrawers are a special contract with which the user does not interact. It is used to automate the collection of the protocol fees generated by each cauldron as well as their distribution to the SPELL buyer for sSPELL and the mSPELL Sender for mSPELL and Treasury.

2 kinds of withdrawer exist: the main Ethereum Mainnet withdrawer and the Multichain Withdrawers, deployed on the other chains where abracadabra is present.

The Multichain Withdrawers collect fees from the Cauldrons and bridge them to the Ethereum Withdrawer on Mainnet, which collects the mainnet fees and distributes it all.

### CauldronOwner.

The CauldronOwner is another contract the user does not interact with. It is the Owner of all the masterContracts, and concentrates them all under one contract, allowing authorized 'operators' to perform actions on the masterContract, like change interest rate, borrow limit, deprecate cauldrons reduce the MIM available in a market…


# DegenBox

The token Vault powering Abracadabra

Degenbox is an authorized fork of [**BentoBox**](https://docs.sushi.com/products/bentobox) (as Abracadabra purchased the licence for it). Cauldrons are built on top of both BentoBox and Degenbox, which allow users to reduce transaction fees as well as allow the creation of multiple strategies for the assets held inside.

Please do not send funds directly to either BentoBox or Degenbox as they will be lost! Use the "Deposit" function instead!

### `Constructor`​ <a href="#constructor" id="constructor"></a>

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

**Parameters**

| Name            | Type      | Description      |
| --------------- | --------- | ---------------- |
| **wethToken\_** | `address` | address of WETH. |

### Functions <a href="#functions" id="functions"></a>

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

* [DOMAIN\_SEPARATOR](#domain_separator)
* [balanceOf](#balanceof)
* [masterContractApproved](#mastercontractapproved)
* [masterContractOf](#mastercontractof)
* [nonces](#nonces)
* [owner](#owner)
* [pendingOwner](#pendingowner)
* [pendingStrategy](#pendingstrategy)
* [strategy](#strategy)
* [strategyData](#strategydata)
* [toAmount](#toamount)
* [toShare](#toshare)
* [totals](#totals)
* [whitelistedMasterContracts](#whitelistedmastercontracts)

#### Write Functions

* [batch](#batch)
* [batchFlashLoan](#batchflashloan)
* [claimOwnership](#claimownership)
* [deploy](#deploy)
* [deposit](#deposit)
* [flashLoan](#flashloan)
* [harvest](#harvest)
* [permitToken](#permittoken)
* [registerProtocol](#registerprotocol)
* [setMasterContractApproval](#setmastercontractapproval)
* [setStrategy](#setstrategy)
* [setStrategyTargetPercentage](#setstrategytargetpercentage)
* [transfer](#transfer)
* [transferMultiple](#transfermultiple)
* [transferOwnership](#transferownership)
* [whitelistMasterContract](#whitelistmastercontract)
* [withdraw](#withdraw)

***

#### `DOMAIN_SEPARATOR | view`[​](https://smart-docs.vercel.app/contract#DOMAIN_SEPARATOR) <a href="#domain_separator" id="domain_separator"></a>

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `bytes32` |

#### `balanceOf | view`[​](https://smart-docs.vercel.app/contract#balanceOf) <a href="#balanceof" id="balanceof"></a>

```solidity
mapping(IERC20 => mapping(address => uint256)) public balanceOf
```

**Parameters**

| Name  | Type      | Description                          |
| ----- | --------- | ------------------------------------ |
| **/** | `address` | Token to check                       |
| **/** | `address` | The address which balance is checked |

**Return values**

| Name  | Type      | Description                          |
| ----- | --------- | ------------------------------------ |
| **/** | `uint256` | Shares of 'token' owned by 'address' |

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

```solidity
function batch(bytes[] calldata calls, bool revertOnFail) 
    external payable 
    returns (bool[] memory successes, bytes[] memory results) 
```

**Parameters**

| Name             | Type      | Description                                                             |
| ---------------- | --------- | ----------------------------------------------------------------------- |
| **calls**        | `bytes[]` | An array of inputs for each call.                                       |
| **revertOnFail** | `bool`    | If True then reverts after a failed call and stops doing further calls. |

**Return values**

| Name          | Type      | Description                                                                          |
| ------------- | --------- | ------------------------------------------------------------------------------------ |
| **successes** | `bool[]`  | An array indicating the success of a call, mapped one-to-one to `calls`.             |
| **results**   | `bytes[]` | An array with the returned data of each function call, mapped one-to-one to `calls`. |

#### `batchFlashLoan | nonpayable`[​](https://smart-docs.vercel.app/contract#batchFlashLoan) <a href="#batchflashloan" id="batchflashloan"></a>

```solidity
function batchFlashLoan(
    IBatchFlashBorrower borrower,
    address[] calldata receivers,
    IERC20[] calldata tokens,
    uint256[] calldata amounts,
    bytes calldata data
) public {
```

**Parameters**

| Name          | Type        | Description                                                                                                  |
| ------------- | ----------- | ------------------------------------------------------------------------------------------------------------ |
| **borrower**  | `address`   | The address of the contract that implements and conforms to `IBatchFlashBorrower` and handles the flashloan. |
| **receivers** | `address[]` | The address of the contract that implements and conforms to `IBatchFlashBorrower` and handles the flashloan. |
| **tokens**    | `address[]` | The addresses of the tokens.                                                                                 |
| **amounts**   | `uint256[]` | amounts of the tokens for each receiver.                                                                     |
| **data**      | `bytes`     | The calldata to pass to the `borrower` contract.                                                             |

**Return values**

No return values for this function.

#### `claimOwnership | nonpayable`[​](https://smart-docs.vercel.app/contract#claimOwnership) <a href="#claimownership" id="claimownership"></a>

```solidity
function claimOwnership() public 
```

Needs to be called by `pendingOwner` to claim ownership.

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

```solidity
function deploy(
    address masterContract,
    bytes calldata data,
    bool useCreate2
) public payable returns (address cloneAddress)
```

Deploys a given master Contract as a clone.

**Parameters**

| Name               | Type      | Description                                                                                 |
| ------------------ | --------- | ------------------------------------------------------------------------------------------- |
| **masterContract** | `address` | The address of the contract to clone.                                                       |
| **data**           | `bytes`   | Additional abi encoded calldata that is passed to the new clone via `IMasterContract.init`. |
| **useCreate2**     | `bool`    | Creates the clone by using the CREATE2 opcode, in this case `data` will be used as salt.    |

**Return values**

| Name             | Type      | Description                            |
| ---------------- | --------- | -------------------------------------- |
| **cloneAddress** | `address` | Address of the created clone contract. |

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

```solidity
function deposit(
    IERC20 token_,
    address from,
    address to,
    uint256 amount,
    uint256 share
) public payable allowed(from) returns (uint256 amountOut, uint256 shareOut)
```

**Parameters**

| Name        | Type      | Description                                                                    |
| ----------- | --------- | ------------------------------------------------------------------------------ |
| **token\_** | `address` | The ERC-20 token to deposit.                                                   |
| **from**    | `address` | which account to pull the tokens from.                                         |
| **to**      | `address` | which account to push the tokens to.                                           |
| **amount**  | `uint256` | Token amount in native representation to deposit.                              |
| **share**   | `uint256` | Token amount represented in shares to deposit. Takes precedence over `amount`. |

**Return values**

| Name          | Type      |                                             |
| ------------- | --------- | ------------------------------------------- |
| **amountOut** | `uint256` | The amount deposited.                       |
| **shareOut**  | `uint256` | The deposited amount represented in shares. |

#### `flashLoan | nonpayable`[​](https://smart-docs.vercel.app/contract#flashLoan) <a href="#flashloan" id="flashloan"></a>

```solidity
function flashLoan(
    IFlashBorrower borrower,
    address receiver,
    IERC20 token,
    uint256 amount,
    bytes calldata data
) public
```

**Parameters**

| Name         | Type      |                                                                                                         |
| ------------ | --------- | ------------------------------------------------------------------------------------------------------- |
| **borrower** | `address` | The address of the contract that implements and conforms to `IFlashBorrower` and handles the flashloan. |
| **receiver** | `address` | Address of the token receiver.                                                                          |
| **token**    | `address` | The address of the token to receive.                                                                    |
| **amount**   | `uint256` | Amount of the tokens to receive.                                                                        |
| **data**     | `bytes`   | The calldata to pass to the `borrower` contract.                                                        |

**Return values**

No return values for this function.

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

```solidity
function harvest(
    IERC20 token,
    bool balance,
    uint256 maxChangeAmount
) public
```

The actual process of yield farming. Executes the strategy of `token`. Optionally does housekeeping if `balance` is true.

**Parameters**

| Name                | Type      | Description                                                                        |
| ------------------- | --------- | ---------------------------------------------------------------------------------- |
| **token**           | `address` | The address of the token for which a strategy is deployed.                         |
| **balance**         | `bool`    | True if housekeeping should be done.                                               |
| **maxChangeAmount** | `uint256` | The maximum amount for either pulling or pushing from/to the `IStrategy` contract. |

**Return values**

No return values for this function.

#### `masterContractApproved | view`[​](https://smart-docs.vercel.app/contract#masterContractApproved) <a href="#mastercontractapproved" id="mastercontractapproved"></a>

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

masterContract to user to approval state, returns True if the user has approved the masterContract.

**Parameters**

| Name  | Type      | Description                    |
| ----- | --------- | ------------------------------ |
| **/** | `address` | Address of the masterContract. |
| **/** | `address` | Address of the user.           |

**Return values**

| Name  | Type   | Description                                             |
| ----- | ------ | ------------------------------------------------------- |
| **/** | `bool` | Returns True if the masterContract is approved by user. |

#### `masterContractOf | view`[​](https://smart-docs.vercel.app/contract#masterContractOf) <a href="#mastercontractof" id="mastercontractof"></a>

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

Mapping from clone contracts to their masterContract.

**Parameters**

| Name  | Type      | Description                     |
| ----- | --------- | ------------------------------- |
| **/** | `address` | Address of the cloned contract. |

**Return values**

| Name  | Type      | Description                                                  |
| ----- | --------- | ------------------------------------------------------------ |
| **/** | `address` | Address of the masterContract clone contract is cloned from. |

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

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

User nonces for masterContract approvals.

**Parameters**

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

**Return values**

| Name  | Type      | Description        |
| ----- | --------- | ------------------ |
| **/** | `uint256` | Nonce of the user. |

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

Owner of the DegenBox contract. Can perform actions that onlyOwner() can perform, such as strategy updates.

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      | Description          |
| ----- | --------- | -------------------- |
| **/** | `address` | Address of the Owner |

#### `pendingOwner | view`[​](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. |

#### `pendingStrategy | view`[​](https://smart-docs.vercel.app/contract#pendingStrategy) <a href="#pendingstrategy" id="pendingstrategy"></a>

Strategy change being submitted to a delay of 3 days, the setStrategy function is called twice, once to declare a strategy change, and another time after STRATEGY\_DELAY (3 days). In between those calls, the new strategy is pendingStrategy.

**Parameters**

| Name  | Type      | Description                                                 |
| ----- | --------- | ----------------------------------------------------------- |
| **/** | `address` | The address of the token that maps to a strategy to change. |

**Return values**

| Name  | Type      | Description                                               |
| ----- | --------- | --------------------------------------------------------- |
| **/** | `address` | The address of the contract that conforms to `IStrategy`. |

#### `permitToken | nonpayable`[​](https://smart-docs.vercel.app/contract#permitToken) <a href="#permittoken" id="permittoken"></a>

```solidity
function permitToken(
        IERC20 token,
        address from,
        address to,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public
```

**Parameters**

<table><thead><tr><th>Name</th><th width="374">Type</th><th></th></tr></thead><tbody><tr><td><strong>token</strong></td><td><code>address</code></td><td>The ERC20 token that supports permit to call permit on.</td></tr><tr><td><strong>from</strong></td><td><code>address</code></td><td>The token owner's address</td></tr><tr><td><strong>to</strong></td><td><code>address</code></td><td>The token spender's address</td></tr><tr><td><strong>amount</strong></td><td><code>uint256</code></td><td>The amount to be approved.</td></tr><tr><td><strong>deadline</strong></td><td><code>uint256</code></td><td>Timestamp in the future until which permit can be called.</td></tr><tr><td><strong>v</strong></td><td><code>uint8</code></td><td>v of the ECDSA signature.</td></tr><tr><td><strong>r</strong></td><td><code>bytes32</code></td><td>r of the ECDSA signature.</td></tr><tr><td><strong>s</strong></td><td><code>bytes32</code></td><td>s of the ECDSA signature.</td></tr></tbody></table>

**Return values**

No return values for this function.

#### `registerProtocol | nonpayable`[​](https://smart-docs.vercel.app/contract#registerProtocol) <a href="#registerprotocol" id="registerprotocol"></a>

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

#### `setMasterContractApproval | nonpayable`[​](https://smart-docs.vercel.app/contract#setMasterContractApproval) <a href="#setmastercontractapproval" id="setmastercontractapproval"></a>

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **user**           | `address` |
| **masterContract** | `address` |
| **approved**       | `bool`    |
| **v**              | `uint8`   |
| **r**              | `bytes32` |
| **s**              | `bytes32` |

**Return values**

No return values for this function.

#### `setStrategy | nonpayable`[​](https://smart-docs.vercel.app/contract#setStrategy) <a href="#setstrategy" id="setstrategy"></a>

```solidity
function setStrategy(IERC20 token, IStrategy newStrategy) public onlyOwner
```

Sets the contract address of a new strategy that conforms to `IStrategy` for `token`. Must be called twice with the same arguments. A new strategy becomes pending first and can be activated once `STRATEGY_DELAY` is over. In the case of the Degenbox, `STRATEGY_DELAY` is 3 days.

**Parameters**

| Name            | Type      | Description                                                 |
| --------------- | --------- | ----------------------------------------------------------- |
| **token**       | `address` | The address of the token that maps to a strategy to change. |
| **newStrategy** | `address` | The address of the contract that conforms to `IStrategy`.   |

**Return values**

No return values for this function.

#### `setStrategyTargetPercentage | nonpayable`[​](https://smart-docs.vercel.app/contract#setStrategyTargetPercentage) <a href="#setstrategytargetpercentage" id="setstrategytargetpercentage"></a>

```solidity
function setStrategyTargetPercentage(
         IERC20 token, 
         uint64 targetPercentage_
      ) public onlyOwner {
```

Sets the target percentage of the strategy for `token`. It corresponds to the percentage of tokens deployed to the Strategy, vs kept in DegenBox.

**Parameters**

| Name                   | Type      | Description                                                                    |
| ---------------------- | --------- | ------------------------------------------------------------------------------ |
| **token**              | `address` | The address of the token that maps to a strategy to change.                    |
| **targetPercentage\_** | `uint64`  | The new target in percent. Must be lesser or equal to `MAX_TARGET_PERCENTAGE`. |

**Return values**

No return values for this function.

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

Returns the address of the Strategy mapped to the given ERC20 token.

**Parameters**

| Name  | Type      | Description                                      |
| ----- | --------- | ------------------------------------------------ |
| **/** | `address` | The address of the token that maps to a strategy |

**Return values**

| Name  | Type      |                                                                               |
| ----- | --------- | ----------------------------------------------------------------------------- |
| **/** | `address` | The address of the current strategy: a contract that conforms to `IStrategy`. |

#### `strategyData | view`[​](https://smart-docs.vercel.app/contract#strategyData) <a href="#strategydata" id="strategydata"></a>

**Parameters**

| Name  | Type      | Description                                      |
| ----- | --------- | ------------------------------------------------ |
| **/** | `address` | The address of the token that maps to a strategy |

**Return values**

| Name                  | Type      | Description                                                           |
| --------------------- | --------- | --------------------------------------------------------------------- |
| **strategyStartDate** | `uint64`  | Timestamp of the strategy start date.                                 |
| **targetPercentage**  | `uint64`  | Current targetPercentage (% of funds wanted in strategy) of the token |
| **balance**           | `uint128` | Current balance held by strategy (before harvest)                     |

#### `toAmount | view`[​](https://smart-docs.vercel.app/contract#toAmount) <a href="#toamount" id="toamount"></a>

```solidity
function toAmount(
    IERC20 token,
    uint256 share,
    bool roundUp
) external view returns (uint256 amount)
```

Converts amounts of shares of a token into it's native representation.

**Parameters**

| Name        | Type      | Description                         |
| ----------- | --------- | ----------------------------------- |
| **token**   | `address` | The ERC-20 token.                   |
| **share**   | `uint256` | The amount of shares.               |
| **roundUp** | `bool`    | If the result should be rounded up. |

**Return values**

| Name       | Type      | Description                                       |
| ---------- | --------- | ------------------------------------------------- |
| **amount** | `uint256` | The share amount back into native representation. |

#### `toShare | view`[​](https://smart-docs.vercel.app/contract#toShare) <a href="#toshare" id="toshare"></a>

```solidity
function toShare(
    IERC20 token,
    uint256 amount,
    bool roundUp
) external view returns (uint256 share)
```

Converts amounts of a token in it's native representation into shares.

**Parameters**

| Name        | Type      | Description                                 |
| ----------- | --------- | ------------------------------------------- |
| **token**   | `address` | The ERC-20 token.                           |
| **amount**  | `uint256` | The `token` amount.                         |
| **roundUp** | `bool`    | If the result `share` should be rounded up. |

**Return values**

| Name      | Type      | Description                             |
| --------- | --------- | --------------------------------------- |
| **share** | `uint256` | The token amount represented in shares. |

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

```solidity
mapping(IERC20 => Rebase) public totals;
```

Keeps track of how many tokens are stored by DegenBox as well as how many shares are held by users.

**Parameters**

| Name  | Type      | Description                        |
| ----- | --------- | ---------------------------------- |
| **/** | `address` | ERC20 Address which total we want. |

**Return values**

| Name        | Type      |                                                                         |
| ----------- | --------- | ----------------------------------------------------------------------- |
| **elastic** | `uint128` | How many tokens (in native representation) are deposited into DegenBox. |
| **base**    | `uint128` | How many shares of tokens are held by users.                            |

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

```solidity
function transfer(
    IERC20 token,
    address from,
    address to,
    uint256 share
) public allowed(from) 
```

Transfer shares from a user account to another one.

**Parameters**

| Name      | Type      |                                       |
| --------- | --------- | ------------------------------------- |
| **token** | `address` | The ERC20 token to transfer.          |
| **from**  | `address` | The account to transfer `token` from. |
| **to**    | `address` | The account to transfer `token` to.   |
| **share** | `uint256` | The amount of shares to transfer.     |

**Return values**

No return values for this function.

#### `transferMultiple | nonpayable`[​](https://smart-docs.vercel.app/contract#transferMultiple) <a href="#transfermultiple" id="transfermultiple"></a>

```solidity
function transferMultiple(
    IERC20 token,
    address from,
    address[] calldata tos,
    uint256[] calldata shares
) public allowed(from) {
```

Transfer shares from a user account to multiple other ones.

**Parameters**

| Name       | Type        |                                                             |
| ---------- | ----------- | ----------------------------------------------------------- |
| **token**  | `address`   | The ERC20 token to transfer.                                |
| **from**   | `address`   | The account to transfer `token` from.                       |
| **tos**    | `address[]` | The accounts to transfer `token` to.                        |
| **shares** | `uint256[]` | The amount of `token` in shares for each receiver in `tos`. |

**Return values**

No return values for this function.

#### `transferOwnership | nonpayable`[​](https://smart-docs.vercel.app/contract#transferOwnership) <a href="#transferownership" id="transferownership"></a>

```solidity
function transferOwnership(
    address newOwner,
    bool direct,
    bool renounce
) public onlyOwner 
```

Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner. Can only be invoked by the current `owner`.

**Parameters**

| Name         | Type      | Description                                                                                           |
| ------------ | --------- | ----------------------------------------------------------------------------------------------------- |
| **newOwner** | `address` | Address of the new owner.                                                                             |
| **direct**   | `bool`    | True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`.      |
| **renounce** | `bool`    | Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise. |

**Return values**

No return values for this function.

#### `whitelistMasterContract | nonpayable`[​](https://smart-docs.vercel.app/contract#whitelistMasterContract) <a href="#whitelistmastercontract" id="whitelistmastercontract"></a>

<pre class="language-solidity"><code class="lang-solidity">function whitelistMasterContract(
<strong>    address masterContract, 
</strong>    bool approved
) public onlyOwner
</code></pre>

Enables or disables a contract for approval without signed message.

**Parameters**

| Name               | Type      | Description                                   |
| ------------------ | --------- | --------------------------------------------- |
| **masterContract** | `address` | masterContract which status is being changed. |
| **approved**       | `bool`    | New approval status.                          |

**Return values**

No return values for this function.

#### `whitelistedMasterContracts | view`[​](https://smart-docs.vercel.app/contract#whitelistedMasterContracts) <a href="#whitelistedmastercontracts" id="whitelistedmastercontracts"></a>

Returns True if a masterContract is whitelisted.

**Parameters**

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

**Return values**

| Name  | Type   | Description          |
| ----- | ------ | -------------------- |
| **/** | `bool` | Whitelisting status. |

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

```solidity
function withdraw(
    IERC20 token_,
    address from,
    address to,
    uint256 amount,
    uint256 share
) public allowed(from) returns (uint256 amountOut, uint256 shareOut) 
```

Withdraws an amount of `token` from a user account.

**Parameters**

| Name        | Type      | Description                                                               |
| ----------- | --------- | ------------------------------------------------------------------------- |
| **token\_** | `address` | The ERC-20 token to withdraw.                                             |
| **from**    | `address` | From which user to pull the tokens.                                       |
| **to**      | `address` | To which user to push the tokens.                                         |
| **amount**  | `uint256` | Amount of tokens. Either one of `amount` or `share` needs to be supplied. |
| **share**   | `uint256` | Like above, but `share` takes precedence over `amount`.                   |

**Return values**

| Name          | Type      | Description                                          |
| ------------- | --------- | ---------------------------------------------------- |
| **amountOut** | `uint256` | Amount of token withdrawn, in native representation. |
| **shareOut**  | `uint256` | Shares of token withdrawn.                           |

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

* [LogDeploy](#logdeploy)
* [LogDeposit](#logdeposit)
* [LogFlashLoan](#logflashloan)
* [LogRegisterProtocol](#logregisterprotocol)
* [LogSetMasterContractApproval](#logsetmastercontractapproval)
* [LogStrategyDivest](#logstrategydivest)
* [LogStrategyInvest](#logstrategyinvest)
* [LogStrategyLoss](https://smart-docs.vercel.app/contract#LogStrategyLoss)
* [LogStrategyProfit](#logstrategyprofit)
* [LogStrategyQueued](#logstrategyqueued)
* [LogStrategySet](#logstrategyset)
* [LogStrategyTargetPercentage](#logstrategytargetpercentage)
* [LogTransfer](#logtransfer)
* [LogWhiteListMasterContract](#logwhitelistmastercontract)
* [LogWithdraw](#logwithdraw)
* [OwnershipTransferred](#ownershiptransferred)

***

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

**Parameters**

| Name               | Type      | Indexed |
| ------------------ | --------- | ------- |
| **masterContract** | `address` | `true`  |
| **data**           | `bytes`   | `false` |
| **cloneAddress**   | `address` | `true`  |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **token**  | `address` | `true`  |
| **from**   | `address` | `true`  |
| **to**     | `address` | `true`  |
| **amount** | `uint256` | `false` |
| **share**  | `uint256` | `false` |

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

**Parameters**

| Name          | Type      | Indexed |
| ------------- | --------- | ------- |
| **borrower**  | `address` | `true`  |
| **token**     | `address` | `true`  |
| **amount**    | `uint256` | `false` |
| **feeAmount** | `uint256` | `false` |
| **receiver**  | `address` | `true`  |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **protocol** | `address` | `true`  |

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

**Parameters**

| Name               | Type      | Indexed |
| ------------------ | --------- | ------- |
| **masterContract** | `address` | `true`  |
| **user**           | `address` | `true`  |
| **approved**       | `bool`    | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **token**  | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **token**  | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **token**  | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **token**  | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **token**    | `address` | `true`  |
| **strategy** | `address` | `true`  |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **token**    | `address` | `true`  |
| **strategy** | `address` | `true`  |

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

**Parameters**

| Name                 | Type      | Indexed |
| -------------------- | --------- | ------- |
| **token**            | `address` | `true`  |
| **targetPercentage** | `uint256` | `false` |

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

**Parameters**

| Name      | Type      | Indexed |
| --------- | --------- | ------- |
| **token** | `address` | `true`  |
| **from**  | `address` | `true`  |
| **to**    | `address` | `true`  |
| **share** | `uint256` | `false` |

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

**Parameters**

| Name               | Type      | Indexed |
| ------------------ | --------- | ------- |
| **masterContract** | `address` | `true`  |
| **approved**       | `bool`    | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **token**  | `address` | `true`  |
| **from**   | `address` | `true`  |
| **to**     | `address` | `true`  |
| **amount** | `uint256` | `false` |
| **share**  | `uint256` | `false` |

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

**Parameters**

| Name                 | Type      | Indexed |
| -------------------- | --------- | ------- |
| clo**previousOwner** | `address` | `true`  |
| **newOwner**         | `address` | `true`  |


# BentoBox

Sushi's instance of the bentoBox, owned by the Sushi Multisig.

## BentoBox

The BentoBox is a vault for tokens. The stored tokens can be flashloaned or used in strategies - the yield from this will go to the token depositors.

You can find the full contract [here](https://github.com/sushiswap/sushiswap/blob/master/protocols/bentobox/v1/contracts/BentoBox.sol).

***Warning:*** Rebasing tokens are **NOT** supported and **WILL** cause a loss of funds!

Please do not send funds directly to either BentoBox or Degenbox as they will be lost! Use the "Deposit" function instead!

### Functions

#### \_tokenBalanceOf

```solidity
function _tokenBalanceOf(IERC20 token) internal view returns (uint256 amount)
```

Internal function that returns the balance of `token` this contract holds, plus the total amount this contract thinks the strategy holds.

**Parameters**

| Name    | Type   | Description                         |
| ------- | ------ | ----------------------------------- |
| `token` | IERC20 | address of ERC20 token to represent |

#### toShare

```solidity
function toShare(
        IERC20 token,
        uint256 amount,
        bool roundUp
    ) external view returns (uint256 share)
```

Helper function to represent an amount of token in shares.

**Parameters**

| Name      | Type    | Description                              |
| --------- | ------- | ---------------------------------------- |
| `token`   | IERC20  | address of ERC20 token to represent      |
| `amount`  | uint256 | amount of aforementioned ERC20 token     |
| `roundUp` | bool    | if the result share should be rounded up |

#### toAmount

```solidity
function toAmount(
        IERC20 token,
        uint256 share,
        bool roundUp
    ) external view returns (uint256 amount)
```

Helper function to represent shares back into token amount.

**Parameters**

| Name      | Type    | Description                               |
| --------- | ------- | ----------------------------------------- |
| `token`   | IERC20  | address of ERC20 token to represent       |
| `share`   | uint256 | amount of shares                          |
| `roundUp` | bool    | if the result amount should be rounded up |

#### deposit

```solidity
function deposit(
        IERC20 token_,
        address from,
        address to,
        uint256 amount,
        uint256 share
    ) public payable allowed(from) returns (uint256 amountOut, uint256 shareOut)
```

Deposit an amount of token represented in either amount or share.

**Parameters**

| Name     | Type    | Description                                                                  |
| -------- | ------- | ---------------------------------------------------------------------------- |
| `token`  | IERC20  | address of ERC20 token to deposit                                            |
| `from`   | address | address of account to pull the tokens from                                   |
| `to`     | address | address of account to push the tokens to                                     |
| `amount` | uint256 | token amount in native representation to deposit                             |
| `share`  | uint256 | token amount represented in shares to deposit, takes precendence over amount |

**Returns**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| `amountOut` | uint256 | amount deposited                       |
| `shareOut`  | uint256 | deposited amount represented in shares |

#### withdraw

```solidity
 function withdraw(
        IERC20 token_,
        address from,
        address to,
        uint256 amount,
        uint256 share
    ) public allowed(from) returns (uint256 amountOut, uint256 shareOut)
```

Withdraws an amount of token from a user account.

**Parameters**

| Name     | Type    | Description                                                                        |
| -------- | ------- | ---------------------------------------------------------------------------------- |
| `token`  | IERC20  | address of ERC20 token to withdraw                                                 |
| `from`   | address | address of account to pull the tokens from                                         |
| `to`     | address | address of account to push the tokens to                                           |
| `amount` | uint256 | token amount in native representation to deposit (must supply `amount` or `share`) |
| `share`  | uint256 | token amount represented in shares to deposit, takes precendence over amount       |

**Returns**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| `amountOut` | uint256 | amount withdrawn                       |
| `shareOut`  | uint256 | withdrawn amount represented in shares |

#### transfer

```solidity
 function transfer(
        IERC20 token,
        address from,
        address to,
        uint256 share
    ) public allowed(from)
```

Transfer shares from a user account to another one.

**Parameters**

| Name    | Type    | Description                                |
| ------- | ------- | ------------------------------------------ |
| `token` | IERC20  | address of ERC20 token to transfer         |
| `from`  | address | address of account to pull the tokens from |
| `to`    | address | address of account to push the tokens to   |
| `share` | uint256 | token amount represented in shares         |

#### transferMultiple

```solidity
function transferMultiple(
        IERC20 token,
        address from,
        address[] calldata tos,
        uint256[] calldata shares
    ) public allowed(from)
```

Transfer shares from a user account to *multiple other ones.*

**Parameters**

| Name     | Type                | Description                                                   |
| -------- | ------------------- | ------------------------------------------------------------- |
| `token`  | IERC20              | address of ERC20 token to transfer                            |
| `from`   | address             | address of account to pull the tokens from                    |
| `tos`    | address\[] calldata | addresses of the receivers of the tokens                      |
| `shares` | uint256\[] calldata | token amount represented in shares for each receiver in `tos` |

#### flashLoan

```solidity
function flashLoan(
        IFlashBorrower borrower,
        address receiver,
        IERC20 token,
        uint256 amount,
        bytes calldata data
    ) public
```

Provides flash loan capabilities.

**Parameters**

| Name       | Type           | Description                                                                                            |
| ---------- | -------------- | ------------------------------------------------------------------------------------------------------ |
| `borrower` | IFlashBorrower | the address of the contract that implements and conforms to `IFlashBorrower` and handles the flashloan |
| `receiver` | address        | address of the token receiver                                                                          |
| `token`    | IERC20         | address of the token to receive                                                                        |
| `amount`   | uint256        | amount of tokens to receive                                                                            |
| `data`     | bytes          | the calldata to pass to the `borrower` contract                                                        |

#### batchFlashLoan

```solidity
 function batchFlashLoan(
        IBatchFlashBorrower borrower,
        address[] calldata receivers,
        IERC20[] calldata tokens,
        uint256[] calldata amounts,
        bytes calldata data
    ) public
```

Support for batched flashloans; useful to request multiple different tokens in a single transaction.

**Parameters**

| Name        | Type                | Description                                                                                                 |
| ----------- | ------------------- | ----------------------------------------------------------------------------------------------------------- |
| `borrower`  | IBatchFlashBorrower | the address of the contract that implements and conforms to `IBatchFlashBorrower` and handles the flashloan |
| `receivers` | address\[]          | array of addresses of the token receivers                                                                   |
| `tokens`    | IERC20\[]           | addresses of the tokens                                                                                     |
| `amounts`   | uint256\[]          | amounts of the tokens for each receiver                                                                     |
| `data`      | bytes               | the calldata to pass to the `borrower` contract                                                             |

#### setStrategyTargetPercentage

```solidity
function setStrategyTargetPercentage(IERC20 token, uint64 targetPercentage_) public onlyOwner
```

Sets the target percentage of the strategy for `token`. Can only be called by the owner of the contract.

**Parameters**

| Name                | Type   | Description                                                                   |
| ------------------- | ------ | ----------------------------------------------------------------------------- |
| `token`             | IERC20 | address of ERC20 token that maps to a strategy to change                      |
| `targetPercentage_` | uint64 | the new target in percent, must be lesser or equal to `MAX_TARGET_PERCENTAGE` |

#### setStrategy

```solidity
function setStrategy(IERC20 token, IStrategy newStrategy) public onlyOwner
```

Sets the contract address of a new strategy that conforms to `IStrategy` for `token` (must be called twice with the same arguments). Can only be called by the owner of the contract.

**Parameters**

| Name          | Type      | Description                                              |
| ------------- | --------- | -------------------------------------------------------- |
| `token`       | IERC20    | address of ERC20 token that maps to a strategy to change |
| `newStrategy` | IStrategy | address of the contract that conforms to `IStrategy`     |

#### harvest

```solidity
function harvest(
        IERC20 token,
        bool balance,
        uint256 maxChangeAmount
    ) public
```

Executes the strategy of `token` - ie, the actual process of yield farming. Optionally does housekeeping if `balance` is true.

**Parameters**

| Name              | Type    | Description                                                                       |
| ----------------- | ------- | --------------------------------------------------------------------------------- |
| `token`           | IERC20  | address of ERC20 token for which a strategy is deployed                           |
| `balance`         | bool    | true if housekeeping should be done                                               |
| `maxChangeAmount` | uint256 | the maximum amount for either pulling or pushing from/to the `IStrategy` contract |


# Cauldrons

Abracadabra's isolated markets


# Cauldron V1

The first version of the cauldron, not used in production anymore.

This is the first version of the Cauldron Contracts. 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/CauldronMediumRiskV1.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

### 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. |

### 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. |


# 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.\
*eg: 75000 = 75%*

### LIQUIDATION\_MULTIPLIER

Returns the liquidation fee in Basis Points.\
*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. |


# Cauldron V3

Third version of the cauldrons, implementing the following changes:

* Dynamic Interest Rate
* Borrow Limit (per user & global)
* Liquidations emit an event
* exchangeRate is automatically updated before solvency checks.

Functions starting with '✨' are new in V3.

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/contracts/CauldronV3.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 |

### ✨ changeBorrowLimit[​](https://smart-docs.vercel.app/contract#changeBorrowLimit) | <mark style="background-color:red;">New in V3</mark> <a href="#changeborrowlimit" id="changeborrowlimit"></a>

```solidity
function changeBorrowLimit(
        uint128 newBorrowLimit, 
        uint128 perAddressPart
    ) public onlyMasterContractOwner {
```

Allows MasterContractOwner to change the borrow limits of the cauldron, both globally and per user.

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **newBorrowLimit** | `uint128` |
| **perAddressPart** | `uint128` |

### ✨ changeInterestRate | <mark style="background-color:red;">New in V3</mark> <a href="#changeinterestrate" id="changeinterestrate"></a>

```solidity
function changeInterestRate(uint64 newInterestRate) public onlyMasterContractOwner {
```

Allows MasterContractOwner to change the interest rate of the Cauldron.\
The rate can only be change every 3 days\
The newInterestRate can't be bigger than 175% of the old rate (the rate can't increase by more than 75% at the time)\
If rate was 0%, the rate can be increased to 1%, the previous rule then applies.

**Parameters**

| Name                | Type     | Description       |
| ------------------- | -------- | ----------------- |
| **newInterestRate** | `uint64` | New Interest rate |

### 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>

Available actions and their ID:

```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.\
*eg: 75000 = 75%*

### LIQUIDATION\_MULTIPLIER

Returns the liquidation fee in Basis Points.\
*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> |

### ✨ borrowLimit | <mark style="background-color:red;">new in V3</mark> <a href="#borrowlimit" id="borrowlimit"></a>

Returns the current borrowLimit, expressed in borrowParts at the cauldron level and at the address level.

**Return values**

| Name                     | Type      | Description                              |
| ------------------------ | --------- | ---------------------------------------- |
| **total**                | `uint128` | Max total borrow parts for the cauldron. |
| **borrowPartPerAddress** | `uint128` | Max total borrow parts per user.         |

### 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. |


# Cauldron V3\_2

An update to the V3 cauldron changing the way swappers work

The Cauldron V3\_2 is an incremental update to the V3 cauldron enabling the use of more powerful swappers, compatible with aggregators, like 0x.

The new `SwapperV2` need calldata given by the aggregator to work and therefore ask this as an input on the liquidate function, which uses a swapper.

### ✨ liquidate | <mark style="background-color:red;">Updated in V3\_2</mark> <a href="#liquidate" id="liquidate"></a>

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

**Parameters**

| Name               | Type        |                                                                                                                   |
| ------------------ | ----------- | ----------------------------------------------------------------------------------------------------------------- |
| **users**          | `address[]` | Array of user addresses                                                                                           |
| **maxBorrowParts** | `uint256[]` | A 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**        | `address`   | Address of the swapper, conforming to ISwapperV2.                                                                 |
| **swapperData**    | `bytes`     | CallData to be passed to the swapper.                                                                             |

\\


# Whitelisted CauldronV3

An update to the V3 cauldron adding a whitelist

Whitelisted CauldronV3 is an update of the V3 cauldron that allows Abracadabra to whitelist certain addresses to borrow up to a certain amount.\
It uses a Whitelister contract that contains the root hash of a merkleTree of addresses and amounts and once called with the correct proof, stores the maxBorrow amount, for the cauldron to check against while borrowing.

You can find the full contract of the cauldron [here](https://github.com/Abracadabra-money/magic-internet-money/blob/main/contracts/WhitelistedCauldronV3.sol) and of the whitelister [here](https://github.com/Abracadabra-money/magic-internet-money/blob/main/contracts/Whitelister.sol).

### ✨ changeWhitelister | <mark style="background-color:green;">Specific to Whitelisted</mark> <a href="#changewhitelister" id="changewhitelister"></a>

```solidity
    function changeWhitelister(IWhitelister newWhiteLister) public onlyMasterContractOwner
```

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **newWhiteLister** | `address` |

\\


# Cauldron V4

Forth version of the cauldrons, implementing the following changes:

* Blacklisted Callees, allowing owner to block cauldron calls to some specific addresses.
* RepayForAll, allowing the repayment of debt to all user proportionally to the borrowPart owned.
* Ability to release funds from Strategy and redeposit them afterwards. (if bentoBox is owned by bentoBoxOwner contract)
* Liquidations can happen as part of cook().

Functions starting with '✨' are new in V4.

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/contracts/CauldronV3.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 |

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

```solidity
function changeBorrowLimit(
        uint128 newBorrowLimit, 
        uint128 perAddressPart
    ) public onlyMasterContractOwner {
```

Allows MasterContractOwner to change the borrow limits of the cauldron, both globally and per user.

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **newBorrowLimit** | `uint128` |
| **perAddressPart** | `uint128` |

### changeInterestRate <a href="#changeinterestrate" id="changeinterestrate"></a>

```solidity
function changeInterestRate(uint64 newInterestRate) public onlyMasterContractOwner {
```

Allows MasterContractOwner to change the interest rate of the Cauldron.\
The rate can only be change every 3 days\
The newInterestRate can't be bigger than 175% of the old rate (the rate can't increase by more than 75% at the time)\
If rate was 0%, the rate can be increased to 1%, the previous rule then applies.

**Parameters**

| Name                | Type     | Description       |
| ------------------- | -------- | ----------------- |
| **newInterestRate** | `uint64` | New Interest rate |

### 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><tr><td>ACTION_LIQUIDATE</td><td>31</td><td>users, maxBorrowParts, to, swapper, swapperData</td><td>address[], uint265[], address, ISwapperV2, bytes</td><td></td></tr><tr><td>ACTION_RELEASE_COLLATERAL_FROM_STRATEGY</td><td>33</td><td></td><td></td><td></td></tr></tbody></table>

Available actions and their ID:

```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;
    uint8 internal constant ACTION_LIQUIDATE = 31;
    uint8 internal constant ACTION_RELEASE_COLLATERAL_FROM_STRATEGY = 33;

    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) |

### ✨ repayForAll​ | <mark style="background-color:red;">New in V4</mark> <a href="#repayforall" id="repayforall"></a>

**Parameters**

| Name       | Type      |                                                    |
| ---------- | --------- | -------------------------------------------------- |
| **amount** | `uint128` | Amount of MIM to repay.                            |
| **skim**   | `bool`    | Ignore amount and take every mim in this contract. |

**Return values**

| Name  | Type      | Description    |
| ----- | --------- | -------------- |
| **/** | `uint128` | Amount repaid. |

### ✨ setBlacklistedCallee | <mark style="background-color:red;">New in V4</mark> <a href="#setblacklistedcallee" id="setblacklistedcallee"></a>

**Parameters**

| Name            | Type      | Description                                |
| --------------- | --------- | ------------------------------------------ |
| **callee**      | `address` | Address of the callee                      |
| **blacklisted** | `bool`    | new blacklist status. True if blacklisted. |

## 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.\
*eg: 75000 = 75%*

### LIQUIDATION\_MULTIPLIER

Returns the liquidation fee in Basis Points.\
*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> |

### ✨ blacklistedCallees | <mark style="background-color:red;">New in V4</mark> <a href="#blacklistedcallees" id="blacklistedcallees"></a>

**Parameters**

| Name  | Type      | Description           |
| ----- | --------- | --------------------- |
| **/** | `address` | Address of the callee |

**Return values**

| Name  | Type   | Description                            |
| ----- | ------ | -------------------------------------- |
| **/** | `bool` | Blacklist status. True if blacklisted. |

### borrowLimit <a href="#borrowlimit" id="borrowlimit"></a>

Returns the current borrowLimit, expressed in borrowParts at the cauldron level and at the address level.

**Return values**

| Name                     | Type      | Description                              |
| ------------------------ | --------- | ---------------------------------------- |
| **total**                | `uint128` | Max total borrow parts for the cauldron. |
| **borrowPartPerAddress** | `uint128` | Max total borrow parts per user.         |

### 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. |


# PrivilegedCauldronV4

A modified version of V4 allowing the creation of debt by owner

Priviledged CauldronV4 is a modified of the V4 cauldron that allows Abracadabra to create debt on behalf of the user.\
It was used during migration of 2 cauldrons to transfer a user position to this new cauldron

You can find the full contract of the cauldron [here](https://github.com/Abracadabra-money/abracadabra-money-foundry/blob/main/src/cauldrons/PrivilegedCauldronV4.sol).

### ✨ addBorrowPosition | <mark style="background-color:green;">Specific to Privileged</mark> <a href="#changewhitelister" id="changewhitelister"></a>

This function allows the masterContractOwner to create a debt position to a user.

```solidity
function addBorrowPosition(address to, uint256 amount) external onlyMasterContractOwner returns (uint256 part)
```

**Parameters**

| Name       | Type      |
| ---------- | --------- |
| **to**     | `address` |
| **amount** | `uint256` |


# GmxV2 CauldronV4

Cauldrons supporting GMX V2 GM Markets

The GMXV2 Cauldron V4 is a customized version of Cauldron V4. The custom part stems from GMXV2's deposits and withdrawals lacking atomicity. In order to still be able to safely interact with GM Markets, the Cauldron V4 has been adapted in a few key aspects:

* An OrderAgent contract will create an orderRouter proxy contracts specific to the user, for each interaction with GMX. This contract will send the deposit order to GMX, receive the GM tokens from GMX and send them back to the cauldron via a callback function called by GMX's DepositHandler, with the opposite happening for withdrawals.
* The Cauldron's solvency check is updated to take into account a pending order in the Proxy, on top of the regular collateral (whether the order succeeds and becomes GM tokens or fails remains as USDC in the order, it is collateral that is backing MIM)
* The Liquidation process is updated to take into account the orderProxy's state, closing open-orders and retrieving USDC from the orderProxy back to the Cauldron.

You can find the full contract code [here](https://github.com/Abracadabra-money/abracadabra-money-contracts/blob/main/src/cauldrons/GmxV2CauldronV4.sol).

## GmxV2 CauldronV4

***

### ✨ setOrderAgent | <mark style="background-color:green;">New in GmxV2 CauldronV4</mark>

This function sets the order agent for the contract. `function setOrderAgent(IGmCauldronOrderAgent _orderAgent) public onlyMasterContractOwner`

**Parameters**

| Name          | Type                    | Note                        |
| ------------- | ----------------------- | --------------------------- |
| `_orderAgent` | `IGmCauldronOrderAgent` | The new order agent to set. |

***

### ♻️ \_isSolvent | <mark style="background-color:yellow;">updated for GmxV2 CauldronV4</mark>

Concrete implementation of `isSolvent`. Includes a second parameter to allow caching `exchangeRate`.

```solidity
function _isSolvent(address user, uint256 _exchangeRate) internal view override returns (bool)
```

It is updated in the GmxV2 CauldronV4 contract to take into account the value of the open order to the solvency check.\
This is because during the leverage cycle, we will borrow MIM and then create an order, that will be filled by another transaction. For the first transaction to suceed, it needs to pass the solvency check and therefore the check includes the value of the newly created order.

***

### ♻️ \_additionalCookAction | <mark style="background-color:yellow;">updated for GmxV2 CauldronV4</mark>

Adds 3 new cook actions to the cook() function, allowing them to be called as part of an atomic bundle of different steps.

* ACTION\_WITHDRAW\_FROM\_ORDER: Makes sure an order exists, then calls `withdrawFromOrder` on it.\
  Used during deleverages after GMX sent the USDC back to the order.
* ACTION\_CREATE\_ORDER: Makes sure no order exists, then creates one with the decoded parameters using `orderAgent.createOrder`.\
  Used for leverages or deleverages in order to interact with GMX.
* ACTION\_CANCEL\_ORDER: Makes sure an order exists, then calls cancelOrder() to cancel it.\
  Used when the order failed to restart the process from scratch or during liquidations when an order is in progress.

***

### ♻️ liquidate | <mark style="background-color:yellow;">updated for GmxV2 CauldronV4</mark>

Handles the liquidation of users' balances when their amount of collateral is too low. `function liquidate(address[] memory users, uint256[] memory maxBorrowParts, address to, ISwapperV2 swapper, bytes memory swapperData) public virtual override`

**Parameters**

| Name             | Type               | Note                                          |
| ---------------- | ------------------ | --------------------------------------------- |
| `users`          | `address[] memory` | Array of user addresses.                      |
| `maxBorrowParts` | `uint256[] memory` | Maximum borrow parts for each user.           |
| `to`             | `address`          | Receiver address in open liquidations.        |
| `swapper`        | `ISwapperV2`       | Swapper contract address.                     |
| `swapperData`    | `bytes memory`     | <p>Additional data for</p><p>the swapper.</p> |

This function has been updated to cancel any open order and sending the short token (USDC) back to the liquidator.

***

### ✨ closeOrder | <mark style="background-color:green;">new in GmxV2 CauldronV4</mark>

Closes an order for a given user. Only callable by the order itself.\
This makes the user's order address 0x0\[…] effectively closing it, and removes it from the mapping of blacklisted callees.\
Newer orders for this same user will be a handled by a new order address.

```solidity
function closeOrder(address user) public
```

**Parameters**

| Name   | Type      | Note                 |
| ------ | --------- | -------------------- |
| `user` | `address` | Address of the user. |

## GmxV2 OrderAgent & RouterOrder

The GmxV2CauldronV4 relies on an OrderAgent and RouterOrders. More information about these periphery contracts bellow:

{% content-ref url="/pages/WMYgOEBHotqadpAPZMyp" %}
[GMX V2 OrderAgent & RouterOrder](/periphery-contracts/gmx-v2-orderagent-and-routerorder)
{% endcontent-ref %}


# Liquidations

The `liquidate` function is a critical component of the Abracadabra cauldron. This function allows liquidators to handle the liquidation of users' balances when the users' amount of collateral is too low.

### Function Signature

```solidity
function liquidate(
    address[] memory users,
    uint256[] memory maxBorrowParts,
    address to,
    ISwapperV2 swapper,
    bytes memory swapperData
) public;
```

#### Parameters

* `users`: An array of user addresses that need to be liquidated.
* `maxBorrowParts`: A one-to-one mapping to `users`. It contains the maximum (partial) borrow amounts (to liquidate) for each respective user.
* `to`: The address of the receiver in open liquidations if the `swapper` is zero.
* `swapper`: An instance of the `ISwapperV2` interface to perform the actual swap operation.
* `swapperData`: Additional data to be passed to the swapper.

### How Liquidation Works

1. The function begins by updating the exchange rate and calling the `accrue` function.
2. It initializes variables to store the total collateral shares, borrow amounts, and borrow parts.
3. The function iterates through each user and checks if they are solvent, i.e., their collateral is sufficient. If not, it proceeds with the liquidation process.
4. For each insolvent user, the function calculates their borrow part, borrow amount, and collateral share. It updates the user's borrow part and collateral share accordingly.
5. It emits events for removing collateral, repaying loans, and liquidation.
6. The function keeps track of the totals for collateral shares, borrow amounts, and borrow parts.
7. After processing all users, the function checks if at least one user was insolvent, otherwise, it reverts.
8. The function updates the total borrow elastic and base values, as well as the total collateral shares.
9. It calculates a distribution amount to share with sSpell holders as a percentage of the liquidation amount.
10. The function converts the total borrow amount to borrow shares.
11. The bentoBox transfers the collateral to the `to` address.
12. If a swapper is provided, the function calls the `swap` function of the swapper to perform the actual swap operation, providing the collateral and borrow shares.
13. The bentoBox transfers the magicInternetMoney (borrow asset) to the msg.sender (liquidator).

### Events

* `LogRemoveCollateral`: Emitted when collateral is removed from the user's account.
* `LogRepay`: Emitted when a user's borrow is repaid.
* `LogLiquidation`: Emitted when a liquidation occurs.

\\


# Proxy Oracles

Oracles enable cauldrons to price the collateral and are a crucial part of the abracadabra infrastructure. Each cauldron has it's own oracle. Abracadabra uses proxy oracles with the Abracadabra Multisig as an owner, to upgrade the oracle implementation if it was to become deprecated, maintaining high levels of security.

Abracadabra uses a variety of Oracle providers depending on chains and assets. The exact oracle can always verified using the oracle() function of the Cauldron. Those oracles include:

* [Chainlink](https://chain.link/)
* [Redstone](https://redstone.finance/)

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

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

**Parameters**

No parameters found in the constructor.

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

* [changeOracleImplementation](#changeoracleimplementation)
* [claimOwnership](#claimownership)
* [get](#get)
* [name](#name)
* [oracleImplementation](#oracleimplementation)
* [owner](#owner)
* [peek](#peek)
* [peekSpot](#peekspot)
* [pendingOwner](#pendingowner)
* [symbol](#symbol)
* [transferOwnership](#transferownership)

***

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

**Parameters**

| Name          | Type      |
| ------------- | --------- |
| **newOracle** | `address` |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name     | Type    |
| -------- | ------- |
| **data** | `bytes` |

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `bool`    |
| **/** | `uint256` |

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

**Parameters**

| Name  | Type    |
| ----- | ------- |
| **/** | `bytes` |

**Return values**

| Name  | Type     |
| ----- | -------- |
| **/** | `string` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name     | Type    |
| -------- | ------- |
| **data** | `bytes` |

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `bool`    |
| **/** | `uint256` |

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

**Parameters**

| Name     | Type    |
| -------- | ------- |
| **data** | `bytes` |

**Return values**

| Name     | Type      |
| -------- | --------- |
| **rate** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name  | Type    |
| ----- | ------- |
| **/** | `bytes` |

**Return values**

| Name  | Type     |
| ----- | -------- |
| **/** | `string` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **newOwner** | `address` |
| **direct**   | `bool`    |
| **renounce** | `bool`    |

**Return values**

No return values for this function.

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

* [LogOracleImplementationChange](https://smart-docs.vercel.app/contract#LogOracleImplementationChange)
* [OwnershipTransferred](https://smart-docs.vercel.app/contract#OwnershipTransferred)

***

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

**Parameters**

| Name          | Type      | Indexed |
| ------------- | --------- | ------- |
| **oldOracle** | `address` | `true`  |
| **newOracle** | `address` | `true`  |

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

**Parameters**

| Name              | Type      | Indexed |
| ----------------- | --------- | ------- |
| **previousOwner** | `address` | `true`  |
| **newOwner**      | `address` | `true`  |


# Strategies

Strategies take an investment from the DegenBox and manage a yield generating operation. The DegenBox owner sets a strategy per token, the owner also determines how much of the token balance is going to be in the strategy (the strategy "target percentage") and how much remains in the DegenBox to enable withdrawals.

Because the funds should be able to be sent back to the DegenBox instantly, the harvest function, which can also rebalance to bring the invested amount to the defined target percentage, can be called by anyone.

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

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

**Parameters**

| Name                | Type      |
| ------------------- | --------- |
| **\_strategyToken** | `address` |
| **\_bentoBox**      | `address` |

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

* [bentoBox](#bentobox)
* [exit](#exit)
* [exited](#exited)
* [feeCollector](#feecollector)
* [feePercent](#feepercent)
* [harvest](#harvest)
* [maxBentoBoxBalance](#maxbentoboxbalance)
* [owner](#owner)
* [pendingOwner](#pendingowner)
* [resetAllowance](#resetallowance)
* [rewardTokenEnabled](#rewardtokenenabled)
* [safeHarvest](#safeharvest)
* [setFeeParameters](#setfeeparameters)
* [setRewardTokenEnabled](#setrewardtokenenabled)
* [setStrategyExecutor](#setstrategyexecutor)
* [setSwapper](#setswapper)
* [skim](#skim)
* [strategyExecutors](#strategyexecutors)
* [strategyToken](#strategytoken)
* [swapRewards](#swaprewards)
* [swapper](#swapper)
* [tag](#tag)
* [transferOwnership](#transferownership)
* [withdraw](#withdraw)

***

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

**Parameters**

| Name      | Type      |
| --------- | --------- |
| **to**    | `address` |
| **value** | `uint256` |
| **data**  | `bytes`   |

**Return values**

| Name        | Type   |
| ----------- | ------ |
| **success** | `bool` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name        | Type      |
| ----------- | --------- |
| **balance** | `uint256` |

**Return values**

| Name            | Type     |
| --------------- | -------- |
| **amountAdded** | `int256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type    |
| ----- | ------- |
| **/** | `uint8` |

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

**Parameters**

| Name        | Type      |
| ----------- | --------- |
| **balance** | `uint256` |
| **sender**  | `address` |

**Return values**

| Name  | Type     |
| ----- | -------- |
| **/** | `int256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

| Name                | Type      |
| ------------------- | --------- |
| **maxBalance**      | `uint256` |
| **rebalance**       | `bool`    |
| **maxChangeAmount** | `uint256` |
| **harvestRewards**  | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **\_feeCollector** | `address` |
| **\_feePercent**   | `uint8`   |

**Return values**

No return values for this function.

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

**Parameters**

| Name        | Type      |
| ----------- | --------- |
| **token**   | `address` |
| **enabled** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **executor** | `address` |
| **value**    | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name          | Type      |
| ------------- | --------- |
| **\_swapper** | `address` |

**Return values**

No return values for this function.

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

**Parameters**

| Name       | Type      |
| ---------- | --------- |
| **amount** | `uint256` |

**Return values**

No return values for this function.

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name             | Type      |
| ---------------- | --------- |
| **amountOutMin** | `uint256` |
| **rewardToken**  | `address` |
| **data**         | `bytes`   |

**Return values**

| Name          | Type      |
| ------------- | --------- |
| **amountOut** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **newOwner** | `address` |
| **direct**   | `bool`    |
| **renounce** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name       | Type      |
| ---------- | --------- |
| **amount** | `uint256` |

**Return values**

| Name             | Type      |
| ---------------- | --------- |
| **actualAmount** | `uint256` |

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

* [FeeChanged](#feechanged)
* [LogSetStrategyExecutor](#logsetstrategyexecutor)
* [OwnershipTransferred](#ownershiptransferred)
* [RewardSwapped](#rewardswapped)
* [RewardTokenUpdated](#rewardtokenupdated)
* [SwapperChanged](#swapperchanged)

***

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

**Parameters**

| Name                     | Type      | Indexed |
| ------------------------ | --------- | ------- |
| **previousFee**          | `uint256` | `false` |
| **newFee**               | `uint256` | `false` |
| **previousFeeCollector** | `address` | `false` |
| **newFeeCollector**      | `address` | `false` |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **executor** | `address` | `true`  |
| **allowed**  | `bool`    | `false` |

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

**Parameters**

| Name              | Type      | Indexed |
| ----------------- | --------- | ------- |
| **previousOwner** | `address` | `true`  |
| **newOwner**      | `address` | `true`  |

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

**Parameters**

| Name          | Type      | Indexed |
| ------------- | --------- | ------- |
| **token**     | `address` | `false` |
| **total**     | `uint256` | `false` |
| **amountOut** | `uint256` | `false` |
| **feeAmount** | `uint256` | `false` |

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

**Parameters**

| Name        | Type      | Indexed |
| ----------- | --------- | ------- |
| **token**   | `address` | `false` |
| **enabled** | `bool`    | `false` |

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

**Parameters**

| Name           | Type      | Indexed |
| -------------- | --------- | ------- |
| **oldSwapper** | `address` | `false` |
| **newSwapper** | `address` | `false` |


# MIMSwap

### Overview

MIMSwap is a decentralized automated market maker (AMM) designed for creating and managing liquidity pools. This documentation provides a detailed guide on the MIMSwap Router, MagicLP liquidity pools, and integration steps for third-party applications. MIMSwap is based off of Dodo DSP v2, complementary information can be found in [Dodo's documentation](https://docs.dodoex.io/en/developer/contracts/dodo-v1-v2/dodo-v1-v2-integration-guide#pool-address-retrieval).

### MagicLP Liquidity Pools

#### Introduction

MagicLP liquidity pools are the core components of the MIMSwap system. They facilitate token swaps, liquidity provision, and yield generation. This section focuses on the MagicLP contract, detailing how it works, how to interact with it directly, and how the MIMSwap Router leverages its functionalities.

#### Key Functions in MagicLP

1. **Swapping Tokens**
   * `sellBase`
   * `sellQuote`
2. **Adding Liquidity**
   * `buyShares`
3. **Removing Liquidity**
   * `sellShares`
4. **Query Functions**
   * `querySellBase`
   * `querySellQuote`

#### Swapping Tokens

**`sellBase`**

This function sells base tokens (e.g., MIM) for quote tokens (e.g., USDC).

```solidity
function sellBase(address to) external nonReentrant onlyClones whenNotPaused returns (uint256 receiveQuoteAmount)
```

**Process:**

1. **Balance Calculation**: Calculates the base tokens received.
2. **Query**: Uses `querySellBase` to determine the amount of quote tokens to send in return.
3. **Transfer**: Transfers the calculated quote tokens to the recipient.
4. **Update Reserves**: Updates the pool reserves.

**Example Usage:**

```solidity
address mim = 0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A;
address usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address lp = '0xPoolAddress'; // Address of the MagicLP pool
address to = msg.sender; // Recipient address
uint256 amountIn = 100 * 1e18; // Amount of base tokens (MIM) to sell

// Query the expected amount of quote tokens (USDC)
(uint256 receiveQuoteAmount, uint256 mtFee) = IMagicLP(lp).querySellBase(to, amountIn);

// Execute the sell
IMagicLP(lp).sellBase(to);
```

**`sellQuote`**

This function sells quote tokens (e.g., USDC) for base tokens (e.g., MIM).

```solidity
function sellQuote(address to) external nonReentrant onlyClones whenNotPaused returns (uint256 receiveBaseAmount)
```

**Process:**

1. **Balance Calculation**: Calculates the quote tokens received.
2. **Query**: Uses `querySellQuote` to determine the amount of base tokens to send in return.
3. **Transfer**: Transfers the calculated base tokens to the recipient.
4. **Update Reserves**: Updates the pool reserves.

**Example Usage:**

```solidity
address mim = 0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A;
address usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address lp = '0xPoolAddress'; // Address of the MagicLP pool
address to = msg.sender; // Recipient address
uint256 amountIn = 100 * 1e6; // Amount of quote tokens (USDC) to sell

// Query the expected amount of base tokens (MIM)
(uint256 receiveBaseAmount, uint256 mtFee) = IMagicLP(lp).querySellQuote(to, amountIn);

// Execute the sell
IMagicLP(lp).sellQuote(to);
```

#### Adding Liquidity

**`buyShares`**

This function allows users to provide liquidity to the pool in exchange for LP tokens.

```solidity
function buyShares(address to) external nonReentrant onlyClones whenNotPaused returns (uint256 shares, uint256 baseInput, uint256 quoteInput)
```

**Process:**

1. **Balance Calculation**: Calculates the base and quote tokens added to the pool.
2. **Share Calculation**: Determines the number of LP tokens to mint based on the input tokens.
3. **Minting**: Mints the LP tokens and sends them to the specified address.
4. **Update Reserves**: Updates the pool reserves.

**Example Usage:**

```solidity
address mim = 0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A;
address usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address lp = '0xPoolAddress'; // Address of the MagicLP pool
address to = msg.sender; // Recipient address
uint256 baseInAmount = 500 * 1e18; // Amount of base tokens (MIM) to add
uint256 quoteInAmount = 500 * 1e6; // Amount of quote tokens (USDC) to add

// Provide liquidity and get LP tokens
IMagicLP(lp).buyShares(to);
```

#### Removing Liquidity

**`sellShares`**

This function allows users to redeem their LP tokens for the underlying base and quote tokens.

```solidity
function sellShares(uint256 shareAmount, address to, uint256 baseMinAmount, uint256 quoteMinAmount, bytes calldata data, uint256 deadline) external nonReentrant onlyClones whenNotPaused returns (uint256 baseAmount, uint256 quoteAmount)
```

**Process:**

1. **Share Calculation**: Determines the amount of base and quote tokens to return based on the LP tokens being redeemed.
2. **Transfer**: Transfers the base and quote tokens to the specified address.
3. **Burning**: Burns the redeemed LP tokens.
4. **Update Reserves**: Updates the pool reserves.

**Example Usage:**

```solidity
address mim = 0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A;
address usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address lp = 0xPoolAddress; // Address of the MagicLP pool
address to = msg.sender; // Recipient address
uint256 sharesIn = 1e18; // Amount of LP tokens to redeem

// Redeem LP tokens for underlying assets
IMagicLP(lp).sellShares(sharesIn, to, 400 * 1e18, 400 * 1e6, "", block.timestamp + 300);
```

#### Query Functions

**`querySellBase`**

Returns the amount of quote tokens received for selling a specified amount of base tokens.

```solidity
function querySellBase(address trader, uint256 payBaseAmount) public view returns (uint256 receiveQuoteAmount, uint256 mtFee)
```

**Usage:**

```solidity
address mim = 0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A;
address usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address lp = 0xPoolAddress; // Address of the MagicLP pool
address trader = msg.sender; // Trader address
uint256 payBaseAmount = 100 * 1e18; // Amount of base tokens (MIM) to sell

// Get the expected quote tokens (USDC)
(uint256 receiveQuoteAmount, uint256 mtFee) = IMagicLP(lp).querySellBase(trader, payBaseAmount);
```

**`querySellQuote`**

Returns the amount of base tokens received for selling a specified amount of quote tokens.

```solidity
function querySellQuote(address trader, uint256 payQuoteAmount) public view returns (uint256 receiveBaseAmount, uint256 mtFee)
```

**Usage:**

```solidity
address mim = 0xFEa7a6a0B346362BF88A9e4A88416B77a57D6c2A;
address usdc = 0xaf88d065e77c8cC2239327C5EDb3A432268e5831;
address lp = 0xPoolAddress; // Address of the MagicLP pool
address trader = msg.sender; // Trader address
uint256 payQuoteAmount = 100 * 1e6; // Amount of quote tokens (USDC) to sell

// Get the expected base tokens (MIM)
(uint256 receiveBaseAmount, uint256 mtFee) = IMagicLP(lp).querySellQuote(trader, payQuoteAmount);
```

#### Example: Using the Router to Interact with MagicLP

While the MagicLP contract provides all the necessary functions for token swaps and liquidity operations, the MIMSwap Router simplifies these interactions by providing a unified interface. Let's walk through an example of how the Router interacts with the MagicLP pools to perform a token swap.

**Step-by-Step Swap Example Using the Router**

1. **Determine the Path and Directions**

   Assume we want to swap MIM for USDC through a single liquidity pool.

   ```solidity
   address[] memory path = new address[](1);
   path[0] = '0xPoolAddress'; // The address of the MIM-USDC liquidity pool

   uint256 directions = 0; // Sell base token (MIM)


   ```
2. **Get the Expected Price**

   Use the `querySellBase` function to get the expected amount of USDC for the given amount of MIM.

   ```solidity
   (uint256 receiveQuoteAmount, uint256 mtFee) = IMagicLP(0xPoolAddress).querySellBase(msg.sender, amountInMIM);
   ```
3. **Execute the Swap**

   Call the `swapTokensForTokens` function on the router with the determined path and directions.

   ```solidity
   uint256 minimumOut = receiveQuoteAmount;
   uint256 deadline = block.timestamp + 300; // 5 minutes from now

   router.swapTokensForTokens(
       msg.sender,
       amountInMIM,
       path,
       directions,
       minimumOut,
       deadline
   );
   ```

By following these steps, third-party systems can effectively integrate MIMSwap's swapping functionality, providing their users with seamless and efficient token swaps.


# Swappers

Swappers are a contract that allows users to perform a swap as part of the series of operation they bundle together when they 'cook' a transaction with Abracadabra. It is often used in 3 contexts: Leverage, Deleverage and Liquidations, to swap collateral and MIM.

While the freedom that cauldrons gives the user in terms of callable contracts would enable them to call any decentralize exchange, swappers are contracts that facilitate this process, standardizing the calls to be made.

Early Swappers hardcoded a route, using a Curve Pool or a UniV2-like DEX, while SwapperV2 support DEX Aggregators and augment the possibilities and adaptability of the system.

Here are the 2 interfaces Swappers can conform to. V2 added a 'data' parameter to be given to the dex aggregator in order to perform swaps in any arbitrary route.

### ISwapperV1

```solidity
interface ISwapper {
    /// @notice Withdraws 'amountFrom' of token 'from' from the BentoBox account for this swapper.
    /// Swaps it for at least 'amountToMin' of token 'to'.
    /// Transfers the swapped tokens of 'to' into the BentoBox using a plain ERC20 transfer.
    /// Returns the amount of tokens 'to' transferred to BentoBox.
    /// (The BentoBox skim function will be used by the caller to get the swapped funds).
    function swap(
        IERC20 fromToken,
        IERC20 toToken,
        address recipient,
        uint256 shareToMin,
        uint256 shareFrom
    ) external returns (uint256 extraShare, uint256 shareReturned);
```

### ISwapperV2

```solidity
interface ISwapperV2 {
    /// @notice Withdraws 'amountFrom' of token 'from' from the BentoBox account for this swapper.
    /// Swaps it for at least 'amountToMin' of token 'to'.
    /// Transfers the swapped tokens of 'to' into the BentoBox using a plain IERC20 transfer.
    /// Returns the amount of tokens 'to' transferred to BentoBox.
    /// (The BentoBox skim function will be used by the caller to get the swapped funds).
    function swap(
        address fromToken,
        address toToken,
        address recipient,
        uint256 shareToMin,
        uint256 shareFrom,
        bytes calldata data
    ) external returns (uint256 extraShare, uint256 shareReturned);
}
```


# Wrappers

Wrappers in this context refers to collateral tokens that modify the original collateral asset in order to achieve something.

It can be to make an asset yield bearing natively (instead of via DegenBox Strategy) like the magicTokens or to accommodate for specificities of this token with a partner application, like Convex.


# GLP Self Repaying

The GLP Self Repaying wrapper, used with the (now deprecated) GLP Self Repaying Cauldron enabled users to have GLP used as collateral while having the GLP Yield be used to automatically pay back the debt of the Cauldron, achieving a system where debt would automatically go down as ETH Rewards were harvested.


# magicGLP

GLP Autocompounder

magicGLP is Abracadabra’s auto-compounder for GLP tokens, where ETH yield produced by GLP farming is automatically auto-compounded back into magicGLP.

It's an ERC4626, also know as vault tokens, and rewards are accrue via an increase in GLP per mGLP as harvests happen.


# magicAPE

APE Autocompounder

magicAPE is Abracadabra’s auto-compounder for APE tokens, where APE yield produced from staking is automatically auto-compounded back into magicAPE.

It's an ERC4626, also know as vault tokens, and rewards are accrue via an increase in APE per mAPE as harvests happen.


# Withdrawers

Cauldron Withdrawers are contract designed to streamline the collection of fees. They are the cauldron's designated fee recipient and collect all the MIM from them before sending them to the distributor contract that will send them to mSPELL and sSPELL after sending the treasury share.

On chains other than Ethereum Mainnet, Withdrawers beam MIM to the distributor contract on Ethereum Mainnet.


# CauldronOwner

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

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

**Parameters**

| Name           | Type      |
| -------------- | --------- |
| **\_treasury** | `address` |
| **\_mim**      | `address` |

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

* [changeBorrowLimit](#changeborrowlimit)
* [changeInterestRate](#changeinterestrate)
* [claimOwnership](#claimownership)
* [deprecated](#deprecated)
* [execute](#execute)
* [mim](#mim)
* [operators](#operators)
* [owner](#owner)
* [pendingOwner](#pendingowner)
* [reduceCompletely](#reducecompletely)
* [reduceSupply](#reducesupply)
* [setAllowedSupplyReducer](#setallowedsupplyreducer)
* [setBlacklistedCallee](#setblacklistedcallee)
* [setDeprecated](#setdeprecated)
* [setFeeTo](#setfeeto)
* [setOperator](#setoperator)
* [setTreasury](#settreasury)
* [transferMasterContractOwnership](#transfermastercontractownership)
* [transferOwnership](#transferownership)
* [treasury](#treasury)
* [withdrawMIMToTreasury](#withdrawmimtotreasury)

***

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

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **cauldron**       | `address` |
| **newBorrowLimit** | `uint128` |
| **perAddressPart** | `uint128` |

**Return values**

No return values for this function.

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

**Parameters**

| Name                | Type      |
| ------------------- | --------- |
| **cauldron**        | `address` |
| **newInterestRate** | `uint64`  |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

| Name      | Type      |
| --------- | --------- |
| **to**    | `address` |
| **value** | `uint256` |
| **data**  | `bytes`   |

**Return values**

| Name        | Type    |
| ----------- | ------- |
| **success** | `bool`  |
| **result**  | `bytes` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **cauldron** | `address` |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **cauldron** | `address` |
| **amount**   | `uint256` |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **cauldron** | `address` |
| **account**  | `address` |
| **allowed**  | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name            | Type      |
| --------------- | --------- |
| **cauldron**    | `address` |
| **callee**      | `address` |
| **blacklisted** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name             | Type      |
| ---------------- | --------- |
| **cauldron**     | `address` |
| **\_deprecated** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **cauldron** | `address` |
| **newFeeTo** | `address` |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **operator** | `address` |
| **enabled**  | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name           | Type      |
| -------------- | --------- |
| **\_treasury** | `address` |

**Return values**

No return values for this function.

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

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **masterContract** | `address` |
| **newOwner**       | `address` |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **newOwner** | `address` |
| **direct**   | `bool`    |
| **renounce** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **bentoBox** | `address` |
| **share**    | `uint256` |

**Return values**

No return values for this function.

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

* [LogDeprecated](#logdeprecated)
* [LogOperatorChanged](#logoperatorchanged)
* [LogTreasuryChanged](#logtreasurychanged)
* [OwnershipTransferred](#ownershiptransferred)

***

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **cauldron** | `address` | `true`  |
| **previous** | `bool`    | `false` |
| **current**  | `bool`    | `false` |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **operator** | `address` | `true`  |
| **previous** | `bool`    | `false` |
| **current**  | `bool`    | `false` |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **previous** | `address` | `true`  |
| **current**  | `address` | `true`  |

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

**Parameters**

| Name              | Type      | Indexed |
| ----------------- | --------- | ------- |
| **previousOwner** | `address` | `true`  |
| **newOwner**      | `address` | `true`  |


# GMX V2 OrderAgent & RouterOrder


# GmxV2CauldronOrderAgent

Agent handling the creation and management of RouterOrder clones.

### createOrder | only callable by cauldrons

This function creates a new order for a specific user with the given parameters. It is called by the `GmxV2CauldronV4` contract to set up a new order in response to user actions.

It creates a clone of the RouterOrder contract and initializes it accordingly.

```solidity
function createOrder(address user, GmRouterOrderParams memory params) external payable onlyOperators returns (address order)
```

**Parameters**

| Name     | Type                  | Note                                                     |
| -------- | --------------------- | -------------------------------------------------------- |
| `user`   | `address`             | Address of the user for whom the order is being created. |
| `params` | `GmRouterOrderParams` | Parameters defining the details of the order.            |

***

### setOracle | only owner

Sets the oracle for a specific GMX V2 market, essential for ensuring accurate market data for the orders.

This oracle is then used by all RouterOrder clones

```solidity
function setOracle(address market, IOracle oracle) external onlyOwner
```

**Parameters**

| Name     | Type      | Note                                                 |
| -------- | --------- | ---------------------------------------------------- |
| `market` | `address` | The market for which the oracle is being set.        |
| `oracle` | `IOracle` | The oracle contract to use for the specified market. |

***

### setCallbackGasLimit | only owner

Adjusts the gas limit for callback functions used in the GMX architecture. This function sets the maximum amount of gas allowed for operations following a callback. This is particularly relevant for the non-atomic nature of GMX transactions, where a user creates an order that is later filled by a keeper. The callback mechanism allows for composability by enabling the orderRouter proxy contract to continue the flow after receiving tokens from the deposit or withdrawal handler.

This callback gas limit is used by all RouterOrder clones.

```solidity
function setCallbackGasLimit(uint256 _callbackGasLimit) external onlyOwner
```

**Parameters**

| Name                | Type      | Note                             |
| ------------------- | --------- | -------------------------------- |
| `_callbackGasLimit` | `uint256` | The new gas limit for callbacks. |

***


# GmxV2CauldronRouterOrder

Implementation of the RouterOrder, cloned by the OrderAgent

### init | For Order Creation

Always called by `GmxV2CauldronOrderAgent` during the order creation process. This function not only initializes the order but also triggers the order creation on the GMX Router.

```solidity
function init(address _cauldron, address _user, GmRouterOrderParams memory params) external payable
```

**Parameters**

| Name        | Type                  | Note                                                       |
| ----------- | --------------------- | ---------------------------------------------------------- |
| `_cauldron` | `address`             | Address of the Cauldron contract, linking the order to it. |
| `_user`     | `address`             | User address for whom the order is being initialized.      |
| `params`    | `GmRouterOrderParams` | Parameters defining the order's characteristics.           |

***

### cancelOrder | Specific to Cauldron

Cancels an open order on the GMX Router. This function is called by the Cauldron contract, typically in scenarios like liquidation or as part of the corresponding \_additionalCookActions.\
It is necessary to call it before processing certain actions as any open order could receive tokens and callbacks from GMX which would lead to unintended results.

```solidity
function cancelOrder() external onlyCauldron 
```

No parameters.

***

### withdrawFromOrder | Specific to Cauldron

Enables the Cauldron contract to withdraw from an order, depositing the token back into the degenBox. This function is always called as part of the additional cook action in the Cauldron contract.\
It can also call closeOrder on the cauldron after the withdrawing part, sending all remaining balance to the user.

This function is used to withdraw the short token from the order. Which happens as part of the deleverage process to the repay MIM.

```solidity
function withdrawFromOrder(address token, address to, uint256 amount, bool closeOrder) external onlyCauldron
```

**Parameters**

| Name         | Type      | Note                                         |
| ------------ | --------- | -------------------------------------------- |
| `token`      | `address` | Token address for the withdrawal.            |
| `to`         | `address` | Recipient address for the withdrawn funds.   |
| `amount`     | `uint256` | Amount to withdraw from the order.           |
| `closeOrder` | `bool`    | Whether to close the order after withdrawal. |

***

### sendValueInCollateral | Specific to Cauldron

Transfers a specified amount of DegenBox shares to the liquidator during a liquidation process. This function is used exclusively in liquidation scenarios.

This function transfers an amount of the short token to the liquidator, this amount is calculated using an amount of collateralShare as an input to be compatible with the liquidation function. It computes the value of this in shortToken and transfers it.

```solidity
function sendValueInCollateral(address recipient, uint256 shareMarketToken) external onlyCauldron
```

**Parameters**

| Name               | Type      | Note                                                |
| ------------------ | --------- | --------------------------------------------------- |
| `recipient`        | `address` | The recipient to receive the collateral.            |
| `shareMarketToken` | `uint256` | Share of the market token to be sent as collateral. |

***

### orderValueInCollateral | Public View

Calculates the value of the order in terms of collateral, used in the `_isSolvent` function in the Cauldron contract to include the order's value in solvency checks.

```solidity
function orderValueInCollateral() public view returns (uint256)
```

No parameters.

***

### isActive | Public View

Checks if the order is active, used in liquidation processes to know if the order needs to be cancelled.

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

No parameters.

***

### afterDepositExecution | Callback for Deposit Handler

This callback function is triggered after a deposit order is executed. It verifies that the deposit originated from this contract and then proceeds to deposit the received market tokens as collateral back into the cauldron. This action effectively converts the tokens from the deposit into collateral within the cauldron and then closes the order associated with the user.

```solidity
function afterDepositExecution(bytes32 /*key*/, IGmxV2Deposit.Props memory deposit, IGmxV2EventUtils.EventLogData memory /*eventData*/) external override onlyDepositHandler
```

**Parameters**

| Name        | Type                            | Note                                    |
| ----------- | ------------------------------- | --------------------------------------- |
| `key`       | `bytes32`                       | The unique key identifying the deposit. |
| `deposit`   | `IGmxV2Deposit.Props`           | Properties of the executed deposit.     |
| `eventData` | `IGmxV2EventUtils.EventLogData` | Additional event data (unused here).    |

***

### afterWithdrawalCancellation | Callback for Withdrawal Handler

This callback is invoked after a withdrawal order is cancelled. It ensures that the withdrawal was associated with this contract and then follows the same process as `afterDepositExecution`, depositing the market tokens as collateral in the cauldron.

When a withdrawal cancels or fails, GMX will send back to the order gm tokens, not the short token. In this case, we use this callback to ensure those gm tokens are deposited back as collateral.

```solidity
function afterWithdrawalCancellation(bytes32 /*key*/, IGmxV2Withdrawal.Props memory withdrawal, IGmxV2EventUtils.EventLogData memory /*eventData*/) external override onlyWithdrawalHandler
```

**Parameters**

| Name         | Type                            | Note                                       |
| ------------ | ------------------------------- | ------------------------------------------ |
| `key`        | `bytes32`                       | The unique key identifying the withdrawal. |
| `withdrawal` | `IGmxV2Withdrawal.Props`        | Properties of the cancelled withdrawal.    |
| `eventData`  | `IGmxV2EventUtils.EventLogData` | Additional event data (unused here).       |

***

#### Context for Callback Functions

The `afterDepositExecution` and `afterWithdrawalCancellation` callbacks are called by Gmx's keeper as part of the Deposit or Withdrawal Handler. Our implementation of these function utilize the internal function `_depositMarketTokensAsCollateral`. This function takes the market tokens received from the executed deposit or cancelled withdrawal, transfers them to the DegenBox, and then deposits them as collateral in the Cauldron contract. This process adds the tokens back as collateral, directly impacting the user's position within the cauldron, and finalizes the order by closing it.


# MIM

Abracadabra's stablecoin

## Magic Internet Money

Magic Internet Money (MIM) is an ERC20 token with some additional functionality beyond the standard ERC20 behavior. The standard behavior of the token, such as transfers, allowances, and balance checks, are implemented as per the standard ERC20 protocol. Please refer to the ERC20 standard for more details on these functions.

The contract is implemented in Solidity version 0.6.12 and imports several utility libraries and contracts including `BoringMath`, `ERC20`, `IBentoBoxV1`, and `BoringOwnable`.

### Contract Details

The MIM contract is `BoringOwnable`, meaning it has an owner who can only perform certain operations. The owner of the contract is the Big MIM Multisig. The contract uses the `BoringMath` library for mathematical operations, which provides some additional safety features like overflow checks.

The contract defines some constant variables including `symbol`, `name`, and `decimals`, which are common in ERC20 tokens:

* `symbol`: The symbol of the token is "MIM".
* `name`: The name of the token is "Magic Internet Money".
* `decimals`: The number of decimal places the token can be divided into is 18.

The contract also overrides the `totalSupply` variable from the ERC20 standard to make it public and mutable.

### Minting Mechanism

The contract has a unique minting mechanism that limits the amount that can be minted in a given period. The period duration restarts every time minting occurs. This mechanism is implemented in the `mint` function.

The minting mechanism is governed by the `Minting` struct which contains two properties:

* `time`: The time when the last minting occurred.
* `amount`: The amount that was minted.

Furthermore, there are some constant variables related to the minting mechanism:

* `MINTING_PERIOD`: The minting period is set to 24 hours.
* `MINTING_INCREASE`: The minting increase limit is set to 15000.
* `MINTING_PRECISION`: The precision of the minting mechanism is set to 1e5.

This corresponds to a max minting of 15% of the totalSupply per day.

The `mint` function takes two arguments:

* `to`: The address to which the new tokens will be minted.
* `amount`: The amount of tokens to be minted.

The function requires that the `to` address is not the zero address and that the total supply of tokens after the minting will not exceed the limit defined by the minting mechanism. The minting mechanism ensures that the total amount minted in a given period does not exceed the total supply of tokens multiplied by the `MINTING_INCREASE` divided by the `MINTING_PRECISION`. If these conditions are met, the tokens are minted, added to the balance of the `to` address, and the total supply is updated accordingly. A `Transfer` event is emitted with the zero address as the sender and the `to` address as the recipient.

### Minting to BentoBox

The contract also includes a `mintToBentoBox` function, which mints tokens and immediately deposits them into a BentoBox. This function takes three arguments:

* `clone`: The address of the recipient used in the BentoBox deposit.
* `amount`: The amount of tokens to be minted.
* `bentoBox`: The BentoBox where the tokens will be deposited.

The function first mints the tokens to the BentoBox address and then deposits them into the BentoBox using the `deposit` function from the `BentoBox` interface. This effectively allows the contract owner to mint tokens directly into a BentoBox.

### Burn Mechanism

Finally, the contract also includes a `burn` function which allows any address to burn (destroy) tokens from their own balance. This function takes a single argument:

* `amount`: The amount of tokens to be burned.

The function requires that the `amount` to be burned is less than or equal to the balance of the sender. If this condition is met, the tokens are subtracted from the balance of the sender and the total supply of tokens. A `Transfer` event is emitted with the sender as the sender and the zero address as the recipient, signifying the destruction of the tokens.

### Total (minted) Supply vs Circulating Supply

The total supply of Magic Internet Money (MIM) refers to all tokens that have been minted, regardless of their current status or location. This includes tokens that are not circulating but available to be borrowed by users. However, it's important to understand that not all minted MIM tokens are immediately put into active circulation.

When MIM tokens are minted, they are often directly deposited into Cauldrons, which are lending markets. Here, they are made available for users to borrow. It's only when a user decides to borrow these tokens that they truly enter circulation. This is because "circulating supply" refers to tokens that are borrowed and therefore free to move, not just tokens that exist.

This mechanism means that the circulating supply of MIM is typically smaller than the total supply. While the total supply counts all minted tokens, the circulating supply only counts those that are actively being borrowed and circulating. Therefore, when assessing the supply of MIM, it's crucial to distinguish between these two concepts to get a clear understanding of the supply.


# Omnichain MIM

How MIM moves between chains

Abracadabra's Cross-Chain Token Beaming System utilizes the Omnichain Fungible Token (OFT) standard by LayerZero, a decentralized and highly scalable protocol for cross-chain transactions. This system replaces the previous Multichain router for web3 that facilitated arbitrary cross-chain interactions. The system comprises three components:

1. The LzProxyOFTV2 contract used on the Ethereum mainnet
2. The LzIndirectOFTV2 contract used on sidechains
3. The ElevatedMinterBurner contract that authorizes the minting and burning of MIM tokens on sidechains, allowing compatibility with already deployed MIM contract on sidechain

## Beaming flow:

### Mainnet to Sidechain:

This process involves transferring native MIM from the Ethereum mainnet to a sidechain.

1. The user initiates the process by interacting with the `LzProxyOFTV2` contract on the Ethereum mainnet, which transfers MIM from the user's address to the contract's own address.
2. Once the transfer to the `LzProxyOFTV2` mainnet contract is complete, it communicates the transaction details, or "beaming" information, to the `LzIndirectOFTV2` contract on the sidechain through LayerZero
3. The `LzIndirectOFTV2` contract on the sidechain then interacts with the `ElevatedMinterBurner` contract, which mints an equivalent amount of MIM tokens on sidechain, credited to the user's account.

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

### Sidechain A to sidechain B

This process involves burning MIM tokens on sidechain A and minting them on sidechain B.

1. The user first interacts with the `LzIndirectOFTV2` contract on sidechain A which then calls upon the `ElevatedMinterBurner` contract on the same sidechain, burning the user's MIM tokens.
2. Once the tokens are burnt, the `LzIndirectOFTV2` contract on sidechain A communicates "beaming" information to the `LzIndirectOFTV2` contract on sidechain B through LayerZero.
3. Upon receiving the beaming information, the `LzIndirectOFTV2` contract on sidechain B interacts with its `ElevatedMinterBurner`, which mints an equivalent amount of MIM tokens on sidechain B, assigned to the user's account.

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

### Sidechain to Mainnet

This process involves burning MIM tokens on a sidechain and transferring an equivalent amount from the proxy to the user on the Ethereum mainnet.

1. The user interacts with the `LzIndirectOFTV2` contract on the sidechain, which engages its `ElevatedMinterBurner` contract, burning the user's MIM tokens.
2. Once the tokens are burnt, the `LzIndirectOFTV2` contract communicates the "beaming" information to the `LzProxyOFTV2` contract on the Ethereym mainnet through LayerZero.
3. The `LzProxyOFTV2` contract on mainnet transfers an equivalent amount of MIM tokens from itself to the user's account.

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

Note that while these examples use a generic "user" term, Omnichain MIM can be beamed from one user to another or to oneself, with the sender specifying the recipient.


# LzProxyOFTV2

The `LzProxyOFTV2.sol` contract is a pivotal component in Abracadabra's cross-chain beaming system. This contract is deployed on the Ethereum mainnet and plays a key role in the secure transfer of Magic Internet Money (MIM) tokens across different networks.

Here's a detailed developer's overview of this contract:

### Contract Structure

This contract inherits from the `LzBaseOFTV2.sol` base contract, which provides foundational functionality for operating with Omnichain Fungible Tokens (OFTs) on the LayerZero network.

The contract has two key state variables:

1. `innerToken`: This is an instance of the `IERC20` interface and signifies the MIM token on the Ethereum mainnet.
2. `ld2sdRate`: This variable holds the conversion rate between the shared decimals of the LayerZero network and the decimals of the MIM token.

### Constructor

The constructor for `LzProxyOFTV2` takes three parameters: `_token`, `_sharedDecimals`, and `_lzEndpoint`. The `_token` parameter is the address of the MIM token on Ethereum, `_sharedDecimals` represents the number of decimals that the LayerZero network uses, and `_lzEndpoint` is the address of the LayerZero endpoint for this chain.

### Public Functions

The contract offers two key public functions:

1. `circulatingSupply()`: This function returns the total circulating supply of the MIM token on Ethereum, excluding the balance that the contract itself holds.
2. `token()`: This function returns the address of the MIM token.

### Internal Functions

Three crucial internal functions are defined in the contract:

1. `_debitFrom(address _from, uint16, bytes32, uint _amount)`: This function transfers MIM tokens from the user to the contract. It requires that the function caller is the owner of the MIM tokens.
2. `_creditTo(uint16, address _toAddress, uint _amount)`: This function transfers MIM tokens from the contract to the user.
3. `_ld2sdRate()`: An immutable uint that represents the conversion rate from the token's native decimal places to the shared decimal places used in the LayerZero system. LayerZero using 8 decimals.

### Interaction with LayerZero

The `LzProxyOFTV2` contract is a vital part of Abracadabra's system that integrates with LayerZero. This contract acts as a "proxy" on the Ethereum mainnet, facilitating the beaming of MIM tokens to side chains. By locking MIM tokens into this contract, users can initiate the beaming process, which results in the minting of equivalent MIM tokens on the chosen side chain.

This contract uses the LayerZero network to communicate with other chains, enabling the fast, secure, and reliable transfer of MIM tokens across different chains.


# LzIndirectOFTV2

The `LzIndirectOFTV2.sol` contract acts as an Omnichain Fungible Token (OFT) in the LayerZero bridging system. This contract operates on sidechains and enables the transfer of MIM tokens from the Ethereum mainnet to the sidechain.

Here is a detailed overview of the contract:

### Contract Inheritance

The `LzIndirectOFTV2.sol` contract inherits from `LzBaseOFTV2.sol`, which provides the basic structure and functions for an OFT.

### Imported Libraries and Interfaces

* `IMintableBurnable.sol`: The interface for the `ElevatedMinterBurner` contract

### State Variables

* `minterBurner`: An immutable instance of `IMintableBurnable` that represents the `ElevatedMinterBurner` contract. This contract is authorized to mint and burn MIM tokens on the sidechain.
* `innerToken`: An instance of `IERC20` that represents the MIM token on the sidechain.
* `ld2sdRate`: An immutable uint that represents the conversion rate from the token's native decimal places to the shared decimal places used in the LayerZero system. LayerZero using 8 decimals.

### Constructor

The constructor for this contract takes four arguments: `_token`, `_minterBurner`, `_sharedDecimals`, and `_lzEndpoint`. These arguments are used to set the initial state of the contract.

### Public Functions

* `circulatingSupply()`: Returns the total supply of the `innerToken`.
* `token()`: Returns the address of the `innerToken`.

### Internal Functions

* `_debitFrom()`: Burns the specified amount of `innerToken` from the `_from` address. This function calls the minterBurner.burn()
* `_creditTo()`: Mints the specified amount of `innerToken` to the `_toAddress`. This function calls the minterBurner.mint()
* `_ld2sdRate()`: Returns the conversion rate from the token's native decimal places to the shared decimal places used in the LayerZero system.


# ElevatedMinterBurner

The `ElevatedMinterBurner.sol` contract is a periphery contract designed to facilitate minting and burning of tokens, and executing arbitrary calls.

It is an authorized minter and burner of MIM on sidechains, which allows Omnichain MIM to be compatible with the already deployed MIM contracts on sidechains.

It will be called by `LzIndirectOFTV2`as part of the beaming flow, which is an operator of `ElevatedMinterBurner`

### Contract Dependencies

The contract imports and builds upon the `Operatable.sol` and `IMintableBurnable.sol` contracts. The `Operatable.sol` mixin provides functionality to restrict certain contract functions to be executed only by an owner or operators. The `IMintableBurnable.sol` is an interface that defines the minting and burning functions that this contract implements.

### State Variables

* `IMintableBurnable public immutable token;` The contract holds a state variable `token` of type `IMintableBurnable`, which is made immutable and public. This variable represents the token for which minting, burning, and other operations can be performed. The token used is the MIM token on each sidechains.

### Constructor

* `constructor(IMintableBurnable token_)` The contract's constructor takes a token of type `IMintableBurnable` as an argument and assigns it to the `token` state variable.\
  The token used is the MIM token on each sidechains.

### Functions

1. `function burn(address from, uint256 amount) external override onlyOperators returns (bool)`: This function allows operators to burn a specific amount of tokens from a given address. It calls the `burn` function from the `IMintableBurnable` token instance. Returns true if the operation is successful.
2. `function mint(address to, uint256 amount) external override onlyOperators returns (bool)`: This function allows operators to mint a specific amount of tokens to a given address. It calls the `mint` function from the `IMintableBurnable` token instance. Returns true if the operation is successful.
3. `function exec(address target, bytes calldata data) external onlyOwner`: This function allows the contract owner to execute arbitrary calls to a target address with provided data. It directly calls the `call` function of the target address. If the call fails, it reverts the transaction and provides the failed call's result as the revert reason.

The `ElevatedMinterBurner.sol` contract is a key part of the bridging mechanism, providing an interface to mint and burn MIM in a controlled manner, while also allowing the contract owner to execute arbitrary calls.


# SPELL

Abracadabra's Governance Token

## Spell Token Contract

The Spell token contract is an ERC20 token contract that inherits from the BoringOwnable contract, making it owned by a specific address (the "owner") that has exclusive permission to perform certain operations.

### Token Information

The contract declares the following constants for the ERC20 token:

* `symbol`: The token's symbol is "SPELL".
* `name`: The token's name is "Spell Token".
* `decimals`: The token has 18 decimal.

### Total Supply and Max Supply

The contract maintains a `totalSupply` variable, which tracks the total number of tokens that have been minted and are in existence. It also declares a `MAX_SUPPLY` constant which is set to 420 billion, representing the maximum number of SPELL tokens that can ever be minted.

### Minting Mechanism

The contract includes a `mint` function, which allows the contract owner to create new tokens. This function takes two parameters:

* `to`: The address to which the new tokens will be minted.
* `amount`: The number of tokens to be minted.

The function has a couple of requirements that must be met:

* The `to` address must not be the zero address, ensuring that tokens are not minted to an address that can't use them.
* The total supply of tokens after minting must not exceed the `MAX_SUPPLY`.

If these conditions are met, the tokens are minted by increasing the `totalSupply` and the balance of the `to` address by the `amount`. A `Transfer` event is emitted, with the zero address as the sender and the `to` address as the recipient, signifying the creation of new tokens.


# sSPELL

An auto-compounding staking contract for SPELL

sSPELL is the original staking contract for SPELL holders. It is a version of the SushiBar by ChefNomi.\
It works with a share system, users mint sSPELL by depositing SPELL into the contract via the mint(amount) function, and they receive an amount of sSPELL at the current SPELL per sSPELL ratio.

When protocol fees are accrued and SPELL is bought back and sent to the sSPELL contract, SPELL is deposited but no sSPELL is minted: the SPELL per sSPELL ratio increases.

The burn function is the exact inverse of mint, it burns your sSPELL and gives you back SPELL at the current SPELL:sSPELL ratio.

To avoid people gaming the system, upon staking, the sSPELL is subject to a 24h lockup, where it can be moved, burned, used as collateral etc…

Appart from this, sSPELL is a regular ERC20.

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

```solidity
function mint(uint256 amount) public returns (bool) {
```

**Parameters**

| Name       | Type      | Description               |
| ---------- | --------- | ------------------------- |
| **amount** | `uint256` | Amount of SPELL to stake. |

**Return values**

| Name  | Type   | Description                                  |
| ----- | ------ | -------------------------------------------- |
| **/** | `bool` | Returns True if the operation is successful. |

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

```solidity
function burn(address to, uint256 shares) public returns (bool) {
```

**Parameters**

| Name       | Type      |                               |
| ---------- | --------- | ----------------------------- |
| **to**     | `address` | Address to send the SPELL to. |
| **shares** | `uint256` | Amount of sSPELL to burn.     |

**Return values**

| Name  | Type   | Description                                  |
| ----- | ------ | -------------------------------------------- |
| **/** | `bool` | Returns True if the operation is successful. |

### `burnFrom | nonpayable`[​](https://smart-docs.vercel.app/contract#burnFrom) <a href="#burnfrom" id="burnfrom"></a>

```solidity
function burnFrom(
    address from,
    address to,
    uint256 shares
) public returns (bool) {
```

Same as Burn, but allow another address that has been approved by you using the standard ERC20 approve() to burn on your behalf.

**Parameters**

| Name       | Type      | Description                      |
| ---------- | --------- | -------------------------------- |
| **from**   | `address` | Address to burn the sSPELL from. |
| **to**     | `address` | Address to send the SPELL to.    |
| **shares** | `uint256` | Amount of sSPELL to burn.        |

**Return values**

| Name  | Type   |                                              |
| ----- | ------ | -------------------------------------------- |
| **/** | `bool` | Returns True if the operation is successful. |


# 1InchSpellSwapper

Contract that swaps the MIM it receives from the mSpellSender (which is more than simply mSPELL as it does payouts to mSPELL, sSPELL and Treasury) and swaps it for SPELL on 1inch.\
The contract is automated using Gelato Tasks and off-chain resolvers to obtain the 1inch calldata.

The user never interacts with this contracts but the sSPELL staker benefits from it in the form of regular SPELL payouts to sSPELL.


# mSPELL

A native multichain staking system for SPELL with payouts in MIM.

mSPELL is a staking system allowing users to stake SPELL in any of the supported chains and get a share of protocol revenue in the form of MIM they can claim.

To create a native staking system on every chain that stems from the same protocol revenue on Ethereum Mainnet (protocol fees from all chains are sent back to Ethereum Mainnet), mSPELL uses a combination of 3 contracts:

* mSPELL Staking, available on every supported chain, allowing users to stake their SPELL and claim there MIM.
* mSPELL Reporter, available on every supported chain, a contract that uses LayerZero's messaging infrastructure to let mSPELL Sender know about how much SPELL is staked.
* mSPELL Sender, available on Ethereum Mainnet, which role it is to send the correct amount of MIM to the different mSPELL Staking contracts, by bridging MIM, and using the values obtained from the various mSPELL Reporters.

Unlike sSPELL, mSPELL isn't a token, but a staked position. The user does not receive mSPELL tokens, but has SPELL staked into the mSPellStaking contract.


# mSpellSender

Contract pulling MIM from the Withdrawer and distributing it.

mSPELL sender is responsible from claiming the fees in the Withdrawer (*it is the owner of the withdrawer and can access funds this way)* and distributing it to the 3 recipients:

* the Treasury (based on the [treasuryPercentage](#treasurypercentage) value)
* Staking contracts, divided into:
  * sSPELL (based on the amount of SPELL staked)
  * mSPELL (based on the total amount of SPELL staked on all chains)

For mSPELL specifically, the sender will bridge the funds to the mSpellStaking contracts in the right amount (based on the amount of SPELL staked) on all chains.

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

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

**Parameters**

No parameters found in the constructor.

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

* [addMSpellRecipient](https://smart-docs.vercel.app/contract#addMSpellRecipient)
* [addReporter](https://smart-docs.vercel.app/contract#addReporter)
* [bridgeMim](https://smart-docs.vercel.app/contract#bridgeMim)
* [changePurchaser](https://smart-docs.vercel.app/contract#changePurchaser)
* [checker](https://smart-docs.vercel.app/contract#checker)
* [claimOwnership](https://smart-docs.vercel.app/contract#claimOwnership)
* [isActiveChain](https://smart-docs.vercel.app/contract#isActiveChain)
* [isOperator](https://smart-docs.vercel.app/contract#isOperator)
* [lzReceive](https://smart-docs.vercel.app/contract#lzReceive)
* [mSpellReporter](https://smart-docs.vercel.app/contract#mSpellReporter)
* [owner](https://smart-docs.vercel.app/contract#owner)
* [pendingOwner](https://smart-docs.vercel.app/contract#pendingOwner)
* [recipients](https://smart-docs.vercel.app/contract#recipients)
* [setOperator](https://smart-docs.vercel.app/contract#setOperator)
* [sspellBuyBack](https://smart-docs.vercel.app/contract#sspellBuyBack)
* [transferOwnership](https://smart-docs.vercel.app/contract#transferOwnership)
* [transferWithdrawer](https://smart-docs.vercel.app/contract#transferWithdrawer)
* [treasury](https://smart-docs.vercel.app/contract#treasury)
* [treasuryPercentage](https://smart-docs.vercel.app/contract#treasuryPercentage)

***

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

**Parameters**

| Name          | Type      |
| ------------- | --------- |
| **recipient** | `address` |
| **chainId**   | `uint256` |
| **chainIdLZ** | `uint256` |

**Return values**

No return values for this function.

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

**Parameters**

| Name          | Type      |
| ------------- | --------- |
| **reporter**  | `bytes`   |
| **chainIdLZ** | `uint256` |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name                     | Type      |
| ------------------------ | --------- |
| **\_purchaser**          | `address` |
| **\_treasury**           | `address` |
| **\_treasuryPercentage** | `uint256` |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

| Name            | Type    |
| --------------- | ------- |
| **canExec**     | `bool`  |
| **execPayload** | `bytes` |

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

**Return values**

| Name         | Type     |
| ------------ | -------- |
| **isActive** | `uint8`  |
| **position** | `uint32` |

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

| Name             | Type     |
| ---------------- | -------- |
| **\_srcChainId** | `uint16` |
| **\_srcAddress** | `bytes`  |
| **/**            | `uint64` |
| **\_payload**    | `bytes`  |

**Return values**

No return values for this function.

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

**Return values**

| Name  | Type    |
| ----- | ------- |
| **/** | `bytes` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

**Return values**

| Name             | Type      |
| ---------------- | --------- |
| **recipient**    | `address` |
| **chainId**      | `uint32`  |
| **chainIdLZ**    | `uint32`  |
| **lastUpdated**  | `uint32`  |
| **amountStaked** | `uint128` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **operator** | `address` |
| **status**   | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **newOwner** | `address` |
| **direct**   | `bool`    |
| **renounce** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **newOwner** | `address` |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

* [LogAddRecipient](https://smart-docs.vercel.app/contract#LogAddRecipient)
* [LogBridgeToRecipient](https://smart-docs.vercel.app/contract#LogBridgeToRecipient)
* [LogChangePurchaser](https://smart-docs.vercel.app/contract#LogChangePurchaser)
* [LogSetOperator](https://smart-docs.vercel.app/contract#LogSetOperator)
* [LogSetReporter](https://smart-docs.vercel.app/contract#LogSetReporter)
* [LogSpellStakedReceived](https://smart-docs.vercel.app/contract#LogSpellStakedReceived)
* [OwnershipTransferred](https://smart-docs.vercel.app/contract#OwnershipTransferred)

***

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

**Parameters**

| Name          | Type      | Indexed |
| ------------- | --------- | ------- |
| **recipient** | `address` | `true`  |
| **chainId**   | `uint256` | `false` |
| **chainIdLZ** | `uint256` | `false` |

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

**Parameters**

| Name          | Type      | Indexed |
| ------------- | --------- | ------- |
| **recipient** | `address` | `true`  |
| **amount**    | `uint256` | `false` |
| **chainId**   | `uint256` | `false` |

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

**Parameters**

| Name                     | Type      | Indexed |
| ------------------------ | --------- | ------- |
| **\_purchaser**          | `address` | `false` |
| **\_treasury**           | `address` | `false` |
| **\_treasuryPercentage** | `uint256` | `false` |

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

**Parameters**

| Name         | Type      | Indexed |
| ------------ | --------- | ------- |
| **operator** | `address` | `true`  |
| **status**   | `bool`    | `false` |

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

**Parameters**

| Name          | Type      | Indexed |
| ------------- | --------- | ------- |
| **chainIdLZ** | `uint256` | `true`  |
| **reporter**  | `bytes`   | `false` |

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

**Parameters**

| Name           | Type      | Indexed |
| -------------- | --------- | ------- |
| **srcChainId** | `uint16`  | `false` |
| **timestamp**  | `uint32`  | `false` |
| **amount**     | `uint128` | `false` |

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

**Parameters**

| Name              | Type      | Indexed |
| ----------------- | --------- | ------- |
| **previousOwner** | `address` | `true`  |
| **newOwner**      | `address` | `true`  |


# mSpellStaking

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

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

**Parameters**

| Name        | Type      |
| ----------- | --------- |
| **\_mim**   | `address` |
| **\_spell** | `address` |

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

* [ACC\_REWARD\_PER\_SHARE\_PRECISION](https://smart-docs.vercel.app/contract#ACC_REWARD_PER_SHARE_PRECISION)
* [accRewardPerShare](https://smart-docs.vercel.app/contract#accRewardPerShare)
* [claimOwnership](https://smart-docs.vercel.app/contract#claimOwnership)
* [deposit](https://smart-docs.vercel.app/contract#deposit)
* [emergencyWithdraw](https://smart-docs.vercel.app/contract#emergencyWithdraw)
* [lastRewardBalance](https://smart-docs.vercel.app/contract#lastRewardBalance)
* [mim](https://smart-docs.vercel.app/contract#mim)
* [owner](https://smart-docs.vercel.app/contract#owner)
* [pendingOwner](https://smart-docs.vercel.app/contract#pendingOwner)
* [pendingReward](https://smart-docs.vercel.app/contract#pendingReward)
* [spell](https://smart-docs.vercel.app/contract#spell)
* [toggleLockUp](https://smart-docs.vercel.app/contract#toggleLockUp)
* [toggleLockup](https://smart-docs.vercel.app/contract#toggleLockup)
* [transferOwnership](https://smart-docs.vercel.app/contract#transferOwnership)
* [updateReward](https://smart-docs.vercel.app/contract#updateReward)
* [userInfo](https://smart-docs.vercel.app/contract#userInfo)
* [withdraw](https://smart-docs.vercel.app/contract#withdraw)

***

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **\_amount** | `uint256` |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name       | Type      |
| ---------- | --------- |
| **\_user** | `address` |

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

| Name       | Type   |
| ---------- | ------ |
| **status** | `bool` |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type   |
| ----- | ------ |
| **/** | `bool` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **newOwner** | `address` |
| **direct**   | `bool`    |
| **renounce** | `bool`    |

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

**Return values**

| Name           | Type      |
| -------------- | --------- |
| **amount**     | `uint128` |
| **rewardDebt** | `uint128` |
| **lastAdded**  | `uint128` |

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

**Parameters**

| Name         | Type      |
| ------------ | --------- |
| **\_amount** | `uint256` |

**Return values**

No return values for this function.

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

* [ClaimReward](https://smart-docs.vercel.app/contract#ClaimReward)
* [Deposit](https://smart-docs.vercel.app/contract#Deposit)
* [EmergencyWithdraw](https://smart-docs.vercel.app/contract#EmergencyWithdraw)
* [OwnershipTransferred](https://smart-docs.vercel.app/contract#OwnershipTransferred)
* [Withdraw](https://smart-docs.vercel.app/contract#Withdraw)

***

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **user**   | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **user**   | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **user**   | `address` | `true`  |
| **amount** | `uint256` | `false` |

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

**Parameters**

| Name              | Type      | Indexed |
| ----------------- | --------- | ------- |
| **previousOwner** | `address` | `true`  |
| **newOwner**      | `address` | `true`  |

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

**Parameters**

| Name       | Type      | Indexed |
| ---------- | --------- | ------- |
| **user**   | `address` | `true`  |
| **amount** | `uint256` | `false` |


# mSpellReporter

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

* Filename: **/**
* Number of EVM logging *events*: **0**
* Number of *functions*: **6**

\\

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

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

**Parameters**

| Name               | Type      |
| ------------------ | --------- |
| **\_endpoint**     | `address` |
| **\_SPELL**        | `address` |
| **\_mSpell**       | `address` |
| **\_mSpellSender** | `address` |

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

* [SPELL](https://smart-docs.vercel.app/contract#SPELL)
* [lastUpdated](https://smart-docs.vercel.app/contract#lastUpdated)
* [mSpell](https://smart-docs.vercel.app/contract#mSpell)
* [mSpellSender](https://smart-docs.vercel.app/contract#mSpellSender)
* [sendAmount](https://smart-docs.vercel.app/contract#sendAmount)
* [withdraw](https://smart-docs.vercel.app/contract#withdraw)

***

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `uint256` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

| Name  | Type      |
| ----- | --------- |
| **/** | `address` |

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

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

**Parameters**

No parameters for this function.

**Return values**

No return values for this function.

### Events (for EVM logging)[​](https://smart-docs.vercel.app/contract#events-for-evm-logging) <a href="#events-for-evm-logging" id="events-for-evm-logging"></a>

No **events** found in this smart contract.


# Ethereum Mainnet

Each Lending Market has a dedicated smart contract. These smart contracts are called **cauldrons** and allow users to open loans, borrow MIMs, leverage and repay. A difference checker between Kashi and our Cauldrons contracts can be find [**here**](https://www.diffchecker.com/JVs0rrxi).

Cauldrons are built either on top of [**BentoBox**](https://docs.sushi.com/products/bentobox) or on Degenbox. You can find Certora's audits for Bentobox [**here**](https://www.certora.com/wp-content/uploads/2022/02/SushiBentoboxFeb2021.pdf).

## Boxes:

* DegenBox: [0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce](https://etherscan.io/address/0xd96f48665a1410C0cd669A88898ecA36B9Fc2cce)
* BentoBox: [0xf5bce5077908a1b7370b9ae04adc565ebd643966](https://etherscan.io/address/0xf5bce5077908a1b7370b9ae04adc565ebd643966)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V2:

* ALCX: [0x7b7473a76D6ae86CE19f7352A1E89F6C9dc39020](https://etherscan.io/address/0x7b7473a76D6ae86CE19f7352A1E89F6C9dc39020)
* AGLD: [0xc1879bf24917ebE531FbAA20b0D05Da027B592ce](https://etherscan.io/address/0xc1879bf24917ebE531FbAA20b0D05Da027B592ce)
* FTT: [0x9617b633EF905860D919b88E1d9d9a6191795341](https://etherscan.io/address/0x9617b633EF905860D919b88E1d9d9a6191795341)
* SHIB: [0x252dCf1B621Cc53bc22C256255d2bE5C8c32EaE4](https://etherscan.io/address/0x252dCf1B621Cc53bc22C256255d2bE5C8c32EaE4)
* SPELL: [0xCfc571f3203756319c231d3Bc643Cee807E74636](https://etherscan.io/address/0xCfc571f3203756319c231d3Bc643Cee807E74636)
* WBTC: [0x5ec47EE69BEde0b6C2A2fC0D9d094dF16C192498](https://etherscan.io/address/0x5ec47EE69BEde0b6C2A2fC0D9d094dF16C192498)
* WETH: [0x390Db10e65b5ab920C19149C919D970ad9d18A41](https://etherscan.io/address/0x390Db10e65b5ab920C19149C919D970ad9d18A41)
* cvx3pool: [0x257101F20cB7243E2c7129773eD5dBBcef8B34E0](https://etherscan.io/address/0x257101F20cB7243E2c7129773eD5dBBcef8B34E0)
* cvxtricrypto2: [0x4EAeD76C3A388f4a841E9c765560BBe7B3E4B3A0](https://etherscan.io/address/0x4EAeD76C3A388f4a841E9c765560BBe7B3E4B3A0)
* sSPELL: [0x3410297D89dCDAf4072B805EFc1ef701Bb3dd9BF](https://etherscan.io/address/0x3410297D89dCDAf4072B805EFc1ef701Bb3dd9BF)
* xSUSHI: [0x98a84EfF6e008c5ed0289655CcdCa899bcb6B99F](https://etherscan.io/address/0x98a84EfF6e008c5ed0289655CcdCa899bcb6B99F)
* yvCVXETH: [0xf179fe36a36B32a4644587B8cdee7A23af98ed37](https://etherscan.io/address/0xf179fe36a36B32a4644587B8cdee7A23af98ed37)
* yvWETH-v2: [0x920D9BD936Da4eAFb5E25c6bDC9f6CB528953F9f](https://etherscan.io/address/0x920D9BD936Da4eAFb5E25c6bDC9f6CB528953F9f)
* yvcrvIB: [0xEBfDe87310dc22404d918058FAa4D56DC4E93f0A](https://etherscan.io/address/0xEBfDe87310dc22404d918058FAa4D56DC4E93f0A)

#### V3:

* yvSTETH2: [0x53375adD9D2dFE19398eD65BAaEFfe622760A9A6](https://etherscan.io/address/0x53375adD9D2dFE19398eD65BAaEFfe622760A9A6)
* yvDAI: [0x7Ce7D9ED62B9A6c5aCe1c6Ec9aeb115FA3064757](https://etherscan.io/address/0x7Ce7D9ED62B9A6c5aCe1c6Ec9aeb115FA3064757)
* Stargate-USDC: [0xd31E19A0574dBF09310c3B06f3416661B4Dc7324](https://etherscan.io/address/0xd31E19A0574dBF09310c3B06f3416661B4Dc7324)
* Stargate-USDT: [0xc6B2b3fE7c3D7a6f823D9106E22e66660709001e](https://etherscan.io/address/0xc6B2b3fE7c3D7a6f823D9106E22e66660709001e)
* LUSD: [0x8227965A7f42956549aFaEc319F4E444aa438Df5](https://etherscan.io/address/0x8227965A7f42956549aFaEc319F4E444aa438Df5)

#### V4:

* magciAPE: [0x692887E8877C6Dd31593cda44c382DB5b289B684](https://etherscan.io/address/0x692887E8877C6Dd31593cda44c382DB5b289B684)
* WBTC: [0x85f60D3ea4E86Af43c9D4E9CC9095281fC25c405](https://etherscan.io/address/0x85f60D3ea4E86Af43c9D4E9CC9095281fC25c405)
* yvSTETH3: [0x406b89138782851d3a8C04C743b010CEb0374352](https://etherscan.io/address/0x406b89138782851d3a8C04C743b010CEb0374352)
* CRV: [0x207763511da879a900973A5E092382117C3c1588](https://etherscan.io/address/0x207763511da879a900973A5E092382117C3c1588)
* CRV2: [0x7d8dF3E4D06B0e19960c19Ee673c0823BEB90815](https://etherscan.io/address/0x7d8dF3E4D06B0e19960c19Ee673c0823BEB90815)
* yv-3Crypto: [0x7259e152103756e1616A77Ae982353c3751A6a90](https://etherscan.io/address/0x7259e152103756e1616A77Ae982353c3751A6a90)
* yv-mim3crv: [0xF75EDb14F320DF35BB1dB1bb4204762431614e46](https://etherscan.io/address/0xF75EDb14F320DF35BB1dB1bb4204762431614e46)
* stdeusd: [0x00380CB5858664078F2289180CC32F74440AC923](https://etherscan.io/address/0x00380CB5858664078F2289180CC32F74440AC923)

</details>

<details>

<summary>Deprecated Cauldrons:</summary>

* yvUSDC-v2: [0x6cbAFEE1FaB76cA5B5e144c43B3B50d42b7C8c8f](https://etherscan.io/address/0x6cbAFEE1FaB76cA5B5e144c43B3B50d42b7C8c8f)
* yvUSDT-v2: [0x551a7CfF4de931F32893c928bBc3D25bF1Fc5147](https://etherscan.io/address/0x551a7CfF4de931F32893c928bBc3D25bF1Fc5147)
* yvWETH: [0x6Ff9061bB8f97d948942cEF376d98b51fA38B91f](https://etherscan.io/address/0x6Ff9061bB8f97d948942cEF376d98b51fA38B91f)
* xSUSHI: [0xbb02A884621FB8F5BFd263A67F58B65df5b090f3](https://etherscan.io/address/0xbb02A884621FB8F5BFd263A67F58B65df5b090f3)
* yvYFI: [0xFFbF4892822e0d552CFF317F65e1eE7b5D3d9aE6](https://etherscan.io/address/0xFFbF4892822e0d552CFF317F65e1eE7b5D3d9aE6)
* sSPELL: [0xC319EEa1e792577C319723b5e60a15dA3857E7da](https://etherscan.io/address/0xC319EEa1e792577C319723b5e60a15dA3857E7da)
* cvx3pool-v1: [0x806e16ec797c69afa8590A55723CE4CC1b54050E](https://etherscan.io/address/0x806e16ec797c69afa8590A55723CE4CC1b54050E)
* cvx3pool-v2: [0x6371EfE5CD6e3d2d7C477935b7669401143b7985](https://etherscan.io/address/0x6371EfE5CD6e3d2d7C477935b7669401143b7985)
* wsOHM: [0x003d5A75d284824Af736df51933be522DE9Eed0f](https://etherscan.io/address/0x003d5A75d284824Af736df51933be522DE9Eed0f)
* FTM: [0x05500e2Ee779329698DF35760bEdcAAC046e7C27](https://etherscan.io/address/0x05500e2Ee779329698DF35760bEdcAAC046e7C27)
* yvcrvstETH: [0x0BCa8ebcB26502b013493Bf8fE53aA2B1ED401C1](https://etherscan.io/address/0x0BCa8ebcB26502b013493Bf8fE53aA2B1ED401C1)
* cvxrenCrv: [0x35a0Dd182E4bCa59d5931eae13D0A2332fA30321](https://etherscan.io/address/0x35a0Dd182E4bCa59d5931eae13D0A2332fA30321)

</details>

## Wrappers:

* magicAPE: [0xf35b31B941D94B249EaDED041DB1b05b7097fEb6](https://etherscan.io/address/0xf35b31B941D94B249EaDED041DB1b05b7097fEb6)

## Withdrawer:

[0xB2c3A9c577068479B1E5119f6B7da98d25Ba48f4](https://etherscan.io/address/0xB2c3A9c577068479B1E5119f6B7da98d25Ba48f4)

## Omnichain MIM:

* Native MIM: [0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3](https://etherscan.io/token/0x99d8a9c45b2eca8864373a26d1459e3dff1e17f3)
* LzProxyOFTV2: [0x439a5f0f5E8d149DDA9a0Ca367D4a8e4D6f83C10](https://etherscan.io/address/0x439a5f0f5E8d149DDA9a0Ca367D4a8e4D6f83C10)
* OFTWrapper: [0x287176dfbec7e8cee0f876fc7b52960ee1784adc](https://etherscan.io/address/0x287176dfbec7e8cee0f876fc7b52960ee1784adc#code)

## SPELL:

* SPELL Token: [0x090185f2135308bad17527004364ebcc2d37e5f6](https://etherscan.io/token/0x090185f2135308bad17527004364ebcc2d37e5f6)
* sSpell Token: [0x26fa3fffb6efe8c1e69103acb4044c26b9a106a9](https://etherscan.io/address/0x26fa3fffb6efe8c1e69103acb4044c26b9a106a9)
* mSpell Contract: [0xbD2fBaf2dc95bD78Cf1cD3c5235B33D1165E6797](https://etherscan.io/address/0xbD2fBaf2dc95bD78Cf1cD3c5235B33D1165E6797)

## MIMSwap:

* MIMSwap Router: [0x7202B7ca846fc93467E95fa279bC6085F2d5b6FE](https://etherscan.io/address/0x7202B7ca846fc93467E95fa279bC6085F2d5b6FE)
* MIMSwap Factory: [0xDF46F6b1a5F794F21eaD4008C7De4E02Dc045297](https://etherscan.io/address/0xDF46F6b1a5F794F21eaD4008C7De4E02Dc045297)
* MIMSwap MagicLP: [0x6C843D25A2b0eE3E8844492e891dc7257645023A](https://etherscan.io/address/0x6C843D25A2b0eE3E8844492e891dc7257645023A)


# Arbitrum One

## Boxes:

* DegenBox: [0x7c8fef8ea9b1fe46a7689bfb8149341c90431d38](https://arbiscan.io/address/0x7c8fef8ea9b1fe46a7689bfb8149341c90431d38)
* BentoBox: [0x74c764d41b77dbbb4fe771dab1939b00b146894a](https://arbiscan.io/address/0x74c764d41b77dbbb4fe771dab1939b00b146894a)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V2:

* WETH: [0xC89958B03A55B5de2221aCB25B58B89A000215E6](https://arbiscan.io/address/0xC89958B03A55B5de2221aCB25B58B89A000215E6)

#### V4:

* magicGLP: [0x726413d7402fF180609d0EBc79506df8633701B1](https://arbiscan.io/address/0x726413d7402fF180609d0EBc79506df8633701B1)
* gmARB: [0x4F9737E994da9811B8830775Fd73E2F1C8e40741](https://arbiscan.io/address/0x4F9737E994da9811B8830775Fd73E2F1C8e40741)
* gmETH: [0x2b02bBeAb8eCAb792d3F4DDA7a76f63Aa21934FA](https://arbiscan.io/address/0x2b02bBeAb8eCAb792d3F4DDA7a76f63Aa21934FA)
* gmBTC: [0xD7659D913430945600dfe875434B6d80646d552A](https://arbiscan.io/address/0xD7659D913430945600dfe875434B6d80646d552A)
* gmSOL: [0x7962ACFcfc2ccEBC810045391D60040F635404fb](https://arbiscan.io/address/0x7962ACFcfc2ccEBC810045391D60040F635404fb)
* gmLINK: [0x66805F6e719d7e67D46e8b2501C1237980996C6a](https://arbiscan.io/address/0x66805F6e719d7e67D46e8b2501C1237980996C6a)

</details>

<details>

<summary>Deprecated Cauldrons:</summary>

* abracadabraWrappedStakedGlp: [0x5698135CA439f21a57bDdbe8b582C62f090406D5](https://arbiscan.io/address/0x5698135CA439f21a57bDdbe8b582C62f090406D5)

</details>

## Periphery:

* GMXV2 OrderAgent & RouterOrder: [0x8157075B278718C3c075043FAa85822Ad98d60F2](https://arbiscan.io/address/0x8157075B278718C3c075043FAa85822Ad98d60F2)

## Wrappers:

* GLP Self-Repaying: [0x3477Df28ce70Cecf61fFfa7a95be4BEC3B3c7e75](https://arbiscan.io/address/0x3477Df28ce70Cecf61fFfa7a95be4BEC3B3c7e75)
* magicGLP: [0x85667409a723684fe1e57dd1abde8d88c2f54214](https://arbiscan.io/address/0x85667409a723684fe1e57dd1abde8d88c2f54214)

## Withdrawer:

[0x2c9f65bd1a501cb406584f5532ce57c28829b131](https://arbiscan.io/address/0x2c9f65bd1a501cb406584f5532ce57c28829b131)

## Omnichain MIM:

* Arbitrum MIM: [0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a](https://arbiscan.io/token/0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a)
* LzIndirectOFTV2: [0x957A8Af7894E76e16DB17c2A913496a4E60B7090](https://arbiscan.io/address/0x957A8Af7894E76e16DB17c2A913496a4E60B7090)
* ElevatedMinterBurner: [0x26f20d6dee51ad59af339bedf9f721113d01b6b3](https://arbiscan.io/address/0x26f20d6dee51ad59af339bedf9f721113d01b6b3)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://arbiscan.io/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC)

## SPELL:

* SPELL Token: [0x3e6648c5a70a150a88bce65f4ad4d506fe15d2af](https://arbiscan.io/token/0x3e6648c5a70a150a88bce65f4ad4d506fe15d2af)
* mSpell Contract: [0x1DF188958A8674B5177f77667b8D173c3CdD9e51](https://arbiscan.io/address/0x1DF188958A8674B5177f77667b8D173c3CdD9e51)

### MIMSwap:

* MIMSwap Router: [0x63d8e76143a1fd075981A44e27652aDffEE09F01](https://arbiscan.io/address/0x63d8e76143a1fd075981A44e27652aDffEE09F01)
* MIMSwap Factory: [0x8D0Cd3eEf1794F59F2B3a664Ef07fCAD401FEc73](https://arbiscan.io/address/0x8D0Cd3eEf1794F59F2B3a664Ef07fCAD401FEc73)
* MIMSwap MagicLP: [0x2958dB359D22411cDF9825F8b27f17350a6fC6BB](https://arbiscan.io/address/0x2958dB359D22411cDF9825F8b27f17350a6fC6BB)


# Optimism

## Boxes:

* DegenBox: [0xa93c81f564579381116ee3e007c9fcfd2eba1723](https://optimistic.etherscan.io/address/0xa93c81f564579381116ee3e007c9fcfd2eba1723)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V3:

* Velodrome vOP/USDC: [0x68f498C230015254AFF0E1EB6F85Da558dFf2362](https://optimistic.etherscan.io/address/0x68f498C230015254AFF0E1EB6F85Da558dFf2362)

</details>

## Strategies:

* Velodrome Volatile OP/USDC: [0xA3372CD2178c52fdCB1f6e4c4E93014B4dB3B20d](https://optimistic.etherscan.io/address/0xA3372CD2178c52fdCB1f6e4c4E93014B4dB3B20d)

## Wrappers:

* Velodrome Volatile OP/USDC: [0x6eb1709e0b562097bf1cc48bc6a378446c297c04](https://optimistic.etherscan.io/address/0x6eb1709e0b562097bf1cc48bc6a378446c297c04)

## Withdrawer:

## Omnichain MIM:

* Optimism MIM: [0xb153fb3d196a8eb25522705560ac152eeec57901](https://optimistic.etherscan.io/token/0xb153fb3d196a8eb25522705560ac152eeec57901)
* LzIndirectOFTV2: [0x48686c24697fe9042531B64D792304e514E74339](https://optimistic.etherscan.io/address/0x48686c24697fe9042531B64D792304e514E74339)
* ElevatedMinterBurner: [0x1e188dd74adf8cc95c98714407e88a4a99b759a5](https://optimistic.etherscan.io/address/0x1e188dd74adf8cc95c98714407e88a4a99b759a5)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://optimistic.etherscan.io/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC)


# Kava

## Boxes:

* DegenBox: [0x630FC1758De85C566Bdec1D75A894794E1819d7E](https://kavascan.com/address/0x630FC1758De85C566Bdec1D75A894794E1819d7E)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V4:

* Stargate USDT LP: [0x895731a0C3836a5534561268F15EBA377218651D](https://explorer.kava.io/address/0x895731a0C3836a5534561268F15EBA377218651D)
* MIM/USDT CurveLP: [0x3CFf6F628Ebc88e167640966E67314Cf6466E6A8](https://explorer.kava.io/address/0x3CFf6F628Ebc88e167640966E67314Cf6466E6A8)

</details>

## Strategies:

* Stargate USDT: [0x30D525cbB79D2baaE7637eA748631a6360Ce7c16](https://kavascan.com/address/0x30D525cbB79D2baaE7637eA748631a6360Ce7c16)

## Omnichain MIM:

* Kava MIM: [0x471EE749bA270eb4c1165B5AD95E614947f6fCeb](https://kavascan.com/address/0x471EE749bA270eb4c1165B5AD95E614947f6fCeb)
* LzIndirectOFTV2: [0xc7a161Cfd0e133d289B13692b636B8e8B5CD8d8c](https://kavascan.com/address/0xc7a161Cfd0e133d289B13692b636B8e8B5CD8d8c/read-contract#address-tabs)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://kavascan.com/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC/read-contract#address-tabs)

### MIMSwap:

* MIMSwap Router: [0x526a17c623809792c033c9816Ae9a6fA80aCDfdd](https://kavascan.com/address/0x526a17c623809792c033c9816Ae9a6fA80aCDfdd)
* MIMSwap Factory: [0x7Ad0e580d8458BbeF71EC6A1755c59651E1EAaa7](https://kavascan.com/address/0x7Ad0e580d8458BbeF71EC6A1755c59651E1EAaa7)
* MIMSwap MagicLP: [0x1B77fDaBAa7FefD55f4aC075B6E817b8d773315b](https://kavascan.com/address/0x1B77fDaBAa7FefD55f4aC075B6E817b8d773315b)


# Avalanche C-Chain

## Boxes:

* DegenBox: [0x1fc83f75499b7620d53757f0b01e2ae626aae530](https://snowtrace.io/address/0x1fc83f75499b7620d53757f0b01e2ae626aae530)
* BentoBox: [0xf4f46382c2be1603dc817551ff9a7b333ed1d18f](https://snowtrace.io/address/0xf4f46382c2be1603dc817551ff9a7b333ed1d18f)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V2:

* AVAX: [0x3CFEd0439aB822530b1fFBd19536d897EF30D2a2](https://snowtrace.io/address/0x3CFEd0439aB822530b1fFBd19536d897EF30D2a2)
* AVAX/MIM SLP: [0xAcc6821d0F368b02d223158F8aDA4824dA9f28E3](https://snowtrace.io/address/0xAcc6821d0F368b02d223158F8aDA4824dA9f28E3)

</details>

<details>

<summary>Deprecated Cauldrons:</summary>

* wMEMO-v1: [0x56984F04d2d04B2F63403f0EbeDD3487716bA49d](https://snowtrace.io/address/0x56984F04d2d04B2F63403f0EbeDD3487716bA49d)
* wMEMO-v2: [0x35fA7A723B3B39f15623Ff1Eb26D8701E7D6bB21](https://snowtrace.io/address/0x35fA7A723B3B39f15623Ff1Eb26D8701E7D6bB21)
* xJOE: [0x3b63f81Ad1fc724E44330b4cf5b5B6e355AD964B](https://snowtrace.io/address/0x3b63f81Ad1fc724E44330b4cf5b5B6e355AD964B)
* AVAX/USDC.e-jLP: [0x95cCe62C3eCD9A33090bBf8a9eAC50b699B54210](https://snowtrace.io/address/0x95cCe62C3eCD9A33090bBf8a9eAC50b699B54210)
* AVAX/USDT.e-jLP: [0x0a1e6a80E93e62Bd0D3D3BFcF4c362C40FB1cF3D](https://snowtrace.io/address/0x0a1e6a80E93e62Bd0D3D3BFcF4c362C40FB1cF3D)
* AVAX/MIM-jLP: [0x2450Bf8e625e98e14884355205af6F97E3E68d07](https://snowtrace.io/address/0x2450Bf8e625e98e14884355205af6F97E3E68d07)

</details>

## Strategies:

## Wrappers:

## Withdrawer:

## Omnichain MIM:

* Avalanche MIM: [0x130966628846bfd36ff31a822705796e8cb8c18d](https://snowtrace.io/token/0x130966628846bfd36ff31a822705796e8cb8c18d)
* LzIndirectOFTV2: [0xB3a66127cCB143bFB01D3AECd3cE9D17381B130d](https://snowtrace.io/address/0xB3a66127cCB143bFB01D3AECd3cE9D17381B130d)
* ElevatedMinterBurner: [0x9ba780f8a517e2245892a388427973c8b7c3b769](https://snowtrace.io/address/0x9ba780f8a517e2245892a388427973c8b7c3b769)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://snowtrace.io/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC)


# Polygon POS

## Omnichain MIM:

* Polygon MIM: [0x49a0400587a7f65072c87c4910449fdcc5c47242](https://polygonscan.com/token/0x49a0400587a7f65072c87c4910449fdcc5c47242)
* LzIndirectOFTV2: [0xca0d86afc25c57a6d2aCdf331CaBd4C9CEE05533](https://polygonscan.com/address/0xca0d86afc25c57a6d2aCdf331CaBd4C9CEE05533)
* ElevatedMinterBurner: [0x8e7982492f6d330d0e1aab9e110d7dffc69c20fc](https://polygonscan.com/address/0x8e7982492f6d330d0e1aab9e110d7dffc69c20fc)
* OFTWrapper: [0xe1261e47b08a22df93af46889ee504c2aa6dfd4c](https://polygonscan.com/address/0xe1261e47b08a22df93af46889ee504c2aa6dfd4c#readContract)


# Fantom Opera

## Boxes:

* DegenBox: [0x74a0bca2eeedf8883cb91e37e9ff49430f20a616](https://ftmscan.com/address/0x74a0bca2eeedf8883cb91e37e9ff49430f20a616)
* BentoBox: [0xf5bce5077908a1b7370b9ae04adc565ebd643966](https://ftmscan.com/address/0xf5bce5077908a1b7370b9ae04adc565ebd643966)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V2:

* FTM: [0x8E45Af6743422e488aFAcDad842cE75A09eaEd34](https://ftmscan.com/address/0x8E45Af6743422e488aFAcDad842cE75A09eaEd34)
* FTM: [0xd4357d43545F793101b592bACaB89943DC89d11b](https://ftmscan.com/address/0xd4357d43545F793101b592bACaB89943DC89d11b)
* yvWFTM: [0xed745b045f9495B8bfC7b58eeA8E0d0597884e12](https://ftmscan.com/address/0xed745b045f9495B8bfC7b58eeA8E0d0597884e12)
* xBOO: [0xa3Fc1B4b7f06c2391f7AD7D4795C1cD28A59917e](https://ftmscan.com/address/0xa3Fc1B4b7f06c2391f7AD7D4795C1cD28A59917e)
* FTM/MIM-Spirit: [0x7208d9F9398D7b02C5C22c334c2a7A3A98c0A45d](https://ftmscan.com/address/0x7208d9F9398D7b02C5C22c334c2a7A3A98c0A45d)
* FTM/MIM-Spooky: [0x4fdfFa59bf8dda3F4d5b38F260EAb8BFaC6d7bC1](https://ftmscan.com/address/0x4fdfFa59bf8dda3F4d5b38F260EAb8BFaC6d7bC1)

</details>

<details>

<summary>Deprecated Cauldrons:</summary>

* ICE: [0xF08e4cc9015a1B8F49A8EEc7c7C64C14B9abD7C7](https://ftmscan.com/address/0xF08e4cc9015a1B8F49A8EEc7c7C64C14B9abD7C7)
* FTM: [0xEf7A0bd972672b4eb5DF28f2F544f6b0BF03298a](https://ftmscan.com/address/0xEf7A0bd972672b4eb5DF28f2F544f6b0BF03298a)

</details>

## Omnichain MIM:

* Fantom MIM: [0x82f0b8b456c1a451378467398982d4834b6829c1](https://ftmscan.com/token/0x82f0b8b456c1a451378467398982d4834b6829c1)
* LzIndirectOFTV2: [0xc5c01568a3B5d8c203964049615401Aaf0783191](https://ftmscan.com/address/0xc5c01568a3B5d8c203964049615401Aaf0783191)
* ElevatedMinterBurner: [0x64c65549c10d86de6f00c3b0d5132d8f742af8c4](https://ftmscan.com/address/0x64c65549c10d86de6f00c3b0d5132d8f742af8c4)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://ftmscan.com/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC)


# BNB Chain

## Boxes:

* DegenBox: [0x090185f2135308BaD17527004364eBcC2D37e5F6](https://bscscan.com/address/0x090185f2135308BaD17527004364eBcC2D37e5F6)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V2:

* BNB: [0x692CF15F80415D83E8c0e139cAbcDA67fcc12C90](https://bscscan.com/address/0x692CF15F80415D83E8c0e139cAbcDA67fcc12C90)
* CAKE: [0xF8049467F3A9D50176f4816b20cDdd9bB8a93319](https://bscscan.com/address/0xF8049467F3A9D50176f4816b20cDdd9bB8a93319)

</details>

## Strategies:

* CAKE: [0x08B918dD18E087893bb9d711d9E0BBaA7a63Ef63](https://bscscan.com/address/0x08B918dD18E087893bb9d711d9E0BBaA7a63Ef63)

## Omnichain MIM:

* BNBChain MIM: [0xfe19f0b51438fd612f6fd59c1dbb3ea319f433ba](https://bscscan.com/token/0xfe19f0b51438fd612f6fd59c1dbb3ea319f433ba)
* LzIndirectOFTV2: [0x41D5A04B4e03dC27dC1f5C5A576Ad2187bc601Af](https://bscscan.com/address/0x41D5A04B4e03dC27dC1f5C5A576Ad2187bc601Af)
* ElevatedMinterBurner: [0x79533f85479e04d2214305638b6586b724bec951](https://bscscan.com/address/0x79533f85479e04d2214305638b6586b724bec951)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://bscscan.com/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC)


# Moonriver

## Omnichain MIM:

* Moonriver MIM: [0x0cae51e1032e8461f4806e26332c030e34de3adb](https://moonriver.moonscan.io/address/0x0cae51e1032e8461f4806e26332c030e34de3adb)
* LzIndirectOFTV2: [0xeF2dBDfeC54c466F7Ff92C9c5c75aBB6794f0195](https://moonriver.moonscan.io/address/0xeF2dBDfeC54c466F7Ff92C9c5c75aBB6794f0195)
* ElevatedMinterBurner: [0x6e858b0dd9a9dcdf710b28c236292e30ba079728](https://moonriver.moonscan.io/address/0x6e858b0dd9a9dcdf710b28c236292e30ba079728)
* OFTWrapper: [0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC](https://moonriver.moonscan.io/address/0x287176dfBEC7E8cee0f876FC7B52960ee1784AdC)


# Base

## Omnichain MIM:

* Base MIM: [0x4A3A6Dd60A34bB2Aba60D73B4C88315E9CeB6A3D](https://basescan.org/token/0x4A3A6Dd60A34bB2Aba60D73B4C88315E9CeB6A3D)
* LzIndirectOFTV2: [0x4035957323fc05ad9704230e3dc1e7663091d262](https://basescan.org/address/0x4035957323fc05ad9704230e3dc1e7663091d262)
* FeeHandler:\
  [0x52B2773FB2f69d565C651d364f0AA95eBED097E4](https://basescan.org/address/0x52B2773FB2f69d565C651d364f0AA95eBED097E4)


# Linea

## Omnichain MIM:

* Linea MIM: [0xdd3b8084af79b9bae3d1b668c0de08ccc2c9429a](https://lineascan.build/token/0xdd3b8084af79b9bae3d1b668c0de08ccc2c9429a)
* LzIndirectOFTV2: [0x60bbefe16dc584f9af10138da1dfbb4cdf25a097](https://lineascan.build/address/0x60bbefe16dc584f9af10138da1dfbb4cdf25a097)
* FeeHandler: [0x41b191911cf3482b31cfcd65bd3c79e76b26b35a](https://lineascan.build/address/0x41b191911cf3482b31cfcd65bd3c79e76b26b35a)


# Blast Mainnet

## Boxes:

* BlastBox: [0xC8f5Eb8A632f9600D1c7BC91e97dAD5f8B1e3748](https://blastscan.io/address/0xC8f5Eb8A632f9600D1c7BC91e97dAD5f8B1e3748#code)

## Cauldrons:

<details>

<summary>Active Cauldrons:</summary>

#### V4:

* WETH: [0x79e8CAd80E2aA49A246B789584C45aAB1CFe402e](https://blastscan.io/address/0x79e8CAd80E2aA49A246B789584C45aAB1CFe402e)

</details>

## MIMSwap | Gold Points:

As part of the Liquidity Launch Event (LLE) happening on Blast for the launch of MIMSwap, this contract will be used to store the liquidity and receive Gold Points.

### Gold Points:

* LLE Contract : [0xa64b73699cc7334810e382a4c09caec53636ab96](https://blastscan.io/address/0xa64b73699cc7334810e382a4c09caec53636ab96)
* Gold Point Receiver: [0xa64B73699Cc7334810E382A4C09CAEc53636Ab96](https://blastscan.io/address/0xa64B73699Cc7334810E382A4C09CAEc53636Ab96)
* Point Operator: [0xD1025F1359422Ca16D9084908d629E0dBa60ff28](https://blastscan.io/address/0xD1025F1359422Ca16D9084908d629E0dBa60ff28)

### MIMSwap:

* MIMSwap Router: [0x85FAAfc31bc8B16bE7039F869cD2006dA257b705](https://blastscan.io/address/0x85FAAfc31bc8B16bE7039F869cD2006dA257b705)
* MIMSwap Factory: [0x7E05363E225c1c8096b1cd233B59457104B84908](https://blastscan.io/address/0x7E05363E225c1c8096b1cd233B59457104B84908)
* MIMSwap MagicLP: [0xeDa89B8b19eBEf5FC0D5e21ebAd174366C230D35](https://blastscan.io/address/0xeDa89B8b19eBEf5FC0D5e21ebAd174366C230D35)

## Active Cauldrons:

### V4:

* WETH: [0x79e8CAd80E2aA49A246B789584C45aAB1CFe402e](https://blastscan.io/address/0x79e8cad80e2aa49a246b789584c45aab1cfe402e#code)
  * Redstone Oracle Aggregator: [0x86e761F620b7ac8Ea373e0463C8c3BCCE7bD385B](https://blastscan.io/address/0x86e761F620b7ac8Ea373e0463C8c3BCCE7bD385B)

## Omnichain MIM:

* MIM: [0x76DA31D7C9CbEAE102aff34D3398bC450c8374c1](https://blastscan.io/address/0x76DA31D7C9CbEAE102aff34D3398bC450c8374c1)
* LzIndirectOFTV2: [0xcA8A205a579e06Cb1bE137EA3A5E5698C091f018](https://blastscan.io/address/0xcA8A205a579e06Cb1bE137EA3A5E5698C091f018)
* FeeHandler: [0x630FC1758De85C566Bdec1D75A894794E1819d7E](https://blastscan.io/address/0x630FC1758De85C566Bdec1D75A894794E1819d7E)

## Omnichain SPELL:

* SPELL: [0x741A2378a8E003acbAdbc21506bC624062Ace36E](https://blastscan.io/address/0x741A2378a8E003acbAdbc21506bC624062Ace36E)
* LzIndirectOFTV2: [0x6E4358c889bb7871061904Be31Fe47C3B8b7F442](https://blastscan.io/address/0x6E4358c889bb7871061904Be31Fe47C3B8b7F442)
* FeeHandler: [0xA3372CD2178c52fdCB1f6e4c4E93014B4dB3B20d](https://blastscan.io/address/0xA3372CD2178c52fdCB1f6e4c4E93014B4dB3B20d)


