# mUSD

An incentivised constant sum market maker with hard limits at max region. This supports low slippage swaps and applies penalties towards min and max regions. AMM produces a stablecoin (mAsset) and redirects lending market interest and swap fees to the savings contract, producing a second yield-bearing asset.

`_minOutputQuantity` is used to limit slippage when swapping, minting or redeeming. Useful for preventing Sandwich and Frontrunning attacks.

Contracts are upgradable except for integration contracts. The ProtocolDAO multisig can migrate the assets from one integration contract to another.

{% hint style="warning" %}
Note that the mUSD on Ethereum mainnet is not fungible with the mUSD on Polygon. This is due to the fact that the basket of underlying assets is separate and the composition is different.

On Ethereum mUSD is composed of DAI, USDC, USDT and sUSD. \
On Polygon mUSD is composed of DAI, USDC and USDT.
{% endhint %}

{% tabs %}
{% tab title="Polygon" %}

| Contracts                                                                                        | Address                                                                                                                  |
| ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ |
| [mUSD](https://github.com/mstable/mStable-contracts/blob/master/contracts%2Fmasset%2FMasset.sol) | [0xe840b73e5287865eec17d250bfb1536704b43b21](https://polygonscan.com/address/0xe840b73e5287865eec17d250bfb1536704b43b21) |
| {% endtab %}                                                                                     |                                                                                                                          |
| {% endtabs %}                                                                                    |                                                                                                                          |

mUSD follows the ERC20 standard. The non-standard [`decreaseAllowance`](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#ERC20-decreaseAllowance-address-uint256-) and [`increaseAllowance`](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#ERC20-increaseAllowance-address-uint256-) functions have been added to mitigate the well-known issues around setting allowances. These are based on the OpenZeppelin ERC20 implementation.

## ERC-20 Functions

### totalSupply()

`function totalSupply () external returns (uint256)`

Returns the amount of tokens in existence.

### balanceOf()

`function balanceOf () external returns (uint256)`

Returns the amount of tokens owned by `account`.

### transfer()

`function transfer () external returns (bool)`

Moves `amount` tokens from the caller's account to `recipient`.

Returns a boolean value indicating whether the operation succeeded.

Emits a {Transfer} event.

### allowance()

`function allowance () external returns (uint256)`

Returns the remaining number of tokens that`spender`will be allowed to spend on behalf of`owner`through {transferFrom}. This is zero by default.

This value changes when {approve} or {transferFrom} are called.

### approve()

`function approve () external returns (bool)`

Sets `amount` as the allowance of `spender` over the caller's tokens.

Returns a boolean value indicating whether the operation succeeded.

IMPORTANT: Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: <https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729>

Emits an {Approval} event.

### transferFrom()

`function transferFrom () external returns (bool)`

Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism. `amount` is then deducted from the caller's allowance.

Returns a boolean value indicating whether the operation succeeded.

Emits a {Transfer} event.&#x20;

### increaseAllowance()

`function increaseAllowance () public returns (bool)`

Atomically increases the allowance granted to `spender` by the caller.

This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}.

Emits an {Approval} event indicating the updated allowance.

Requirements:

* `spender` cannot be the zero address.

### decreaseAllowance()

`function decreaseAllowance () public returns (bool)`

Atomically decreases the allowance granted to `spender` by the caller.

This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}.

Emits an {Approval} event indicating the updated allowance.

Requirements:

* `spender` cannot be the zero address.
* `spender` must have allowance for the caller of at least

  `subtractedValue`.

## Functions

### mint()

`function mint (address _input, uint256 _inputQuantity, uint256 _minOutputQuantity, address _recipient) external returns (uint256 mintOutput)`

Mint a single bAsset, at a 1:1 ratio with the bAsset. This contract must have approval to spend the senders bAsset

| Parameter            | Type    | Description                                                           |
| -------------------- | ------- | --------------------------------------------------------------------- |
| `_input`             | address | Address of the bAsset to deposit for the minted mAsset.               |
| `_inputQuantity`     | uint256 | Quantity in bAsset units                                              |
| `_minOutputQuantity` | uint256 | Minimum mAsset quantity to be minted. This protects against slippage. |
| `_recipient`         | address | Recipient of the newly minted mAsset tokens                           |

### mintMulti()

`function mintMulti (address[] _inputs, uint256[] _inputQuantities, uint256 _minOutputQuantity, address _recipient) external returns (uint256 mintOutput)`

Mint with multiple bAssets, at a 1:1 ratio to mAsset. This contract must have approval to spend the senders bAssets

<table data-header-hidden><thead><tr><th width="250.5076452599389">Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td>Parameter</td><td>Type</td><td>Description</td></tr><tr><td><code>_inputs</code></td><td>address[]</td><td>Non-duplicate address array of bASset addresses to deposit for the minted mAsset tokens.</td></tr><tr><td><code>_inputQuantities</code></td><td>uint256[]</td><td>Quantity of each bAsset to deposit for the minted mAsset. Order of array should mirror the above bAsset addresses.</td></tr><tr><td><code>_minOutputQuantity</code> </td><td>uint256</td><td>Minimum mAsset quantity to be minted. This protects against slippage.</td></tr><tr><td><code>_recipient</code></td><td>address</td><td>Address to receive the newly minted mAsset tokens</td></tr></tbody></table>

### getMintOutput()

`function getMintOutput (address _input, uint256 _inputQuantity) external returns (uint256 mintOutput)`

Get the projected output of a given mint

| Parameter        | Type    | Description                                            |
| ---------------- | ------- | ------------------------------------------------------ |
| `_input`         | address | Address of the bAsset to deposit for the minted mAsset |
| `_inputQuantity` | uint256 | Quantity in bAsset units                               |

### getMintMultiOutput()

`function getMintMultiOutput (address[] _inputs, uint256[] _inputQuantities) external returns (uint256 mintOutput)`

Get the projected output of a given mint

| Parameter          | Type       | Description                                                                                  |
| ------------------ | ---------- | -------------------------------------------------------------------------------------------- |
| `_inputs`          | address\[] | Non-duplicate address array of addresses to bAssets to deposit for the minted mAsset tokens. |
| `_inputQuantities` | uint256\[] | Quantity of each bAsset to deposit for the minted mAsset.                                    |

### swap()

`function swap (address _input, address _output, uint256 _inputQuantity, uint256 _minOutputQuantity, address _recipient) external returns (uint256 swapOutput)`

Swaps one bAsset for another bAsset using the bAsset addresses. bAsset <> bAsset swaps will incur a small fee (swapFee()).

| Parameter            | Type    | Description                                                               |
| -------------------- | ------- | ------------------------------------------------------------------------- |
| `_input`             | address | Address of bAsset to deposit                                              |
| `_output`            | address | Address of bAsset to receive                                              |
| `_inputQuantity`     | uint256 | Units of input bAsset to swap                                             |
| `_minOutputQuantity` | uint256 | Minimum quantity of the swap output asset. This protects against slippage |
| `_recipient`         | address | Address to transfer output asset to                                       |

### getSwapOutput()

`function getSwapOutput (address _input, address _output, uint256 _inputQuantity) external returns (uint256 swapOutput)`

Determines both if a trade is valid, and the expected fee or output. Swap is valid if it does not result in the input asset exceeding its maximum weight.

| Parameter        | Type    | Description                   |
| ---------------- | ------- | ----------------------------- |
| `_input`         | address | Address of bAsset to deposit  |
| `_output`        | address | Address of bAsset to receive  |
| `_inputQuantity` | uint256 | Units of input bAsset to swap |

### redeem()

`function redeem (address _output, uint256 _mAssetQuantity, uint256 _minOutputQuantity, address _recipient) external returns (uint256 outputQuantity)`

Redeems a specified quantity of mAsset in return for a bAsset specified by bAsset address. The bAsset is sent to the specified recipient. The bAsset quantity is relative to current vault balance levels and desired mAsset quantity. The quantity of mAsset is burnt as payment. A minimum quantity of bAsset is specified to protect against price slippage between the mAsset and bAsset.

| Parameter            | Type    | Description                                                                               |
| -------------------- | ------- | ----------------------------------------------------------------------------------------- |
| `_output`            | address | Address of the bAsset to receive                                                          |
| `_mAssetQuantity`    | uint256 | Quantity of mAsset to redeem                                                              |
| `_minOutputQuantity` | uint256 | Minimum bAsset quantity to receive for the burnt mAssets. This protects against slippage. |
| `_recipient`         | address | Address to transfer the withdrawn bAssets to.                                             |

### redeemMasset()

`function redeemMasset (uint256 _mAssetQuantity, uint256[] _minOutputQuantities, address _recipient) external returns (uint256[] outputQuantities)`

Credits a recipient with a proportionate amount of bAssets, relative to current vault balance levels and desired mAsset quantity. Burns the mAsset as payment.

| Parameter              | Type       | Description                             |
| ---------------------- | ---------- | --------------------------------------- |
| `_mAssetQuantity`      | uint256    | Quantity of mAsset to redeem            |
| `_minOutputQuantities` | uint256\[] | Min units of output to receive          |
| `_recipient`           | address    | Address to credit the withdrawn bAssets |

### redeemExactBassets()

`function redeemExactBassets (address[] _outputs, uint256[] _outputQuantities, uint256 _maxMassetQuantity, address _recipient) external returns (uint256 mAssetQuantity)`

Credits a recipient with a certain quantity of selected bAssets, in exchange for burning the relative Masset quantity from the sender. Sender also incurs a small fee on the outgoing asset.

| Parameter            | Type       | Description                                                                               |
| -------------------- | ---------- | ----------------------------------------------------------------------------------------- |
| `_outputs`           | address\[] | Addresses of the bAssets to receive                                                       |
| `_outputQuantities`  | uint256\[] | Units of the bAssets to redeem                                                            |
| `_maxMassetQuantity` | uint256    | Maximum mAsset quantity to burn for the received bAssets. This protects against slippage. |
| `_recipient`         | address    | Address to receive the withdrawn bAssets                                                  |

### getRedeemOutput()

`function getRedeemOutput (address _output, uint256 _mAssetQuantity) external returns (uint256 bAssetOutput)`

Gets the estimated output from a given redeem

| Parameter         | Type    | Description                      |
| ----------------- | ------- | -------------------------------- |
| `_output`         | address | Address of the bAsset to receive |
| `_mAssetQuantity` | uint256 | Quantity of mAsset to redeem     |

### getRedeemExactBassetsOutput()

`function getRedeemExactBassetsOutput (address[] _outputs, uint256[] _outputQuantities) external returns (uint256 mAssetQuantity)`

Gets the estimated output from a given redeem

| Parameter           | Type       | Description                        |
| ------------------- | ---------- | ---------------------------------- |
| `_outputs`          | address\[] | Addresses of the bAsset to receive |
| `_outputQuantities` | uint256\[] | Quantities of bAsset to redeem     |

### getBasket()

`function getBasket () external returns (bool, bool)`

Get basket details for `Masset_MassetStructs.Basket`

### getBassets()

`function getBassets () external returns (struct BassetPersonal[] personal, struct BassetData[] bData)`

Get data for a all bAssets in basket

### getBasset()

`function getBasset (address _bAsset) external returns (struct BassetPersonal personal, struct BassetData bData)`

Get data for a specific bAsset, if it exists

| Parameter | Type    | Description       |
| --------- | ------- | ----------------- |
| `_bAsset` | address | Address of bAsset |

### getConfig()

`function getConfig () external returns (struct InvariantConfig config)`

Gets all config needed for general InvariantValidator calls

### getPrice()

`function getPrice () external returns (uint256 price, uint256 k)`

Gets the price of the fpToken, and invariant value k
