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


---

# Agent Instructions: Querying This Documentation

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

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

```
GET https://dev.abracadabra.money/core-contracts/mimswap.md?ask=<question>
```

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

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