See it on github

Integration to RIF on Chain Platform

  1. Introduction to MoC
    1. The Moc Contract
    2. MoC State Contracts
  2. Getting RIFPros
    1. Minting RIFPros
    2. Redeeming RIFPros
  3. Getting RDOCs
    1. Minting RDOCs
    2. Redeeming RDOCs
  4. Getting RIF2X
    1. Minting RIF2X
    2. Redeeming RIF2X
  5. From outside the blockchain
    1. Using RSK nodes
    2. Using web3
    3. Official Money on Chain ABIS
    4. Events
    5. Example code minting RIFPros
    6. Example code minting RIFPros without truffle
    7. Example code redeeming RIFPros
    8. Example code redeeming RIFPros without truffle
    9. Example code minting RDOC
    10. Example code redeeming RDOC Request
    11. Example code redeeming free RDOC
    12. Example code redeeming all RDOC
    13. Example code minting RIF2X
    14. Example code redeeming RIF2X

Introduction to MoC

Money On Chain is a suite of smart contracts whose purpose is providing:

Money on Chain runs on the RSK network and uses the RIF token as reserve assets to back Money on Chain. You can find more info on the RIF token and decentralized economies here.

The rationale behind this is that deposits of RIF help collateralize the RDOCs, RIFPro absorbs the USD-RIF rate fluctuations, and RIF2X is leveraged borrowing value from RIFPro and RDOC holders, with a daily interest rate being paid to the former.

MoC system is a network of cooperative smart contracts working together to ultimately provide a US dollar pegged ERC20 Token (RDOC). In this sense, the contracts we can categorize them into 4 categories:

Also you can read official information about MoC architecture and Money on Chain's smart contracts

The Moc Contract

The Money On Chain's Smart Contract suite is in control of the minting and redeeming of its tokens, including the RIFPro, RDOC and RIF2X tokens. This means that the generation of new tokens is controlled programmatically by said suite. To get some new tokens you should interact with the suite. The entry point is the MoC smart contract whose addresses are available on the following networks:

In the world of second and third generation blockchains it is not possible to update the code of an already deployed smart contract. If we need to fix a bug or update the logic of a function, then we can use the proxy architecture pattern.

The proxy pattern allows all function calls to go through a Proxy contract that will redirect the message to another smart contract that contains the business logic. MoC is a Proxy Contract.

When the logic needs to be updated, a new version of your business logic contract is created and the reference is updated in the proxy contract. You can read more about proxies contracts here.

MoC precisions

The Money on Chain system handles different types of currency precision to operate with tokens and RIF. The MoCLibConnection contract defines 2 variables that are used across the platform:

MoC State Contracts

MocInrate

Deals with interest payments on leverage deposits and defines the interest rates to trade with RDOC and RIF2X. Also with the commission rates to operate on the Money on Chain platform.

MocState

This contract holds the system variables to manage the state, whether it's the state itself or the liquidation thresholds, as well as many view functions to access and evaluate it.

Getting RIFPros

In this tutorial we will show you how to get RIFPro tokens.

The RIFPro, as you may already know, is an ERC20 token.(If you didn't, and you don't know what is exactly an ERC20 token here is a full explanation of it).

This means that most wallets like Nifty and MetaMask can handle them if you tell them to (MetaMask tutorial on how to do it, Nifty is very similar to it so you should follow that link too if you are using the latter).

That RIFPro is an ERC20 Token also means that any user that has already some tokens can trade them to you in exchange for a service or for another token.

But in some circumstances you may not find such a user. In those cases, you may be happy to know that you can create them(or mint them, as it is usually said) using the Smart Contracts.

Minting RIFPros

In this tutorial the method(or function) that is of interest to us is function mintRiskPro(uint256 resTokensToMint) public.

You must approve the amount of RIF token that you are willing to use on the Money on Chain platform before minting RIFPro. The approved amount is called allowedBalance. You can do this by invoking function approve(address _spender, uint256 _value) public returns (bool success) that is part of the ERC20 standard.

Parameters of the operation

The resTokensToMint parameter

It is the amount the contract will use to actually mint RIFPros, i.e. it will not be used to pay commission, all of this funds will be transformed purely on RIFPros.
This parameter is a RIF amount and uses a precision of the type reservePrecision that contains 18 decimal places is defined in MoCLibConnection contract.

Maybe, depending on the state of the contract, a value lesser than resTokensToMint will be used to mint the RIFPros. In that case, all the extra RIFs will be sent to you.

You have to take into consideration that it will be split in three.

allowedBalance (RIF Token) >= resTokensToMint + resTokensToMint * commissionRate

Gas limit and gas price

This two values are a parameter of the transaction, this is not used in the contract and it is usually managed by your wallet(you should read about them if you are developing and you don't know exactly what are they) but you should take them into account when trying to send all of your funds to mint some RIFPros.

Possible failures

This operation may fail if one of the following scenarios occurs:

The MoC contract is liquidated:

In the extraneous case where a coverage that barely covers the stable tokens funds is reached, the contract will liquidate all of its assets. If this state occurs, no more RIFPros will be available for minting.
To know if the contract is liquidated you can ask the MocState for the state, this will return a 0 if liquidated(it is actually an enum).

The MoC contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. You can get more information about stoppables contracts here
In that state, the contract doesn't allow minting any type of token.

To know if this is the case you can ask to MoC if it's paused().

You allowed too few funds:

If the RIF funds you allowed doesn't cover the amount you specified on resTokensToMint.

If this is the case the transaction will revert, all your funds will be returned (except the fee paid to the network). The error message will be "amount is not enough".

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

How-to

In the following sections we will give some code on how this can be done through a Smart Contract or directly, with a console or with an app.

Smart Contract​


To create a new Smart Contract that uses the Money On Chain platform, you can use any language and IDE you want. In this tutorial, we will show you how to do it using Solidity language, Truffle Framework and NPM.
Truffle framework offers some template projects that you can use to develop applications that use smart contracts. You can get more information here.
Assuming you already have your project up and running (if you don't, please follow this link) the only extra thing you need to do is to install our repo as a dependency in your NPM project. In order you need to do this you just need to run the following command.

npm install --save -E git+https://[email protected]/money-on-chain/main-RIF-contract.git


Having done that lets you use our contract as a dependency to your contract. For this let's suppose you are doing some kind of contract that when executing a certain task charges a fixed commission. Now let's suppose that the commission is sent in RIFs because it is easier for the user but actually you want some RIFPros. The good news is that you can do this instantly just by minting them. The code necessary to do this is actually pretty simple.

You just have to import the contract

import 'money-on-chain/contracts/MoC.sol';
import 'money-on-chain/contracts/MoCInrate.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​

​and, finally, when you receive a commission, exchange it for some RIFPros

uint256 resTokensToMint = 100000000;
if (resTokensToMint <= moc.getAllowance(msg.sender)){
    uint256 commissionOfMoC = mocInrate.calcCommissionValue(msg.value);
    moc.mintRiskPro(resTokensToMint-commissionOfMoC);
}


You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIFPro token.

This will leave you with a contract similar to the following

pragma solidity 0.5.8;
​
import "money-on-chain/contracts/MoC.sol";
import "money-on-chain/contracts/MoCInrate.sol";
import "money-on-chain/contracts/token/RiskProToken.sol";
// Here you will import your own dependencies
​
contract YourMintingRiskProContract {
    // Address of the MoC contract
    MoC public moc;
    // Address of the MocInrate contract
    MoCInrate public mocInrate;
    // Address of the RIFPro token
    RiskProToken public riskPro;
    // Address that will receive all the commissions
    address public receiverAddress;
    // rest of your variables
​
    constructor (MoC _moc, MoCInrate _mocInrate, RiskProToken _riskPro, address _receiverAddress) public {
        moc = _moc;
        mocInrate = _mocInrate;
        riskPro = _riskPro;
        receiverAddress = _receiverAddress;
        // You could have more variables to initialize here
    }
​
    function doTask(uint256 _resTokensToMint) public {
        //We compute the commision.
​        uint256 commission = mocInrate.calcCommissionValue(_resTokensToMint);
        //We compute the resTokensToMint.
        uint256 resTokensToMint = _resTokensToMint - commission;
        // Mint some new RIFPro
        moc.mintRiskPro(_resTokensToMint);
​        // Transfer it to your receiver account
        riskPro.transfer(receiverAddress, riskPro.balanceOf(address(this)));
        // Rest of the function to actually perform the task
    }
    // rest of your contract
}
​
​

And that is it, the only thing left to do is to add in the truffle migrations scripts the address to MoC and BPro when deploying YourContract and you are done.
​​

Redeeming RIFPros

The Money On Chain's Smart Contract suite is in control of the redeeming of its tokens, including the RIFPro token. This means that the return of RIFPros is controlled programmatically by said suite. ​A user can "sell" their RIFPro back to the contract and recover the corresponding amount of RIF.

This means that to redeem RIFPros you must interact with the suite. The entry point are the same as explained in Minting RIFPros.

In this tutorial the method(or function) that is of interest to us is function redeemRiskPro(uint256 riskProAmount) public.

Parameters of the operation

The riskProAmount parameter

It is the amount that the contract will use to redeem RIFPros and to calculate commissions. All of these funds will be transformed exclusively into RIF.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places and is defined in MoCLibConnection contract.
Money on Chain is a dynamic system that allows you to redeem a maximum amount of RIFPros and can be obtained by calling the absoluteMaxRiskPro() view of the MocState contract.

The redeeming process is divided into 3 parts:
The first part transforms the amount riskProAmount into an RIF amount, but 3 things can happen:

userBalance = riskProToken.balanceOf(user);
userAmount  = Math.min(riskProAmount, userBalance);

riskProFinalAmount = Math.min(userAmount, absoluteMaxRiskPro);

The second part will be used to pay the commission, this part is a percentage of the previous part. The exact percentage is established in the variable commissionRate of the contract MocInrate. The current value is 0.002 and can be queried through the getCommissionRate() function since this parameter is public (note that this parameter when queried through that method also has an accuracy of 18 decimal places, that is, a 2 \ * 10 ^ 15 in that parameter means that 0.2% is charged as commission).

The third part returns the amount in RIF discounting the previously calculated commissions.

totalRif = riskProToResToken(riskProFinalAmount);
rifReceived = totalRif - totalRif * commissionRate

Gas limit and gas price

These two values are a parameter of the transaction, this is not used in the contract and is generally managed by your wallet (you should read about them if you are developing and do not know exactly what they are), but you should take them into account when trying to redeem some RIFPros.

Possible failures

This operation may fail if one of the following scenarios occurs:

The contract is liquidated:

In the extraneous case where a coverage that barely covers the stable tokens funds is reached, the contract will liquidate all of its assets. If this state occurs, no more RIFPros will be available for redeeming. The condition is the same as that explained in The MoC contract is liquidated.

The contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. The condition is the same as that explained in The MoC contract is paused.

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

How-to

In the following sections we will give some code on how this can be done through a Smart Contract or directly, with a console or with an app.

Smart Contract​


To create a new Smart Contract that uses the Money On Chain platform, you can use any language and IDE you want. In this tutorial, we will show you how to do it using Solidity language, Truffle Framework and NPM.
Truffle framework offers some template projects that you can use to develop applications that use smart contracts. You can get more information here.
Assuming you already have your project up and running (if you don't, please follow this link) the only extra thing you need to do is to install our repo as a dependency in your NPM project. In order you need to do this you just need to run the following command.

npm install --save -E git+https://[email protected]/money-on-chain/main-RIF-contract.git

Having done that lets you use our contract as a dependency to your contract. For this let's suppose you are doing some kind of contract that when executing a certain task charges a fixed commission. Now let's suppose that the commission is sent in RIFs because it is easier for the user but actually you want some RIFPros. The good news is that you can do this instantly just by minting them. The code necessary to do this is actually pretty simple.

You just have to import the contract

import 'money-on-chain/contracts/MoC.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​
uint256 riskProAmount = 9000000;
moc.redeemRiskPro(riskProAmount);


You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIFPro token.

This will leave you with a contract similar to the following

import 'money-on-chain/contracts/MoC.sol';
import 'money-on-chain/contracts/MoCInrate.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​

You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIFPro token.

This will leave you with a contract similar to the following
​​

pragma solidity 0.5.8;
​
import "money-on-chain/contracts/MoC.sol";
import "money-on-chain/contracts/token/RiskProToken.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
// Here you will import your own dependencies

contract YourRedeemingRiskProContract {
    // Address of the MoC contract
    MoC public moc;
    // Address of the RIFPro token
    RiskProToken public riskPro;
    // Address of the RIF token
    IERC20 public rif;
    // rest of your variables
​
    constructor (MoC _moc, RiskProToken _riskPro, IERC20 _rif) public {
        moc = _moc;
        riskPro = _riskPro;
        rif = _rif;
        // You could have more variables to initialize here
    }
​
    function doTask(uint256 _riskProAmount) public {
        uint256 previousBalance = bpro.balanceOf(msg.sender);
        uint256 previousRifBalance = rif.balanceOf(msg.sender);
        moc.redeemRiskPro(_riskProAmount);
        uint256 newBalance = bpro.balanceOf(msg.sender);
        uint256 newRifBalance = rif.balanceOf(msg.sender);
    }
    // rest of your contract
}​
​

And that is it, the only thing left to do is to add in the truffle migrations scripts the address to MoC and BPro when deploying YourContract and you are done.
​​

Getting RDOCs

A RDOC, RIF Dollar On Chain, is a RIF-collateralized stable-coin. Its value is pegged to one dollar.

That RDOC is an ERC20 Token means that any user that has already some tokens can trade them to you in exchange for a service or for another token. You can find specific information about ERC-20 tokens here.

Minting RDOCs

RDOC can only be minted in exchange for RIF. Given an amount of RIF paid to the contract, the system calculates the corresponding RDOCs amount to mint, RIF and RDOC balances are added to the Money on Chain system and the new tokens are sent to the user.

In this tutorial the method(or function) that is of interest to us is function mintStableToken(uint256 resTokensToMint) public .

You must approve the amount of RIF token that you are willing to use on the Money on Chain platform before minting RDOC. The approved amount is called allowedBalance. You can do this by invoking function approve(address _spender, uint256 _value) public returns (bool success) that is part of the ERC20 standard.

Parameters of the operation

The resTokensToMint parameter

It is the amount the contract will use to actually mint RDOCs, i.e. it will not be used to pay commission, all of this funds will be transformed purely on RDOCs.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places and is defined in MoCLibConnection contract.
It could be the case, depending on the state of the contract, that a value less than resTokensToMint will be used to mint the RDOCs. In that case, all the extra RIFs will be sent to you.

The redeem process is split in three parts.

allowedBalance (RIF Token) >= resTokensToMint + resTokensToMint * commissionRate

Gas limit and gas price

This two values are a parameter of the transaction, which are not used in the contract and are usually managed by your wallet(you should read about them if you are developing and you don't know exactly what are they), but you should take them into account when trying to send all of your funds to mint some RDOCs.

Possible failures

This operation may fail if one of the following scenarios occurs:

The MoC contract is liquidated:

In the extraneous case where a coverage that barely covers the stable tokens funds is reached, the contract will liquidate all of its assets. If this state occurs, no more RDOCs will be available for minting.
To know if the contract is liquidated you can ask the MocState for the state, this will return a 0 if liquidated(it is actually an enum).

The MoC contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. You can get more information about stoppables contracts here
In that state, the contract doesn't allow minting any type of token.

To know if this is the case you can ask to MoC if it's paused().

You allowed too few funds:

If the RIF funds you allowed doesn't cover the amount you specified on resTokensToMint.

If this is the case the transaction will revert, all your funds will be returned (except the fee paid to the network). The error message will be "amount is not enough".

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

How-to

In the following sections we will give some code on how this can be done through a Smart Contract or directly, with a console or with an app.

Smart Contract​


To create a new Smart Contract that uses the Money On Chain platform, you can use any language and IDE you want. In this tutorial, we will show you how to do it using Solidity language, Truffle Framework and NPM.
Truffle framework offers some template projects that you can use to develop applications that use smart contracts. You can get more information here.
Assuming you already have your project up and running (if you don't, please follow this link) the only extra thing you need to do is to install our repo as a dependency in your NPM project. In order you need to do this you just need to run the following command.

npm install --save -E git+https://[email protected]/money-on-chain/main-RIF-contract.git

Having done that lets you use our contract as a dependency to your contract. For this let's suppose you are doing some kind of contract that when executing a certain task charges a fixed commission. Now let's suppose that the commission is sent in RIFs because it is easier for the user but actually you want some RDOCs. The good news is that you can do this instantly just by minting them. The code necessary to do this is actually pretty simple.

You just have to import the contract

import 'money-on-chain/contracts/MoC.sol';
import 'money-on-chain/contracts/MoCInrate.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​

​and, finally, when you receive a commission, exchange it for some RIFPros

uint256 resTokenToMint = 100000;
if (resTokenToMint > moc.getAllowance(msg.sender)){
    resTokenToMint = moc.getAllowance(msg.sender);
}
uint256 commissionOfMoC = mocInrate.calcCommissionValue(resTokenToMint);
moc.mintStableToken(resTokenToMint-commissionOfMoC);


You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RDOC token.

This will leave you with a contract similar to the following

pragma solidity 0.5.8;
​
import "money-on-chain/contracts/MoC.sol";
import "money-on-chain/contracts/MoCInrate.sol";
import "money-on-chain/contracts/token/StableToken.sol";
// Here you will import your own dependencies
​
contract YourMintingRDocContract {
    // Address of the MoC contract
    MoC public moc;
    // Address of the MocInrate contract
    MoCInrate public mocInrate;
    // Address of the doc token
    StableToken public doc;
    // Address that will receive all the commissions
    address public receiverAddress;
    // rest of your variables
​
    constructor (MoC _moc, MoCInrate _mocInrate, StableToken _doc_, address _receiverAddress) public {
        moc = _moc;
        mocInrate = _mocInrate;
        doc = _doc;
        receiverAddress = _receiverAddress;
        // You could have more variables to initialize here
    }
​
    function doTask(uint256 _restTokenToMint) public {
        //We compute the commision.
​        uint256 commission = mocInrate.calcCommissionValue(_restTokenToMint);
        //We compute the resTokensToMint.
        uint256 resTokensToMint = _restTokenToMint - commission;
        // Mint some new RDOC
        moc.mintStableToken(resTokensToMint);
​        // Transfer it to your receiver account
        doc.transfer(receiverAddress, doc.balanceOf(address(this)));
        // Rest of the function to actually perform the task
    }
    // rest of your contract
}
​
​

And that is it, the only thing left to do is to add in the truffle migrations scripts the address to MoC and RiskPro when deploying YourContract and you are done.

Redeeming RDOCs

Settlements is a time based recurring process that allows or rejects the processing of RDOC redeem requests. The process runs in 90 days intervals.

There are three ways to redeem RDOCs:

Redeeming RDOCs on Settlement: redeemStableTokenRequest

function redeemStableTokenRequest(uint256 stableTokenAmount) public
There is only one redeem request per user during a settlement. A new reedeem request is created if the user invokes it for the first time or has its value updated if it already exists.

Parameters of the operation

The stableTokenAmount parameter

It is the amount that the contract will use to create or update a RDOCs redeem request.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places and can be greater than user's balance at request time, allowing to, for example, redeem all future user's RDOCs.

Gas limit and gas price

These two values are a parameter of the transaction, this is not used in the contract and is generally managed by your wallet (you should read about them if you are developing and do not know exactly what they are), but you should take them into account when trying to redeem some RDOCs.

Possible failures

This operation may fail if one of the following scenarios occurs:

The contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. The condition is the same as that explained in The MoC contract is paused.

Settlement is not ready:

The function can only be invoked when the Settlement is finished executing. If called during execution, the transaction reverts with the error message: Function can only be called when settlement is ready.

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

Not active redeemer:

When a user tries to update a reedem request, but the system can not find its address as an active user for the current settlement. It is a very rare condition in which a transaction reverts with the error message: This is not an active redeemer.
If this situation occurs then you can contact the Money on Chain team to help you.

Not allowed redeemer:

When a user tries to update a reedem request and the system found its address as an active user but redeem request has a different address in the current settlement. It is a very rare condition in which a transaction reverts with the error message: Not allowed redeemer.
If this situation occurs then you can contact the Money on Chain team to help you.

Commisions

The redeemStableTokenRequest operation has no commissions, but when the settlement runs, the total amount of redeem requests will be used to pay the commission, this part is a percentage of the previous part. The exact percentage is established in the variable commissionRate of the contract MocInrate. The current value is 0.002 and can be queried through the getCommissionRate() function since this parameter is public (note that this parameter when queried through that method also has an accuracy of 18 decimal places, that is, a 2 \ * 10 ^ 15 in those parameters means that 0.2% is charged as commission).

Redeeming RDOCs on Settlement: alterRedeemRequestAmount

alterRedeemRequestAmount(bool isAddition, uint256 delta) public
There is only at most one redeem request per user during a settlement. A new reedeem request is created if the user invokes it for the first time or updates its value if it already exists.

Parameters of the operation

The isAddition parameter

true if you increase the amount of the redemption order amount, false otherwise.

The delta parameter

It is the amount that the contract will be used to update a RDOCs redeem request amount.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places and can be greater than user's balance at request time, allowing to, for example, redeem all future user's RDOCs.
If isAddition is false and the delta param is greater than the total amount of the redeem request, then the total amount of the request will be set to 0.

Gas limit and gas price

These two values are a parameter of the transaction, this is not used in the contract and is generally managed by your wallet (you should read about them if you are developing and do not know exactly what they are), but you should take them into account when trying to redeem some RDOCs.

Possible failures

This operation may fail if one of the following scenarios occurs:

The contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. The condition is the same as that explained in The MoC contract is paused.

Settlement is not ready:

The function can only be invoked when the Settlement is finished executing. If called during execution, the transaction reverts with the error message: Function can only be called when settlement is ready.

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

Not active redeemer:

When a user tries to update a redeem request, but the system cannot find its address as an active user for the current settlement. It is a rare condition in which a transaction reverts with the error message: This is not an active redeemer.
If this situation occurs then you can contact the Money on Chain team to help you.

Not allowed redeemer:

When a user tries to update a reedem request and the system found its address as an active user but redeem request has a different address in the current settlement. It is a very rare condition in which a transaction reverts with the error message: Not allowed redeemer.
If this situation occurs then you can contact the Money on Chain team to help you.

Commissions

The alterRedeemRequestAmount operation has no commissions, but when the settlement runs, the total amount of
redeem requests will be used to pay the commission, this part is a percentage of the previous part. The exact percentage is established in the variable commissionRate of the contract MocInrate. The current value is 0.002 and can be queried through the getCommissionRate() function since this parameter is public (note that this parameter when queried through that method also has an accuracy of 18 decimal places, that is, a 2 \ * 10 ^ 15 in those parameters means that 0.2% is charged as commission).

Redeeming RDOCs on Settlement: redeemFreeStableToken

function redeemFreeStableToken(uint256 stableTokenAmount) public

Redeems the requested stableTokenAmount for the user or the max amount of free docs possible if stableTokenAmount is bigger than max.

Parameters of the operation

The stableTokenAmount parameter

It is the amount that the contract will use to redeem free RDOCs.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places and is defined in MoCLibConnection contract.
Money on Chain is a dynamic system that allows you to redeem a maximum amount of free RDOCS and can be obtained by calling the freeStableToken() view of the MocState contract.

The first part transforms the amount stableTokenAmount into an RIF amount, but 3 things can happen:

      stableTokenAmountToRedeem = Math.min(mocState.freeStableToken(), docToken.balanceOf(account));
      finalDocAmount = Math.min(stableTokenAmount, stableTokenAmountToRedeem );
      rdocRifValue <= stableTokensToResToken(finalDocAmount);

The second part will be used to compute and pay the interests of the operation that depends on the abundance of RDOCs in the MOC system. The value can be obtained by invoking the function calcStableTokenRedInterestValues(finalDocAmount, rdocRifValue) of the contract MocInrate and also has an accuracy of 18 decimal places.

The third part will be used to pay the commission, this part is a percentage of the previous part. The exact percentage is established in the variable commissionRate of the contract MocInrate. The current value is 0.002 and can be queried through the getCommissionRate() function since this parameter is public (note that this parameter when queried through that method also has an accuracy of 18 decimal places, that is, a 2 \ * 10 ^ 15 in those parameters means that 0.2% is charged as commission).

The fourth part returns the amount in RIF discounting the previously calculated commissions and interests. In conclusion, the user receives the amount of RIF discounting the commissions

    rifReceived = finalRifAmount - finalRifAmount * commisionRate;
Gas limit and gas price

These two values are a parameter of the transaction, this is not used in the contract and is generally managed by your wallet (you should read about them if you are developing and do not know exactly what they are), but you should take them into account when trying to redeem some RDOCs.

Possible failures

This operation may fail if one of the following scenarios occurs:

The contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. The condition is the same as that explained in The MoC contract is paused.

The MoC contract is liquidated:

In the extraneous case where a coverage that barely covers the stable tokens funds is reached, the contract will liquidate all of its assets. If this state occurs, no more RDOCs will be available for minting.
To know if the contract is liquidated you can ask the MocState for the state, this will return a 0 if liquidated(it is actually an enum).

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

Redeeming RDOCs on Liquidation State: redeemAllStableToken

function redeemAllStableToken() public

Allows redeeming on liquidation state, user RDOCs get burned, and the user receives the equivalent RIFs according to the liquidation price which is the relation between the RDOCs total supply and the amount of RIF available to distribute.
The liquidation price can be queried with the view getLiquidationPrice() of the contract MocState.
If sending RIF fails then the system does not burn the RDOC tokens.

Parameters of the operation

Gas limit and gas price

These two values are a parameter of the transaction, this is not used in the contract and is generally managed by your wallet (you should read about them if you are developing and do not know exactly what they are), but you should take them into account when trying to redeem some RDOCs.

Possible failures

This operation may fail if one of the following scenarios occurs:

The MoC contract is not liquidated:

This operation can only be performed if the system is liquidated. If the MoC contract is in any other state then it fails and returns the following message: Function cannot be called at this state.

To know if the contract is liquidated you can ask the MocState for the state, this will return a 0 if liquidated(it is actually an enum).

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

How-to

In the following sections we will give some code on how this can be done through a Smart Contract or directly, with a console or with an app.

Smart Contract​


To create a new Smart Contract that uses the Money On Chain platform, you can use any language and IDE you want. In this tutorial, we will show you how to do it using Solidity language, Truffle Framework and NPM.
Truffle framework offers some template projects that you can use to develop applications that use smart contracts. You can get more information here.
Assuming you already have your project up and running (if you don't, please follow this link) the only extra thing you need to do is to install our repo as a dependency in your NPM project. In order you need to do this you just need to run the following command.

npm install --save -E git+https://[email protected]/money-on-chain/main-RIF-contract.git

Having done that lets you use our contract as a dependency to your contract. For this let's suppose you are doing some kind of contract that when executing a certain task charges a fixed commission. Now let's suppose that the commission is sent in RIFs because it is easier for the user but actually you want some RDOCs. The good news is that you can do this instantly just by redeeming them. The code necessary to do this is actually pretty simple.

You just have to import the contract

import 'money-on-chain/contracts/MoC.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​
//Create a new redeem request
uint256 stableTokenAmount = 90;
moc.redeemStableTokenRequest(stableTokenAmount);
//Add 10 docs to a redeem request.
moc.alterRedeemRequestAmount(true, 10);
//Sustract 5 docs to a redeem request.
moc.alterRedeemRequestAmount(true, 5);
//Trying to redeem All Docs.
uint256 docBalance = docToken.balanceOf(userAddress);
moc.redeemFreeStableToken(docBalance);

You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the doc token.

This will leave you with a contract similar to the following

import 'money-on-chain/contracts/MoC.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, rest of your params...) {
//....rest of your constructor....
}
​

You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIFPro token.

This will leave you with a contract similar to the following
​​

pragma solidity 0.5.8;
import "money-on-chain/contracts/MoC.sol";
import "money-on-chain/contracts/token/StableToken.sol";
// Here you will import your own dependencies

contract YourRedeemingDocContract {
    // Address of the MoC contract
    MoC public moc;
    // Address of the RIFPro token
    StableToken public doc;
    // RDOC Amout
    uint256 stableTokenAmount;
    // rest of your variables

    constructor (MoC _moc, StableToken _doc, uint256 _stableTokenAmount) public {
        moc = _moc;
        doc = _doc;
        stableTokenAmount = _stableTokenAmount;
        // You could have more variables to initialize here
    }
​
    function createRedeemRequest() public {
        uint256 previousBalance = doc.balanceOf(msg.sender);
        moc.redeemStableTokenRequest(stableTokenAmount);
        uint256 newBalance = doc.balanceOf(msg.sender);
    }

    function addToRedeemRequest(uint256 _addValue) public {
        moc.alterRedeemRequestAmount(true, stableTokenAmount);
        uint256 newBalance = doc.balanceOf(msg.sender);
    }

    function sustractToRedeemRequest(uint256 _addValue) public {
        moc.alterRedeemRequestAmount(false, stableTokenAmount);
        uint256 newBalance = doc.balanceOf(msg.sender);
    }

    function redeemFreeStableToken(uint256 _stableTokenAmount) public {
        uint256 previousBalance = doc.balanceOf(msg.sender);
        moc.redeemFreeStableToken(_stableTokenAmount);
        uint256 newBalance = doc.balanceOf(msg.sender);
    }
    // rest of your contract
}​

And that is it, the only thing left to do is to add in the truffle migrations scripts the address to MoC and RDOC when deploying YourContract and you are done.

Getting RIF2X

RIF2X is targeted towards users looking to profit from long positions in RIF, with two times the risk and reward. Leveraged instruments borrow capital from the base bucket (50% in a X2) and pay a daily rate to it as return.

There is a relation between RDOCS and RIF2X. The more RDOCs minted, the more RIF2X can be minted, since they are used for leverage.

The RIF2X token does not implement an ERC20 interface and can not be traded freely because leveraged instruments cannot change owner. RIF2X are assigned to the user RIFX positions can be canceled any time though.

The daily rate can be obtained invoking the dailyInrate() view of the MocInrate contract.

Minting RIF2X

RIF2X can only be minted in exchange for RIF.

In this tutorial the method(or function) that is of interest to us is function mintRiskProx(bytes32 bucket, uint256 resTokensToMint) public .

You must approve the amount of RIF token that you are willing to use on the Money on Chain platform before minting RIF2X. The approved amount is called allowedBalance. You can do this by invoking function approve(address _spender, uint256 _value) public returns (bool success) that is part of the ERC20 standard.

Parameters of the operation

The bucket parameter

A bucket is a bag that stores the balances of the leveraged token holders. Currently, only the RIF2X bucket called X2 exists. The X2 must be passed as a hex value.

There is also a bucket named C0 but it should not be used to mint and redeem RIF2X.

In the following example you can see how to do it with javascript and the web3 library. For more detailed information about web3 you can read the from outside blockchain section.

const BUCKET_X2 = web3.utils.asciiToHex('X2', 32);

The resTokensToMint parameter

It is the amount the contract will use to actually mint RIF2X, i.e. it will not be used to pay commission, all of this funds will be transformed purely on RIF2X.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places is defined in MoCLibConnection contract.

The amount sent in RIFs to the MoC contract will be split in four.

allowedBalance (RIF Token) >= resTokensToMint + interests + resTokensToMint * commissionRate

Gas limit and gas price

This two values are a parameter of the transaction, this is not used in the contract and it is usually managed by your wallet(you should read about them if you are developing and you don't know exactly what are they) but you should take them into account when trying to send all of your funds to mint some RIF2X.

Possible failures

This operation may fail if one of the following scenarios occurs:

The MoC contract is liquidated:

In the extraneous case where a coverage that barely covers the stable tokens funds is reached, the contract will liquidate all of its assets. If this state occurs, no more RIF2X will be available for minting.
To know if the contract is liquidated you can ask the MocState for the state, this will return a 0 if liquidated(it is actually an enum).

The MoC contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. You can get more information about stoppables contracts here
In that state, the contract doesn't allow minting any type of token.

To know if this is the case you can ask to MoC if it's paused().

Settlement is not ready:

The function can only be invoked when the Settlement is finished executing. If called during execution, the transaction reverts with the error message: Function can only be called when settlement is ready.

Bucket is not available:

Currently, only the RIF2X bucket called 'X2' exists. If it is called with another bucket, the transaction reverts with the error message: Bucket is not available.

Bucket is not a base bucket:

Currently, only the RIF2X bucket called 'X2' exists. If you call the function with C0 bucket, the transaction reverts with the error message: Bucket should not be a base type bucket.

You allowed too few funds:

If the RIF funds you allowed doesn't cover the amount you specified on resTokensToMint.

If this is the case the transaction will revert, all your funds will be returned (except the fee paid to the network). The error message will be "amount is not enough".

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

How-to

In the following sections we will give some code on how this can be done through a Smart Contract or directly, with a console or with an app.

Smart Contract​


To create a new Smart Contract that uses the Money On Chain platform, you can use any language and IDE you want. In this tutorial, we will show you how to do it using Solidity language, Truffle Framework and NPM.
Truffle framework offers some template projects that you can use to develop applications that use smart contracts. You can get more information here.
Assuming you already have your project up and running (if you don't, please follow this link) the only extra thing you need to do is to install our repo as a dependency in your NPM project. In order you need to do this you just need to run the following command.

npm install --save -E git+https://[email protected]/money-on-chain/main-RIF-contract.git

Having done that lets you use our contract as a dependency to your contract. For this let's suppose you are doing some kind of contract that when executing a certain task charges a fixed commission. Now let's suppose that the commission is sent in RIFs because it is easier for the user but actually you want some RIFPros. The good news is that you can do this instantly just by minting them. The code necessary to do this is actually pretty simple.

You just have to import the contract

import 'money-on-chain/contracts/MoC.sol';
import 'money-on-chain/contracts/MoCInrate.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​

​and, finally, when you receive a commission, exchange it for some RIFPros

bytes32 constant public BUCKET_X2 = "X2";
uint256 resTokenToMint = 10000;
if (resTokenToMint > moc.getAllowance(msg.sender)){
    resTokenToMint = moc.getAllowance(msg.sender);
}
uint256 commissionOfMoC = mocInrate.calcCommissionValue(resTokenToMint);
moc.mintRiskProx(BUCKET_X2, resTokenToMint-commissionOfMoC);


You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIF2X token.

This will leave you with a contract similar to the following

pragma solidity 0.5.8;
​
import "money-on-chain/contracts/MoC.sol";
import "money-on-chain/contracts/MoCInrate.sol";
// Here you will import your own dependencies
​
contract YourMintingRIF2xContract {
    // Address of the MoC contract
    MoC public moc;
    // Address of the MocInrate contract
    MoCInrate public mocInrate;
    // Define a constant to call bucket X2
​    bytes32 constant public BUCKET_X2 = "X2";

    constructor (MoC _moc, MoCInrate _mocInrate) public {
        moc = _moc;
        mocInrate = _mocInrate;
        // You could have more variables to initialize here
    }
​
    function doTask(uint256 _reserveTokenToMint) public {
        //We compute the commision.
​        uint256 commission = mocInrate.calcCommissionValue(_reserveTokenToMint);
        //We compute the resTokensToMint.
        uint256 resTokensToMint = _reserveTokenToMint - commission;
        // Mint some new RIFPro
        moc.mintRiskProx(BUCKET_X2, _reserveTokenToMint);
        // Rest of the function to actually perform the task
    }
    // rest of your contract
}
​
​


​​

Redeeming RIF2X

The Money On Chain's Smart Contract suite is in control of redeeming its tokens, including the RIF2X token. This means that the return of RIF2X is controlled programmatically by said suite. ​A user can "sell" their RIF2X back to the contract and have RIF deposited are sent back to the user, alongside the refunded interests (waiting in inrateBag) for the remaining time until the settlement (not yet charged).

In this tutorial the method(or function) that is of interest to us is function redeemRiskProx(bytes32 bucket, uint256 bproxAmount) public.

Parameters of the operation

The bucket parameter

A bucket is a bag that stores the balances of the leveraged token holders. Currently, only the RIF2X bucket called X2 exists. The X2 must be passed as an hex value.

There is also a bucket named C0 but it should not be used to mint and redeem RIF2X.

In the following example you can see how to do it with javascript and the web3 library. For more detailed information about web3 you can read the From outside the blockchain section.

const BUCKET_X2 = web3.utils.asciiToHex('X2', 32);

The bproxAmount parameter

It is the amount that the contract will use to redeem RIF2X and will be used to calculate commissions. All of these funds will be transformed exclusively into RIF.
This parameter uses a precision of the type reservePrecision that contains 18 decimal places and is defined in MoCLibConnection contract.

The redeeming process is divided into 4 parts:
The first part transforms the amount bproxAmount into an RIF amount, but 2 things can happen:

    userBalance = bproxBalanceOf(bucket, user);
    riskProxToRedeem = Math.min(bproxAmount, userBalance);
    rifToRedeem = bproxToBtc(riskProxToRedeem, bucket);

The second part computes interests to be paid to the user.

The third part will be used to pay the commission, this part is a percentage of the first part. The exact percentage is established in the variable commissionRate of the contract MocInrate. The current value is 0.002 and can be queried through the getCommissionRate() function since this parameter is public (note that when this parameter is queried through that method it has an accuracy of 18 decimal places, that is, a 2 \ * 10 ^ 15 in those parameters means that 0.2% is charged as commission).

The fourth part returns the amount in RIF adding the computed interest and discounting the previously calculated commissions.

rifReceived = totalRif + interests - totalRif * commissionRate

Gas limit and gas price

These two values are a parameter of the transaction, this is not used in the contract and is generally managed by your wallet (you should read about them if you are developing and do not know exactly what they are), but you should take them into account when trying to redeem some RIF2X.

Possible failures

This operation may fail if one of the following scenarios occurs:

The MoC contract is liquidated:

In the extraneous case where a coverage that barely covers the stable tokens funds is reached, the contract will liquidate all of its assets. If this state occurs, no more RIF2X will be available for redeeming.
To know if the contract is liquidated you can ask the MocState for the state, this will return a 0 if liquidated(it is actually an enum).

The MoC contract is paused:

If the system suffers some type of attack, the contract can be paused so that operations cannot be done and the risk of the users losing their funds with the operation can be minimized. You can get more information about stoppables contracts here
In that state, the contract doesn't allow minting any type of token.

To know if this is the case you can ask to MoC if it's paused().

Settlement is not ready:

The function can only be invoked when the Settlement has finished executing. If called during execution, the transaction reverts with the error message: Function can only be called when settlement is ready.

Bucket is not available:

Currently, only the RIF2X bucket called 'X2' exists. If it is called with another bucket, the transaction reverts with the error message: Bucket is not available.

Bucket is not a base bucket:

Currently, only the RIF2X bucket called 'X2' exists. If you call the function with C0 bucket, the transaction reverts with the error message: Bucket should not be a base type bucket.

Not enough gas:

If the gas limit sent is not enough to run all the code needed to execute the transaction, the transaction will revert(again, returning all your funds except the fee paid to the network). This may return an "out of gas" error or simply a "revert" error because of the usage of the proxy pattern.

How-to

In the following sections we will give some code on how this can be done through a Smart Contract or directly, with a console or with an app.

Smart Contract​


To create a new Smart Contract that uses the Money On Chain platform, you can use any language and IDE you want. In this tutorial, we will show you how to do it using Solidity language, Truffle Framework and NPM.
Truffle framework offers some template projects that you can use to develop applications that use smart contracts. You can get more information here.
Assuming you already have your project up and running (if you don't, please follow this link) the only extra thing you need to do is to install our repo as a dependency in your NPM project. In order you need to do this you just need to run the following command.

npm install --save -E git+https://[email protected]/money-on-chain/main-RIF-contract.git

Having done that lets you use our contract as a dependency to your contract. For this let's suppose you are doing some kind of contract that when executing a certain task charges a fixed commission. Now let's suppose that the commission is sent in RIFs because it is easier for the user but actually you want some RIFPros. The good news is that you can do this instantly just by minting them. The code necessary to do this is actually pretty simple.

You just have to import the contract

import 'money-on-chain/contracts/MoC.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​
uint256 riskProAmount = 9000000;
moc.redeemRiskPro(riskProAmount);


You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIFPro token.

This will leave you with a contract similar to the following

import 'money-on-chain/contracts/MoC.sol';
import 'money-on-chain/contracts/MoCInrate.sol';

Receive the address in the constructor in order to be able to interact with it later

constructor (MoC _mocContract, MoCInrate _mocInrateContract, rest of your params...) {
//....rest of your constructor....
}
​

You can send it immediately to you so you can start using it right away. In order to do this you should add a few more lines similar to the ones before, only that you will have to use the RIFPro token.

This will leave you with a contract similar to the following
​​

pragma solidity 0.5.8;
​
import "money-on-chain/contracts/MoC.sol";
import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
// Here you will import your own dependencies

contract YourRedeemingRiskProxContract {
    // Address of the MoC contract
    MoC public moc;
    // Address of the RIF token
    IERC20 public rif;
    // rest of your variables
​    bytes32 constant public BUCKET_X2 = "X2";

    constructor (MoC _moc, IERC20 _rif) public {
        moc = _moc;
        rif = _rif;
        // You could have more variables to initialize here
    }
​
    function doTask(uint256 _riskProAmount) public {
        uint256 previeusBalance = moc.riskProxBalanceOf(BUCKET_X2, msg.sender);
        uint256 previousRifBalance = rif.balanceOf(msg.sender);
        moc.redeemRiskProx(BUCKET_X2,_riskProAmount);
        uint256 newBalance = moc.riskProxBalanceOf(BUCKET_X2, msg.sender);
        uint256 newRifBalance = rif.balanceOf(msg.sender);
    }
    // rest of your contract
}​
​

From outside the blockchain

The logic of the Money on Chain platform is developed with smart contracts that run on the RSK blockchain. To interact with this kind of technology, we developed a dApp (decentralized application), which is a web or mobile application that invokes the functions of the smart contracts.

You can find tutorials about developing dApps in the following resources:

The web3 library is one of the most popular to invoke the functions of smart contracts and there are different projects to use them with

We use web3.js in this tutorial.

An RSK smart contract is bytecode implemented on the RSK blockchain. When a smart contract is compiled, an ABI (application binary interface) is generated and it is required so that you can specify which contract function to invoke, as well as get a guarantee that the function will return the data in the format you expect.
The ABI in JSON format must be provided to web3 to build decentralized applications.

Using RSK nodes

Money on Chain contracts are executed on the RSK blockchain whose public nodes are testnet (testing environment) and mainnet (production environment). You can use a public node or install a node in your own server.

Public node: RSK Testnet

Public node: RSK Mainnet

Truffle config: truffle.js

If you use truffle then you can use the following settings in your truffle.js file

const HDWalletProvider = require('truffle-hdwallet-provider');

const mnemonic = 'YOUR_MNEMO_PRHASE';

module.exports = {
  compilers: {
    solc: {
      version: '0.5.8',
      evmVersion: 'byzantium',
      settings: {
        optimizer: {
          enabled: true,
          runs: 1
        }
      }
    }
  },
  networks: {
    development: {
      host: '127.0.0.1',
      port: 8545,
      network_id: '*'
    },
    mocTestnet: {
      host: 'https://public-node.testnet.rsk.co',
      provider: new HDWalletProvider(mnemonic, 'https://public-node.testnet.rsk.co'),
      network_id: '31',
      gasPrice: 60000000
    },
    rskMainnet: {
      host: 'https://public-node.rsk.co',
      provider: new HDWalletProvider(mnemonic, 'https://public-node.rsk.co'),
      network_id: '30',
      gasPrice: 60000000
    }
  }
};

Installing your own node

The RSK node can be installed on different operating systems such as Linux, Windows and Mac. It is also possible to run them in environments running docker and in cloud service providers such as AWS, Azure and Google. For more information check the official RSK documentation

Using web3

You can use the technology that suits you best for your project to integrate with the Money on Chain platform, but you must use web3 to invoke the functions of smart contracts. You can learn how to use it with the following tutorials:

Official Money on Chain ABIS

In the Money on Chain repository you can find the official ABIs of the platform. You can use them to build your own decentralized applications to invoke the functions of smart contracts.

Events

When a transaction is mined, smart contracts can emit events and write logs to the blockchain that the frontend can then process. Click here for more information about events.

In the following example we will show you how to find events that are emitted by Money On Chain smart contract in RSK Testnet blockchain with truffle.

Code example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MocExchange = require('../../build/contracts/MoCExchange.json');
const truffleConfig = require('../../truffle');

/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');

//Contract address on testnet
const mocExchangeAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading MoCExchange contract to get the events emitted by this
  const mocExchange = await getContract(MocExchange.abi, mocExchangeAddress);
  if (!mocExchange) {
    throw Error('Can not find MoCExchange contract.');
  }

  // In this example we are getting RPro Mint events from MoCExchange contract
  // in the interval of blocks passed by parameter
  const getEvents = () =>
    Promise.resolve(mocExchange.getPastEvents('RiskProMint', { fromBlock: 1000, toBlock: 1010 }))
      .then(events => console.log(events))
      .catch(err => console.log('Error getting past events ', err));

  await getEvents();
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Check official web3 documentation for more details.

Example code minting RIFPros

In the following example we will show how to invoke the mintRiskPro function of the Money on Chain contract in testnet. Before calling this method we must set an allowance of RIF token available to spend. Check the minting RIFPros section for more information.

We will use truffle and testnet network.
First we create a new node project.

mkdir example-mint-riskpro
node init

Then we add the necessary dependencies to run the project

cd example-mint-riskpro
npm install --save bignumber.js
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MocAbi = require('../../build/contracts/MoC.json');
const MoCStateAbi = require('../../build/contracts/MoCState.json');
const ReserveToken = require('../../build/contracts/ReserveToken.json');
const truffleConfig = require('../../truffle');

/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const reserveTokenAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;
  /**
   * Loads an specified contract
   * @param {json ABI} abi
   * @param {localhost/testnet/mainnet} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  /**
   * Transforms BigNumbers into
   * @param {*} number
   */

  // Loading moc contract
  const moc = await getContract(MocAbi.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute max RIFP available to mint
  const mocState = await getContract(MoCStateAbi.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading ReserveToken contract. It is necessary to set max available RIF to spend
  const reserveToken = await getContract(ReserveToken.abi, reserveTokenAddress);
  if (!reserveToken) {
    throw Error('Can not find ReserveToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const setAllowance = async allowanceAmount => {
    const weiAmount = web3.utils.toWei(allowanceAmount, 'ether');
    console.log(`Calling approve: ${weiAmount}, for address account: ${from}.`);
    await reserveToken.methods.approve(mocContractAddress, weiAmount).send({ from, gasPrice });
    const spendableBalance = await moc.methods.getAllowance(from).call();
    console.log(`Spendable balance for account ${from} is ${spendableBalance}`);
  };

  const mintRiskPro = async (rifAmount, allowanceAmount) => {
    const weiAmount = web3.utils.toWei(rifAmount, 'ether');
    await setAllowance(allowanceAmount);

    console.log(`Calling RPro minting with account: ${from} and amount: ${weiAmount}.`);
    const tx = moc.methods
      .mintRiskPro(weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      });

    return tx;
  };

  // Gets max RIFP available to mint
  const maxRiskProAvailable = await mocState.methods.maxMintRiskProAvalaible().call();

  console.log('Max Available RIFP: '.concat(maxRiskProAvailable.toString()));
  const rifAmount = '0.0005';
  // before start minting RPro we need to set the allowance of RIF available to spend.
  const allowanceAmount = '0.001';

  // Call mint
  await mintRiskPro(rifAmount, allowanceAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code minting RIFPros without truffle

In the following example we will show how to invoke the mintRiskPro function of the Money on Chain contract in testnet. Before calling this method we must set an allowance of RIF token available to spend. Check the minting RIFPros section for more information.

First we create a new node project.

mkdir example-mint-riskpro
node init

Then we add the necessary dependencies to run the project

cd example-mint-riskpro
npm install --save bignumber.js
npm install --save web3
npm install --save truffle-hdwallet-provider

Example

const HDWalletProvider = require('truffle-hdwallet-provider');
const BigNumber = require('bignumber.js');
const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MocAbi = require('./contracts/moc/MoC.json');
const MoCInrateAbi = require('./contracts/moc/MoCInrate.json');
const MoCStateAbi = require('./contracts/moc/MoCState.json');

//Config params to TestNet
const endpoint = 'https://public-node.testnet.rsk.co';
//a mnemonic is 12 words instead of a single private key to sign the //transactions
const mnemonic = 'chase chair crew elbow uncle awful cover asset cradle pet loud puzzle';
const provider = new HDWalletProvider(mnemonic, endpoint);
const web3 = new Web3(provider);

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const reserveTokenAddress = '<contract-address>';
const gasPrice = 60000000;

const execute = async () => {
  /**
   * Loads an specified contract
   * @param {json ABI} abi
   * @param {localhost/testnet/mainnet} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  /**
   * Transforms BigNumbers into
   * @param {*} number
   */

  // Loading moc contract
  const moc = await getContract(MocAbi.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute max RIFP available to mint
  const mocState = await getContract(MoCStateAbi.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading ReserveToken contract. It is necessary to set max available RIF to spend
  const reserveToken = await getContract(ReserveToken.abi, reserveTokenAddress);
  if (!reserveToken) {
    throw Error('Can not find ReserveToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const setAllowance = async allowanceAmount =>{
    const weiAmount = web3.utils.toWei(allowanceAmount, 'ether');
    console.log(`Calling approve: ${weiAmount}, for address account: ${from}.`);
    await reserveToken.methods.approve(mocContractAddress, weiAmount).send({ from, gasPrice });
    const spendableBalance = await moc.methods.getAllowance(from).call();
    console.log(`Spendable balance for account ${from} is ${spendableBalance}`);
  }

  const mintRiskPro = async (rifAmount, allowanceAmount) => {
    const weiAmount = web3.utils.toWei(rifAmount, 'ether');
    await setAllowance(allowanceAmount);

    console.log(`Calling RPro minting with account: ${from} and amount: ${weiAmount}.`);
    const tx = moc.methods
      .mintRiskPro(weiAmount)
      .send({ from, gasPrice }, function (error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      });

    return tx;
  };

  // Gets max RIFP available to mint
  const maxRiskProAvailable = await mocState.methods.maxMintRiskProAvalaible().call();

  console.log('Max Available RIFP: '.concat(maxRiskProAvailable.toString()));
  const rifAmount = '0.0005';
  // before start minting RPro we need to set the allowance of RIF available to spend.
  const allowanceAmount = '0.001';

  // Call mint
  await mintRiskPro(rifAmount, allowanceAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch((err) => {
    console.log('Error', err);
  });
};

Example code redeeming RIFPros

In the following example we will show how to:

We will use truffle and testnet network.
You can find code examples into /examples dir.
First we create a new node project.

mkdir example-redeem-riskpro
node init

Then we add the necessary dependencies to run the project

cd example-redeem-riskpro
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const Moc = require('../../build/contracts/MoC.json');
const MoCState = require('../../build/contracts/MoCState.json');
const RiskProToken = require('../../build/contracts/RiskProToken.json');
const truffleConfig = require('../../truffle');

/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const riskProTokenAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading moc contract
  const moc = await getContract(Moc.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute absolute max RPRO
  const mocState = await getContract(MoCState.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading RProToken contract. It is necessary to compute user balance
  const riskProToken = await getContract(RiskProToken.abi, riskProTokenAddress);
  if (!riskProToken) {
    throw Error('Can not find RiskProToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const redeemRPro = async rproAmount => {
    const weiAmount = web3.utils.toWei(rproAmount, 'ether');
    console.log(`Calling redeem RPro with account: ${from} and amount: ${weiAmount}.`);
    moc.methods
      .redeemRiskPro(weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  const getAbsoluteMaxRpro = await mocState.methods.absoluteMaxRiskPro().call();
  const userAmount = await riskProToken.methods.balanceOf(from).call();

  console.log('=== Max amount of RPro to redeem: ', getAbsoluteMaxRpro.toString());
  console.log('=== User RPro Balance: ', userAmount.toString());

  const rproAmount = '0.00001';

  // Call redeem
  await redeemRPro(rproAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code redeeming RIFPros without truffle

In the following example we will show how to:

We will use the TestNet network.
You can find code examples into /examples dir.
First we create a new node project.

mkdir example-redeem-riskpro
node init

Then we add the necessary dependencies to run the project

cd example-redeem-riskpro
npm install --save web3
npm install --save truffle-hdwallet-provider

Example

const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const Moc = require('../../build/contracts/MoC.json');
const MoCState = require('../../build/contracts/MoCState.json');
const RiskProToken = require('../../build/contracts/RiskProToken.json');

//Config params to TestNet
const endpoint = 'https://public-node.testnet.rsk.co';
//a mnemonic is 12 words instead of a single private key to sign the //transactions
const mnemonic = 'chase chair crew elbow uncle awful cover asset cradle pet loud puzzle';
const provider = new HDWalletProvider(mnemonic, endpoint);
const web3 = new Web3(provider);

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const riskProTokenAddress = '<contract-address>';
const gasPrice = 60000000;

const execute = async () => {
  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading moc contract
  const moc = await getContract(Moc.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute absolute max RPRO
  const mocState = await getContract(MoCState.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading RProToken contract. It is necessary to compute user balance
  const riskProToken = await getContract(RiskProToken.abi, riskProTokenAddress);
  if (!riskProToken) {
    throw Error('Can not find RiskProToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const redeemRPro = async rproAmount => {
    const weiAmount = web3.utils.toWei(rproAmount, 'ether');
    console.log(`Calling redeem RPro with account: ${from} and amount: ${weiAmount}.`);
    moc.methods
      .redeemRiskPro(weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  const getAbsoluteMaxRpro = await mocState.methods.absoluteMaxRiskPro().call();
  const userAmount = await riskProToken.methods.balanceOf(from).call();

  console.log('=== Max amount of RPro to redeem: ', getAbsoluteMaxRpro.toString());
  console.log('=== User RPro Balance: ', userAmount.toString());

  const rproAmount = '0.00001';

  // Call redeem
  await redeemRPro(rproAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code minting RDOC

In the following example we will show how to:

Before minting RDOC we must set an allowance of RIF token available to spend. Check the minting RDOCs section for more information.
We will use truffle and testnet network
You can find code examples into /examples dir.

We will use the TestNet network.
First we create a new node project.

mkdir example-mint-stabletoken
node init

Then we add the necessary dependencies to run the project

cd example-mint-stabletoken
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MocAbi = require('../../build/contracts/MoC.json');
const MoCStateAbi = require('../../build/contracts/MoCState.json');
const ReserveToken = require('../../build/contracts/ReserveToken.json');
const truffleConfig = require('../../truffle');

/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const reserveTokenAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading moc contract
  const moc = await getContract(MocAbi.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute max RDoc available to mint
  const mocState = await getContract(MoCStateAbi.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading ReserveToken contract. It is necessary to set max available RIF to spend
  const reserveToken = await getContract(ReserveToken.abi, reserveTokenAddress);
  if (!reserveToken) {
    throw Error('Can not find ReserveToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const setAllowance = async allowanceAmount => {
    const weiAmount = web3.utils.toWei(allowanceAmount, 'ether');
    console.log(`Calling approve: ${weiAmount}, for address account: ${from}.`);
    await reserveToken.methods.approve(mocContractAddress, weiAmount).send({ from, gasPrice });
    const spendableBalance = await moc.methods.getAllowance(from).call();
    console.log(`Spendable balance for account ${from} is: ${spendableBalance}`);
  };

  const mintDoc = async (rifAmount, allowanceAmount) => {
    const weiAmount = web3.utils.toWei(rifAmount, 'ether');
    await setAllowance(allowanceAmount);
    console.log(`Calling RDoc minting, account: ${from}, amount: ${weiAmount}.`);
    moc.methods
      .mintStableToken(weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  // Gets max RDOC available to mint
  const getAbsoluteMaxRDoc = await mocState.methods.absoluteMaxStableToken().call();
  const rifAmount = '0.00001';
  //// before start minting RDoc we need to set the allowance of RIF available to spend.
  const allowanceAmount = '0.001';

  console.log('=== Max RDoc amount available to mint: ', getAbsoluteMaxRDoc.toString());

  // Call mint
  await mintDoc(rifAmount, allowanceAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code redeeming Free RDOC

In the following example we will show how to invoke redeemFreeStableToken from Money on Chain contract.This method allows to redeem RDOC outside the settlement and they are limited by user balance. Check the RDOC redeemption section for more details.

We will learn how to:

We will use truffle and testnet network
You can find code examples into /examples dir.

We will use the TestNet network.
First we create a new node project.

mkdir example-redeem-free-stabletoken
node init

Then we add the necessary dependencies to run the project

cd example-redeem-free-stabletoken
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MoC = require('../../build/contracts/MoC.json');
const MocState = require('../../build/contracts/MoCState.json');
const StableToken = require('../../build/contracts/StableToken.json');
const truffleConfig = require('../../truffle');
/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Contract addresses on testnet
const mocAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const stableTokenAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading MoC contract
  const moc = await getContract(MoC.abi, mocAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute freeRDoc
  const mocState = await getContract(MocState.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading DocToken contract. It is necessary to compute user balance
  const stableToken = await getContract(StableToken.abi, stableTokenAddress);
  if (!stableToken) {
    throw Error('Can not find StableToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const redeemFreeRDoc = async rDocAmount => {
    const weiAmount = web3.utils.toWei(rDocAmount, 'ether');

    console.log(`Calling redeem free RDoc, account: ${from}, amount: ${weiAmount}.`);
    moc.methods
      .redeemFreeStableToken(weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  const rDocAmount = '10000';
  const freeRDoc = await mocState.methods.freeStableTokeneDoc().call();
  const userRDocBalance = await stableToken.methods.balanceOf(from).call();
  const finalDocAmount = Math.min(freeRDoc, userRDocBalance);
  console.log('=== User RDOC balance: ', userRDocBalance.toString());
  console.log('=== Free RDOC: ', freeRDoc.toString());
  console.log('=== Max Available RDOC to redeem: ', finalDocAmount.toString());

  // Call redeem
  await redeemFreeRDoc(rDocAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code redeeming RDOC Request

In the following example we will show how to invoke redeemStableTokenRequest using Money on Chain contract. This method can recieve any amount of RDOCs to redeem, but this will be processed on the next settlement. Check the RDOC redeemption section for more details.
We will use truffle and testnet network
You can find code examples into /examples dir.

First we create a new node project.

mkdir example-redeem-stabletoken-request
node init

Then we add the necessary dependencies to run the project

cd example-redeem-stabletoken-request
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MoC = require('../../build/contracts/MoC.json');
const truffleConfig = require('../../truffle');
/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Loading MoC address on testnet
const mocAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading MoC contract
  const moc = await getContract(MoC.abi, mocAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  const redeemRDocRequest = async rDocAmount => {
    const [from] = await web3.eth.getAccounts();
    const weiAmount = web3.utils.toWei(rDocAmount, 'ether');

    console.log(`Calling redeem RDoc request, account: ${from}, amount: ${weiAmount}.`);
    moc.methods
      .redeemStableTokenRequest(weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  const rDocAmount = '10000';

  // Call redeem
  await redeemRDocRequest(rDocAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code redeeming all RDOC

In the following example we will show how to invoke redeemAllStableToken using Money on Chain contract. As a condition to do this the Moc contract must be paused(). Check the RDOC redeemption section for more details.
We will use truffle and testnet network
You can find code examples into /examples dir.
First we create a new node project.

mkdir example-redeem-all-stabletoken
node init

Then we add the necessary dependencies to run the project

cd example-redeem-all-stabletoken
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MoC = require('../../build/contracts/MoC.json');
const truffleConfig = require('../../truffle');
/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

// Loading MoC address on testnet
const mocAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);

  // Loading MoC contract
  const moc = await getContract(MoC.abi, mocAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  const redeemAllRDoc = async () => {
    const [from] = await web3.eth.getAccounts();

    console.log(`Calling redeem all RDoc.`);
    moc.methods
      .redeemAllStableToken()
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  // Call redeem
  await redeemAllRDoc();
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code minting RIF2X

In the following example we will learn how to:

Before minting RIF2X we must set an allowance of RIF token available to spend. Check the minting RIF2X section for more information.
We will use truffle and testnet network
You can find code examples into /examples dir.
First we create a new node project.

mkdir example-mint-riskproxtoken
node init

Then we add the necessary dependencies to run the project

cd example-mint-riskproxtoken
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const Moc = require('../../build/contracts/MoC.json');
const MoCState = require('../../build/contracts/MoCState.json');
const ReserveToken = require('../../build/contracts/ReserveToken.json');
const truffleConfig = require('../../truffle');

/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocStateAddress = '<contract-address>';
const reserveTokenAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);
  const strToBytes32 = bucket => web3.utils.asciiToHex(bucket, 32);
  const bucketX2 = 'X2';

  // Loading moc contract
  const moc = await getContract(Moc.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading mocState contract. It is necessary to compute max RIF2X available to mint
  const mocState = await getContract(MoCState.abi, mocStateAddress);
  if (!mocState) {
    throw Error('Can not find MoCState contract.');
  }

  // Loading ReserveToken contract. It is necessary to set max available RIF to spend
  const reserveToken = await getContract(ReserveToken.abi, reserveTokenAddress);
  if (!reserveToken) {
    throw Error('Can not find ReserveToken contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const setAllowance = async allowanceAmount =>{
    const weiAmount = web3.utils.toWei(allowanceAmount, 'ether');
    console.log(`Calling approve: ${weiAmount}, for address account: ${from}.`);
    await reserveToken.methods.approve(mocContractAddress, weiAmount).send({ from, gasPrice });
    const spendableBalance = await moc.methods.getAllowance(from).call();
    console.log(`Spendable balance for account ${from} is ${spendableBalance}`);
  }

  const mintRif2x = async (rifAmount, allowanceAmount) => {
    const weiAmount = web3.utils.toWei(rifAmount, 'ether');
    await setAllowance(allowanceAmount);
    console.log(`Calling mint RIF2X with ${rifAmount} RIFs with account: ${from}.`);
    moc.methods
      .mintRiskProx(strToBytes32(bucketX2), weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  // before start minting RIF2X we need to set the allowance of RIF available to spend.
  const allowanceAmount = '0.001';
  const rifToMint = '0.00001';
  // Gets max RIF2X amount available to mint
  const maxRif2xToMint = await mocState.methods.maxRiskProx(strToBytes32(bucketX2)).call();
  console.log('=== Max Available RIF2X to mint: '.concat(maxRif2xToMint.toString()));

  // Call mint
  await mintRif2x(rifToMint,allowanceAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });

Example code redeeming RIF2X

In the following script example we will learn how to:

We will use truffle and testnet network
You can find code examples into /examples dir.
First we create a new node project.

mkdir example-redeem-riskproxtoken
node init

Then we add the necessary dependencies to run the project

cd example-redeem-riskproxtoken
npm install --save web3

Example

const Web3 = require('web3');
//You must compile the smart contracts or use the official ABIs of the //repository
const MoC = require('../../build/contracts/MoC.json');
const MoCRiskProxManager = require('../../build/contracts/MoCRiskProxManager.json');
const truffleConfig = require('../../truffle');

/**
 * Get a provider from truffle.js file
 * @param {String} network
 */
const getDefaultProvider = network =>
  truffleConfig.networks[network].provider || truffleConfig.networks[network].endpoint;

/**
 * Get a gasPrice from truffle.js file
 * @param {String} network
 */
const getGasPrice = network => truffleConfig.networks[network].gasPrice || 60000000;

/**
 * Get a new web3 instance from truffle.js file
 */
const getWeb3 = network => {
  const provider = getDefaultProvider(network);
  return new Web3(provider, null, {
    transactionConfirmationBlocks: 1
  });
};

const web3 = getWeb3('mocTestnet');
const gasPrice = getGasPrice('mocTestnet');

//Contract addresses on testnet
const mocContractAddress = '<contract-address>';
const mocRiskProxManagerAddress = '<contract-address>';

const execute = async () => {
  web3.eth.defaultGas = 2000000;

  /**
   * Loads an specified contract
   * @param {ContractABI} abi
   * @param {String} contractAddress
   */
  const getContract = async (abi, contractAddress) => new web3.eth.Contract(abi, contractAddress);
  const strToBytes32 = bucket => web3.utils.asciiToHex(bucket, 32);
  const bucketX2 = 'X2';

  // Loading Moc contract
  const moc = await getContract(MoC.abi, mocContractAddress);
  if (!moc) {
    throw Error('Can not find MoC contract.');
  }

  // Loading MoCRiskProxManager contract. It is necessary to compute user RIF2X balance
  const mocRiskProxManager = await getContract(MoCRiskProxManager.abi, mocRiskProxManagerAddress);
  if (!mocRiskProxManager) {
    throw Error('Can not find MoCRiskProxManager contract.');
  }

  const [from] = await web3.eth.getAccounts();

  const redeemRif2x = async rif2xAmount => {
    const weiAmount = web3.utils.toWei(rif2xAmount, 'ether');

    console.log(`Calling redeem RIF2X with account: ${from}, amount: ${weiAmount}.`);
    moc.methods
      .redeemRiskProx(strToBytes32(bucketX2), weiAmount)
      .send({ from, gasPrice }, function(error, transactionHash) {
        if (error) console.log(error);
        if (transactionHash) console.log('txHash: '.concat(transactionHash));
      })
      .on('transactionHash', function(hash) {
        console.log('TxHash: '.concat(hash));
      })
      .on('receipt', function(receipt) {
        console.log(receipt);
      })
      .on('error', console.error);
  };

  const userBalance = await mocRiskProxManager.methods
    .riskProxBalanceOf(strToBytes32(bucketX2), from)
    .call();
  console.log('=== User RIF2X Balance: '.concat(userBalance.toString()));

  const rif2xAmount = '0.00001';

  // Call redeem
  await redeemRif2x(rif2xAmount);
};

execute()
  .then(() => console.log('Completed'))
  .catch(err => {
    console.log('Error', err);
  });