mStable-protocol

πŸ—οΈ How to integrate mStable into your smart contracts.

Installation

The mStable protocol contracts are available as an npm module that may be included in your projects.

Using npm

npm install @mstable/protocol --save-dev

Using yarn

yarn add @mstable/protocol --dev

An example

In this following code examples you will learn how to integrate the mStable protocol. This represents a basic integration and more advanced developers may wish to go straight to the nested API docs or the smart contracts on Github. Deployed contract addresses for Ropsten, Kovan and Mainnet are listed here.

The examples given here are also available as a single contract in the mStable example Github repository.

mStable smart contracts are compiled against version0.5.16 of Solidity.

These examples showcase a basic integration using the npm module and are not considered safe. Your application should build in relevant access control and safety checks.

​

Minting mUSD

Minting takes one or more of the supported tokens and issues mUSD. The following is an example that shows how you can add minting mUSD to a smart contract. This example assumes there are some supported stablecoins held on the contract.

Suppose we are minting mUSD with USDC in this example. We first send some USDC to the contract and then call the external mint function with the address of the USDC contract and the amount to send. The transaction will return the equivalent amount of mUSD to the contract.

pragma solidity ^0.5.16;
​
import { IMasset } from "@mstable/protocol/contracts/interfaces/IMasset.sol";
​
...
​
/**
* @dev This is a basic example of minting and assumes that some _bAsset
* is on the contract. In reality it is likely this would be managed
* on a per account basis.
* @param _bAsset Address of the bAsset (stablecoin) to mint with
* @param _bAssetQuanity The amount of bAsset to mint
*
*/
function mint(
address _bAsset,
uint _bAssetQuanity
) external returns (uint massetMinted) {
​
// application logic
​
IERC20(_bAsset).safeApprove(massetContract, uint256(-1));
return IMasset(massetContract).mint(_bAsset, _bAssetQuanity);
}

Depositing into SAVE

Once you have minted mUSD a contract may deposit into the SAVE contract to begin earning yield. This example assumes that mUSD is on the contract. After calling the external deposit function, mUSD will be deposited into the SAVE contract and begin earning yield.

pragma solidity ^0.5.16;
​
import { IMasset } from "@mstable/protocol/contracts/interfaces/IMasset.sol";
import { ISavingsContract } from "@mstable/protocol/contracts/interfaces/ISavingsContract.sol";
​
...
​
​
/**
* @dev This is a basic example of deposits and assumes that some mUSD
* is on the contract. In reality it is likely this would be managed
* on a per account basis
* @param _amount The amount of mUSD to deposit
*/
function deposit(
uint _amount
) external returns (uint256 creditIssued) {
​
// application logic
IERC20(massetContract).safeApprove(savingsContract, uint256(-1));
return ISavingsContract(savingsContract).depositSavings(_amount);
}
​

Withdrawing from SAVE

mUSD may be withdrawn from the SAVE contract at any point. This example assumes that the calling contract has deposited into SAVE. Calling the external withdraw function returns mUSD from the SAVE contract to the calling contract.

pragma solidity ^0.5.16;
​
import { IMasset } from "@mstable/protocol/contracts/interfaces/IMasset.sol";
import { ISavingsContract } from "@mstable/protocol/contracts/interfaces/ISavingsContract.sol";
​
...
​
/**
* @dev This is a basic example of withdrawing mUSD and assumes that some mUSD
* is on the contract. In reality it is likely this would be managed
* on a per account basis
* @param _amount The amount of mUSD to withdraw
*/
function withdraw(
uint _amount
) external {
​
// application logic
​
uint256 creditsToRedeem = helper.getSaveRedeemInput(save, _amount);
ISavingsContract(savingsContract).redeem(creditsToRedeem);
// application logic
}
​

Redeeming from mUSD

Underlying assets may be redeemed from mUSD as the original asset that was deposited or as a mix of any of the underlying assets available in the basket. In this example it is assumed that the contract holds some mUSD and wishes to redeem an underlying stablecoin.

By calling the external redeem the caller may redeem an underlying asset. After the transaction completes mUSD will be burned and the underlying asset will be returned to the calling contract.

pragma solidity ^0.5.16;
​
import { IMasset } from "@mstable/protocol/contracts/interfaces/IMasset.sol";
​
...
​
/**
* @dev This is a basic example of redeeming a bAsset and assumes that
* some mUSD is on the contract. In reality it is likely this would be managed
* on a per account basis
* @param _bAsset Address of the bAsset (stablecoin) to redeem with
* @param _bAssetQuanity The amount of bAsset to mint
*
*/
function redeem(
address _bAsset,
uint _bAssetQuanity
) external returns (uint256 massetRedeemed) {
​
// application logic
​
IMasset(massetContract).redeem(_bAsset, _bAssetQuanity);
// application logic
}