NAV Navbar
  • Introduction
  • Solidity Smart Contracts
  • MPX
  • API
  • API - Authentication
  • API - Endpoints
  • API - Data Types
  • Getting help
  • Contributing
  • Bug Reporting
  • Introduction

    Welcome to the MARKET Protocol documentation! Here you will find documentation for our smart contracts and APIs.

    MARKET Protocol has been created to provide a secure, flexible, open source foundation for decentralized trading on the Ethereum blockchain. We provide the pieces necessary to create a decentralized exchange, including the requisite clearing and collateral pool infrastructure, enabling third parties to build applications for trading.

    Visit our Github: https://github.com/MARKETProtocol

    Trade Flow

    Documentation

    Frequently Asked Questions

    Solidity Smart Contracts

    All code for our smart contracts can be found here. If you have any issues to report please do so by opening an issue on GitHub.

    Market Contract

    MarketContract constructor:

    /// @param contractNames comma separated list of 3 names "contractName,longTokenSymbol,shortTokenSymbol"
    /// @param baseAddresses array of 2 addresses needed for our contract including:
    ///     creatorAddress                  address of the person creating the contract
    ///     collateralTokenAddress          address of the ERC20 token that will be used for collateral and pricing
    ///     collateralPoolAddress           address of our collateral pool contract
    /// @param contractSpecs array of unsigned integers including:
    ///     floorPrice          minimum tradeable price of this contract, contract enters settlement if breached
    ///     capPrice            maximum tradeable price of this contract, contract enters settlement if breached
    ///     priceDecimalPlaces  number of decimal places to convert our queried price from a floating point to
    ///                         an integer
    ///     qtyMultiplier       multiply traded qty by this value from base units of collateral token.
    ///     feeInBasisPoints    fee amount in basis points (Collateral token denominated) for minting.
    ///     mktFeeInBasisPoints fee amount in basis points (MKT denominated) for minting.
    ///     expirationTimeStamp seconds from epoch that this contract expires and enters settlement
    constructor(
        string memory contractNames,
        address[3] memory baseAddresses,
        uint[7] memory contractSpecs
    ) public
    {
        PRICE_FLOOR = contractSpecs[0];
        PRICE_CAP = contractSpecs[1];
        require(PRICE_CAP > PRICE_FLOOR);
    
        PRICE_DECIMAL_PLACES = contractSpecs[2];
        QTY_MULTIPLIER = contractSpecs[3];
        EXPIRATION = contractSpecs[6];
        require(EXPIRATION > now, "expiration must be in the future");
    
        COLLATERAL_TOKEN_ADDRESS = baseAddresses[1];
        COLLATERAL_POOL_ADDRESS = baseAddresses[2];
        COLLATERAL_PER_UNIT = MathLib.calculateTotalCollateral(PRICE_FLOOR, PRICE_CAP, QTY_MULTIPLIER);
        COLLATERAL_TOKEN_FEE_PER_UNIT = MathLib.calculateFeePerUnit(
            PRICE_FLOOR,
            PRICE_CAP,
            QTY_MULTIPLIER,
            contractSpecs[4]
        );
        MKT_TOKEN_FEE_PER_UNIT = MathLib.calculateFeePerUnit(
            PRICE_FLOOR,
            PRICE_CAP,
            QTY_MULTIPLIER,
            contractSpecs[5]
        );
    
        // create long and short tokens
        StringLib.slice memory pathSlice = contractNames.toSlice();
        StringLib.slice memory delim = ",".toSlice();
        require(pathSlice.count(delim) == 2, "ContractNames must contain 3 names");  //contractName,lTokenName,sTokenName
        CONTRACT_NAME = pathSlice.split(delim).toString();
    
        PositionToken longPosToken = new PositionToken("MARKET Protocol Long Position Token", pathSlice.split(delim).toString(), 0);
        PositionToken shortPosToken = new PositionToken("MARKET Protocol Short Position Token", pathSlice.split(delim).toString(), 1);
    
        LONG_POSITION_TOKEN = address(longPosToken);
        SHORT_POSITION_TOKEN = address(shortPosToken);
    
        transferOwnership(baseAddresses[0]);
    }
    

    The MarketContract represents the main contract responsible for defining trading specifications as well as creating a set of ERC20 tokens known as Market Protocol Position Tokens. One of these tokens represents a long position or exposure and the other, the opposite, short exposure. Combined with MARKET Protocol's collateral pool these provide all of the needed functionality for trading, settlement and position management.

    Contract Diagram

    MarketContract is an abstract contract that will allow for implementing classes such as MarketContractMPX to complete the needed top level functionality of integrating multiple oracle solutions. We intend to expand the offering of oracle solutions in the future.

    Market Contract MPX

    MarketContractMPX constructor:

    /// @param contractNames comma separated list of 3 names "contractName,longTokenSymbol,shortTokenSymbol"
    /// @param baseAddresses array of 2 addresses needed for our contract including:
    ///     creatorAddress                  address of the person creating the contract
    ///     collateralTokenAddress          address of the ERC20 token that will be used for collateral and pricing
    ///     collateralPoolAddress           address of our collateral pool contract
    /// @param oracleHubAddress     address of our oracle hub providing the callbacks
    /// @param contractSpecs array of unsigned integers including:
    ///     floorPrice              minimum tradeable price of this contract, contract enters settlement if breached
    ///     capPrice                maximum tradeable price of this contract, contract enters settlement if breached
    ///     priceDecimalPlaces      number of decimal places to convert our queried price from a floating point to
    ///                             an integer
    ///     qtyMultiplier           multiply traded qty by this value from base units of collateral token.
    ///     feeInBasisPoints    fee amount in basis points (Collateral token denominated) for minting.
    ///     mktFeeInBasisPoints fee amount in basis points (MKT denominated) for minting.
    ///     expirationTimeStamp     seconds from epoch that this contract expires and enters settlement
    /// @param oracleURL url of data
    /// @param oracleStatistic statistic type (lastPrice, vwap, etc)
    constructor(
        string memory contractNames,
        address[3] memory baseAddresses,
        address oracleHubAddress,
        uint[7] memory contractSpecs,
        string memory oracleURL,
        string memory oracleStatistic
    ) MarketContract(
        contractNames,
        baseAddresses,
        contractSpecs
    )  public
    {
        ORACLE_URL = oracleURL;
        ORACLE_STATISTIC = oracleStatistic;
        ORACLE_HUB_ADDRESS = oracleHubAddress;
    }
    

    MarketContractMPX is the first fully implemented MarketContract that has been built out. Using our internal oracle service built for MPX our initial contracts will settle to price feeds graciously provided by CoinCap;

    Additional parameters

    Parameter Description
    oracleURL URL of the api providing settlement price feed.
    oracleStatistic The price statistic the contract will be settling to from the API

    Market Collateral Pool

    MarketCollateralPool constructor:

    constructor(address marketContractRegistryAddress, address mktTokenAddress) public {
        marketContractRegistry = marketContractRegistryAddress;
        mktToken = mktTokenAddress;
    }
    

    The MarketCollateralPool is a contract responsible for locking required collateral tokens in order to facilitate minting of our MARKET Protocol Position Tokens. The exact ERC20 token that is accepted as collateral will be specified in each MarketContract specification. These collateral balances are segregated and unique to the specific MarketContract that tokens have been created for.

    Minting and Redemption

    Minting Position Tokens

    mintPositionTokens function

    /// @notice Called by a user that would like to mint a new set of long and short token for a specified
    /// market contract.  This will transfer and lock the correct amount of collateral into the pool
    /// and issue them the requested qty of long and short tokens
    /// @param marketContractAddress            address of the market contract to redeem tokens for
    /// @param qtyToMint                      quantity of long / short tokens to mint.
    /// @param isAttemptToPayInMKT            if possible, attempt to pay fee's in MKT rather than collateral tokens
    function mintPositionTokens(
        address marketContractAddress,
        uint qtyToMint,
        bool isAttemptToPayInMKT
    ) external onlyWhiteListedAddress(marketContractAddress)
    {
    
        MarketContract marketContract = MarketContract(marketContractAddress);
        require(!marketContract.isSettled(), "Contract is already settled");
    
        address collateralTokenAddress = marketContract.COLLATERAL_TOKEN_ADDRESS();
        uint neededCollateral = MathLib.multiply(qtyToMint, marketContract.COLLATERAL_PER_UNIT());
        // the user has selected to pay fees in MKT and those fees are non zero (allowed) OR
        // the user has selected not to pay fees in MKT, BUT the collateral token fees are disabled (0) AND the
        // MKT fees are enabled (non zero).  (If both are zero, no fee exists)
        bool isPayFeesInMKT = (isAttemptToPayInMKT &&
            marketContract.MKT_TOKEN_FEE_PER_UNIT() != 0) ||
            (!isAttemptToPayInMKT &&
            marketContract.MKT_TOKEN_FEE_PER_UNIT() != 0 &&
            marketContract.COLLATERAL_TOKEN_FEE_PER_UNIT() == 0);
    
        uint feeAmount;
        uint totalCollateralTokenTransferAmount;
        address feeToken;
        if (isPayFeesInMKT) { // fees are able to be paid in MKT
            feeAmount = MathLib.multiply(qtyToMint, marketContract.MKT_TOKEN_FEE_PER_UNIT());
            totalCollateralTokenTransferAmount = neededCollateral;
            feeToken = mktToken;
    
            // EXTERNAL CALL - transferring ERC20 tokens from sender to this contract.  User must have called
            // ERC20.approve in order for this call to succeed.
            ERC20(mktToken).safeTransferFrom(msg.sender, address(this), feeAmount);
        } else { // fee are either zero, or being paid in the collateral token
            feeAmount = MathLib.multiply(qtyToMint, marketContract.COLLATERAL_TOKEN_FEE_PER_UNIT());
            totalCollateralTokenTransferAmount = neededCollateral.add(feeAmount);
            feeToken = collateralTokenAddress;
            // we will transfer collateral and fees all at once below.
        }
    
        // EXTERNAL CALL - transferring ERC20 tokens from sender to this contract.  User must have called
        // ERC20.approve in order for this call to succeed.
        ERC20(marketContract.COLLATERAL_TOKEN_ADDRESS()).safeTransferFrom(msg.sender, address(this), totalCollateralTokenTransferAmount);
    
        if (feeAmount != 0) {
            // update the fee's collected balance
            feesCollectedByTokenAddress[feeToken] = feesCollectedByTokenAddress[feeToken].add(feeAmount);
        }
    
        // Update the collateral pool locked balance.
        contractAddressToCollateralPoolBalance[marketContractAddress] = contractAddressToCollateralPoolBalance[
            marketContractAddress
        ].add(neededCollateral);
    
        // mint and distribute short and long position tokens to our caller
        marketContract.mintPositionTokens(qtyToMint, msg.sender);
    
        emit TokensMinted(
            marketContractAddress,
            msg.sender,
            feeToken,
            qtyToMint,
            neededCollateral,
            feeAmount
        );
    }
    

    At any time prior to expiration of the MarketContract a user may mint Position Tokens. The minting process requires users to create tokens in pairs, minting both a Long Position Token and a Short Position Token in equal quantities. The Position Tokens are ERC20 tokens are able to be transferred and traded on centralized or decentralized exchanges freely. The required amount of collateral to mint a pair of tokens is always constant for given MarketContract.

    Calculating collateral per pair of tokens

    calculateTotalCollateral function

    /// @notice determines the amount of needed collateral for minting a long and short position token
    function calculateTotalCollateral(
        uint priceFloor,
        uint priceCap,
        uint qtyMultiplier
    ) pure public returns (uint)
    {
        return multiply(subtract(priceCap, priceFloor), qtyMultiplier);
    }
    

    The amount of ERC20 collateral that is required to mint a pair of Position Tokens can be calculated by the taking the difference of priceCap from the priceFloor multiplied by a qtyMultiplier. All three of these variables are defined upon the deployment of a new MarketContract. This amount represents the entire possible range of trading outcomes at settlement. A pair of Long and Short Position Tokens will always be worth this amount, and in fact can be redeemed for that amount at any time. For every unit of collateral that the Long Position Token may gain, the Short Position Token by definition will lose. In this way the pair of tokens is always zero-sum and a holder of both of these tokens has no net exposure to the underlying assets price, they are essentially perfectly hedged. Users wishing to gain exposure, either long or short, will simply either purchase that specific token on a secondary market (an exchange) or mint the pair and sell away the unwanted side.

    Parameter Description
    priceFloor as defined in the MarketContract
    priceCap as defined in the MarketContract
    qtyMultiplier as defined in the MarketContract

    Redeeming Position Tokens

    redeemPositionTokens function

    /// @notice Called by a user that currently holds both short and long position tokens and would like to redeem them
    /// for their collateral.
    /// @param marketContractAddress            address of the market contract to redeem tokens for
    /// @param qtyToRedeem                      quantity of long / short tokens to redeem.
    function redeemPositionTokens(
        address marketContractAddress,
        uint qtyToRedeem
    ) external onlyWhiteListedAddress(marketContractAddress)
    {
        MarketContract marketContract = MarketContract(marketContractAddress);
    
        marketContract.redeemLongToken(qtyToRedeem, msg.sender);
        marketContract.redeemShortToken(qtyToRedeem, msg.sender);
    
        // calculate collateral to return and update pool balance
        uint collateralToReturn = MathLib.multiply(qtyToRedeem, marketContract.COLLATERAL_PER_UNIT());
        contractAddressToCollateralPoolBalance[marketContractAddress] = contractAddressToCollateralPoolBalance[
            marketContractAddress
        ].subtract(collateralToReturn);
    
        // EXTERNAL CALL
        // transfer collateral back to user
        ERC20(marketContract.COLLATERAL_TOKEN_ADDRESS()).safeTransfer(msg.sender, collateralToReturn);
    
        emit TokensRedeemed(
            marketContractAddress,
            msg.sender,
            qtyToRedeem,
            collateralToReturn,
            uint8(MarketSide.Both)
        );
    }
    

    At any time, holders of Position Tokens can redeem equal amounts of Long and Short Position Tokens for the full amount of collateral that was used to create them.

    Redeeming Position Tokens after Settlement

    // @notice called by a user after settlement has occurred.  This function will finalize all accounting around any
    // outstanding positions and return all remaining collateral to the caller. This should only be called after
    // settlement has occurred.
    /// @param marketContractAddress address of the MARKET Contract being traded.
    /// @param qtyToRedeem signed qtyToRedeem, positive (+) for long tokens, negative(-) for short tokens
    function settleAndClose(
        address marketContractAddress,
        int qtyToRedeem
    ) external onlyWhiteListedAddress(marketContractAddress)
    {
        MarketContract marketContract = MarketContract(marketContractAddress);
        require(marketContract.isPostSettlementDelay(), "Contract is not past settlement delay");
    
        // burn tokens being redeemed.
        MarketSide marketSide;
        uint absQtyToRedeem = qtyToRedeem.abs(); // convert to a uint for non signed functions
        if (qtyToRedeem > 0) {
            marketSide = MarketSide.Long;
            marketContract.redeemLongToken(absQtyToRedeem, msg.sender);
        } else {
            marketSide = MarketSide.Short;
            marketContract.redeemShortToken(absQtyToRedeem, msg.sender);
        }
    
        // calculate amount of collateral to return and update pool balances
        uint collateralToReturn = MathLib.calculateNeededCollateral(
            marketContract.PRICE_FLOOR(),
            marketContract.PRICE_CAP(),
            marketContract.QTY_MULTIPLIER(),
            qtyToRedeem,
            marketContract.settlementPrice()
        );
    
        contractAddressToCollateralPoolBalance[marketContractAddress] = contractAddressToCollateralPoolBalance[
            marketContractAddress
        ].subtract(collateralToReturn);
    
        // return collateral tokens
        ERC20(marketContract.COLLATERAL_TOKEN_ADDRESS()).safeTransfer(msg.sender, collateralToReturn);
    
        emit TokensRedeemed(
            marketContractAddress,
            msg.sender,
            absQtyToRedeem,
            collateralToReturn,
            uint8(marketSide)
        );
    }
    

    After settlement has occurred, plus a brief delay of 24 hours to ensure accuracy of settlement pricing, holders of either Short or Long Position Tokens are able to redeem their tokens. Position Token holders will be allocated the correct amount of collateral back based on the settlement price of the contract, for every unit of collateral a holder of a Long Position Token made, the holder of the Short Position Token will have lost (or vise versa).

    Trading Position Tokens

    Position Tokens are ERC20 tokens and are therefore tradeable anywhere they are listed, including our platform MPX

    MPX

    MPX provides users a platform to allow minting, redemption and trading of MARKET Protocol Position Tokens

    MPX is currently running on mainnet, with limited functionality here.

    Using an Ethereum-enabled browser

    To interact with MPX, you will need to use a browser that supports Web3. We recommend using the Metamask Chrome Browser Extension. This will enable you to connect to the Ethereum network from your browser. Metamask allows you to run Ethereum dApps right in your browser without running a full Ethereum node.

    API

    Introduction

    The MPX API follows the JSON:API 1.0 specification. Per the spec, the application/vnd.api+json media type should be used for all requests. All responses will also be provided in this media type. Response bodies will always include Resource Objects, Error Objects, or Links.

    API - Authentication

    curl -X GET -k -H 'Authorization: Bearer [TOKEN]' -i 'https://api.mpexchange.io'
    

    The MPX API uses JWT bearer tokens sent in the Authorization header for authenticating requests. Any ETH address can obtain a valid JWT without further registration.

    Obtain an unsigned token and nonce.

    curl -X GET -k -i 'https://api.mpexchange.io/json_web_tokens/0x2846A3E4c616F652DEA0140Cfda189363E64f07f'
    
    {
      "data": {
        "type": "json-web-tokens",
        "id": "0x2846a3e4c616f652dea0140cfda189363e64f07f",
        "attributes": {
          "nonce": "5c45b580-b1a1-4d42-89c3-34b164c4c242",
          "signature": null,
          "token": "ieyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
        }
      },
      "jsonapi": {
        "version": "1.0"
      }
    }
    

    Begin by requesting an unsigned token and nonce from the GET /json_web_tokens/:addressendpoint.

    Sign the nonce

    curl -X PUT -k -i 'https://api.mpexchange.io/json_web_tokens/0x2846A3E4c616F652DEA0140Cfda189363E64f07f' --data '{
      "data": {
        "type": "json-web-tokens",
        "id": "0x2846a3e4c616f652dea0140cfda189363e64f07f",
        "attributes": {
          "nonce": "5c45b580-b1a1-4d42-89c3-34b164c4c242",
          "signature": "0x9c8df72254b38f8a6ab5107b5e977...",
          "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
        }
      }
    }'
    
    {
      "data": {
        "type": "json-web-tokens",
        "id": "0x2846a3e4c616f652dea0140cfda189363e64f07f",
        "attributes": {
          "nonce": "5c45b580-b1a1-4d42-89c3-34b164c4c242",
          "signature": "0x9c8df72254b38f8a6ab5107b5e977...",
          "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
        }
      },
      "jsonapi": {
        "version": "1.0"
      }
    }
    

    A nonce value will be returned at the JSON path /data/attributes/nonce. Sign it with your ETH address and compose a PUT or PATCH request to the same endpoint. The body of the request should be a json-web-tokens Resource·Object containing the original nonce, unsigned token, and the signed nonce as signature.

    NOTE: The easiest way to sign the nonce manually is with MEW.

    The resulting response will include your valid JWT bearer token in at the JSON path /data/attributes/token. Please note that the token returned from the initial get request is not valid for use as an Authorization bearer token. Only the token returned from the second request can be used as a bearer token.

    First time authentication

    Though it is possible to sign in and access the read only sections of the API with any ETH address, basic user information must be provided in order to create orders or otherwise trade. Please visit MPX and sign up for a user account using the ETH address you intend to use with the API. Until you do so, several of the endpoints described later in this documentation will return an unauthorized response.

    API - Endpoints

    curl -X GET -k -i 'https://api.mpexchange.io'
    

    A list of all available endpoints can be accessed by making a get request to the root endpoint (GET /). The response body will include a Links object whose keys are the base path for each endpoint. Each corresponding value contains a description, a list of actions, and a list of HTTP methods available. Also included will be an array of available filters for the index action and a template for the create action, if appropriate.

    {
      "links": {
    

    /contracts

        "contracts": {
          "href": "http://api.mpexchange.io/contracts",
          "meta": {
            "actions": ["index", "show"],
            "description": "...",
            "methods": ["GET"],
            "filters": ["isSettled", "isWhitelisted"]
          }
        },
    

    Provides a list of MARKET Protocol contracts. Individual contracts can be queried via the show endpoint.

    /fee_recipients

        "fee_recipients": {
          "href": "http://api.mpexchange.io/fee_recipients",
          "meta": {
            "actions": ["index"],
            "description": "...",
            "methods": ["GET"]
          }
        },
    

    Provides a list of fee recipients. Orders must have the correct fee recipient in order to be accepted.

    /fills

        "fills": {
          "href": "http://api.mpexchange.io/fills",
          "meta": {
            "actions": ["index", "show"],
            "description": "...",
            "methods": ["GET"],
            "filters": [
              "maker-address",
              "maker-asset-address",
              "maker-asset-data",
              "order-hash",
              "pair-name",
              "sender-address",
              "taker-address",
              "taker-asset-address",
              "taker-asset-data",
              "transaction-hash"
            ]
          }
        },
    

    Provides a list of fills. Individual fills can be queried via the show endpoint.

    /json_web_tokens

        "json_web_tokens": {
          "href": "http://api.mpexchange.io/json_web_tokens",
          "meta": {
            "actions": ["show", "update"],
            "description": "...",
            "methods": ["GET", "PATCH", "PUT"]
          }
        }
    

    Allows for the creation of JWT tokens. See more in the Authentication section of this documentation.

    /orderbooks

        "orderbooks": {
          "href": "http://api.mpexchange.io/orderbooks",
          "meta": {
            "actions": ["index", "show"],
            "description": "...",
            "methods": ["GET"]
          }
        },
    

    Returns a list of available orderbooks. Each orderbook can be retrieved in full at the show endpoint.

    /orders

        "orders": {
          "href": "http://api.mpexchange.io/orders",
          "meta": {
            "actions": ["create", "destroy", "index", "show"],
            "description": "...",
            "methods": ["DELETE", "GET", "POST"],
            "filters": [
              "exchange-address",
              "maker-address",
              "maker-asset-address",
              "maker-asset-data",
              "pair-name",
              "sender-address",
              "state",
              "taker-asset-address",
              "taker-asset-data"
            ],
            "template": {
              "exchange-address": {
                "required": true,
                "type": "string"
              },
              "expiration-time-seconds": {
                "required": true,
                "type": "number"
              },
              "fee-recipient-address": {
                "required": true,
                "type": "string"
              },
              "hash": {
                "required": true,
                "type": "string"
              },
              "maker-address": {
                "required": true,
                "type": "string"
              },
              "maker-asset-amount": {
                "required": true,
                "type": "number"
              },
              "maker-asset-data": {
                "required": true,
                "type": "string"
              },
              "maker-fee": {
                "required": true,
                "type": "number"
              },
              "salt": {
                "required": true,
                "type": "number"
              },
              "sender-address": {
                "required": true,
                "type": "string"
              },
              "signature": {
                "required": true,
                "type": "string"
              },
              "state": {
                "required": true,
                "type": "string"
              },
              "taker-address": {
                "required": true,
                "type": "string"
              },
              "taker-asset-amount": {
                "required": true,
                "type": "number"
              },
              "taker-asset-data": {
                "required": true,
                "type": "string"
              },
              "taker-fee": {
                "required": true,
                "type": "number"
              }
            }
          }
        },
    

    Returns a list of all orders. Individual orders can be retrieved via the show endpoint. Authenticated users can also create new orders and delete (cancel) their own orders. The cancellation must also take place on chain to ensure an order is no longer able to be filled, but a call to here will remove it from our orderbooks.

    NOTE: To create a user, please visit MPX and follow the registration process.

    /settings

        "settings": {
          "href": "http://api.mpexchange.io/settings",
          "meta": {
            "actions": ["index", "show"],
            "description": "...",
            "methods": ["GET"]
          }
        },
    

    Returns a list of system wide settings.

    /token_pairs

        "token_pairs": {
          "href": "http://api.mpexchange.io/token_pairs",
          "meta": {
            "actions": ["index", "show"],
            "description": "...",
            "methods": ["GET"],
            "filters": [
              "base-token-address",
              "base-token-asset-data",
              "base-token-symbol",
              "is-enabled",
              "is-market-position-token",
              "pair-name",
              "quote-token-address",
              "quote-token-asset-data",
              "quote-token-symbol"
            ]
          }
        },
    

    Provides a list of all Token Pairs being traded on the platform.

    /user_settings

        "user_settings": {
          "href": "http://localhost:5001/user_settings",
          "meta": {
            "actions": [
              "show",
              "update"
            ],
            "description": "...",
            "methods": [
              "GET",
              "PATCH",
              "PUT"
            ]
          },
          "template": {
            "default-gas": {
              "required": true,
              "type": "slow|average|fast"
            }
          }
        },
    

    User configurable settings

        "self": {
          "href": "http://api.mpexchange.io",
          "meta": {
            "actions": ["index"],
            "description": "...",
            "methods": ["GET"]
          }
        }
      },
      "meta": {
        "about": "This API is provided to interact with MPX and MARKET Protocol. It implements a custom version of the 0x Protocol relayer API",
        "copyright": "Copyright 2019 Market Protocol LLC",
        "license": "license goes here",
        "support": "support@marketprotocol.io",
        "website": "https://mpexchange.io"
      },
      "jsonapi": {
        "version": "1.0"
      }
    }
    

    API - Data Types

    Templates contain data type information for each attribute. Below is a description of each type returned.

    boolean

    true || false
    

    Either the value true or the value false. These values should not be in quotation marks.

    numeric

    "0.002"
    

    A string value representing a number. These values should be in quotation marks.

    string

    "Thank you for using MARKET Protocol"
    

    Any non-numeric string value. Any character in the UTF-8 character set is acceptable. These values should be in quotation marks.

    Getting help

    Email

    You can reach us by email at support@marketprotocol.io.

    Contributing

    Want to hack on MARKET Protocol? Awesome!

    MARKET Protocol is an Open Source project and we welcome contributions of all sorts. There are many ways to help, from reporting issues, contributing code, to helping us improve our community.

    Please start by reading about our:

    Development Process

    We follow the GitFlow branching model for development. The latest merged code generally lives in the develop branch of each repository. Your development flow should look like:

    1. Find an interesting issue and communicate! Please let the #engineering Discord channel know what you want to work on
    2. Add a comment to the issue so we don't have multiple contributors unintentionally working on the same task.
    3. Please include your intended solution and a time frame for completion in the issue.
    4. Start with the develop branch and create a new feature branch
    5. Follow the appropriate coding style and write some awesome code
    6. See here for some notes on good commit messages
    7. Open a pull request to the develop branch, not master

    Gitcoin and Bounties

    We are very proud users of Gitcoin. It allows us an easy way to reward our community members for their hard work contributing to MARKET Protocol. Additionally, it allows us to gain traction on issues that are a priority for us to address. We won't always stake every issue, but if you need a bounty to encourage your participation on an issue, and there isn't one yet, please reach out on Discord.

    There are a few guidelines when using Gitcoin that are worth mentioning

    1. Please only start work on an issue when you are actually planning on working on it. Don't call dibs before you can allocate time to the issue
    2. Please make sure to comment in the issue immediately after starting work so we know your plans for implementation and a timeline.
    3. We politely ask that users only have open work on a single bounty at a time, if you have an open bounty that has a PR submitted and would like to tackle another issue, please ask in Discord before proceeding
    4. We will do our best to scope out the issue, but please anticipate some revision requested after you have submitted a PR, we are happy to tip you if these end up well beyond the initial scope
    5. Once you have created a PR, please submit work on Gitcoin so we are able to pay you out once we have accepted the work

    Coding Style

    We use a variety of programming languages in our repositories. When contributing, please follow the existing coding conventions according to the CONTRIBUTING.md file of each repository.

    Project Link
    MARKETProtocol MARKETProtocol

    Git Flow

    We are implementing Git Flow for our branching model.

    Git Branching

    Branching

    $ git checkout -b feature/my-feature develop
    and hotfix branches (prefixed with hotfix/ by convention) off of master:
    
    # hotfix the latest version of master
    $ git checkout -b hotfix/hotfix-version-number master
    
    # or hotfix from a specific version
    $ git checkout -b hotfix/hotfix-version-number <starting-tag-name>
    

    The main trunks which are persistent are develop and master; Master holds the latest release and develop holds the latest stable development copy.

    Contributors create feature branches (prefixed with feature/ by convention) off of develop.

    These new branches are disposable, meaning they have a short lifespan before they are merged back to the main trunks. They are meant to encapsulate small pieces of functionality.

    Finishing Branches

     $ git checkout develop
     $ git merge --no-ff feature/my-feature
     $ git branch -d feature/my-feature
    

    When a contributor is done with a feature branch, they merge it back into develop, or create a pull request in order to have MARKET Protocol core team do so.

    For a hotfix branch, it is merged back into both master and develop so the hotfix carries forward

     $ git checkout master
     $ git merge --no-ff hotfix/hotfix-version-number
     $ git checkout develop
     $ git merge --no-ff hotfix/hotfix-version-number
     $ git branch -d hotfix/hotfix-version-number
    

    Releases

    A release branch is created from the stable develop branch with a tag.

    Using a separate release branch allows us to continue developing new features on develop while we fix bugs and add finishing touches to a release branch.

    When we are ready to finish the release, we merge the release branch into both master and develop (just like a hotfix) so that all changes carry forward. The master branch is tagged at this point as well to mark the released code.

    Merging

    $ git merge --no-ff <branch-name>
    

    Git flow encourages merging of branches with --no-ff

    The --no-ff option allows you to maintain all of your branch history without leaving a bunch of branches lying around in the current commit of the repository.

    $ git pull --rebase
    

    Similarly, best practice is to pull with --rebase to avoid lots of useless merge commits.

    You can configure git to do both of these things by default in your .gitconfig

    git-flow extension

    Using the git-flow extension can greatly simplify your life and is recommended

    Community Guidelines

    We want to keep the MARKET Protocol community awesome, growing and collaborative. We need your help to keep it that way. To help with this we've come up with some general guidelines for the community as a whole:

    Full code of conduct is posted available here.

    Community Improvement

    MARKET Protocol is just as much about community as it is about our technology.

    We need constant help in improving our documentation, building new tools to interface with our platform, spreading the word to new users, helping new users getting setup and much more.

    Please get in touch if you would like to help out. Our #general channel on Discord is a great place to share ideas and volunteer to help.

    Full Time Positions

    MARKET Protocol occasionally hires developers for part time or full time positions.

    We have a strong preference for hiring people who have already started contributing to the project. If you want a full time position on our team, your best shot is to engage with our team and start contributing code. It is very unlikely that we would offer you a full time position on our engineering team unless you've had at least a few pull requests merged.

    Bug Reporting

    If you find bugs, mistakes or inconsistencies, please let us know by filing an issue on GitHub (see details bellow). We highly appreciate you taking the time to contributing to MARKET Protocol.

    We use GitHub for many aspects of project management, including recording meeting notes, outstanding decisions, documenting requests, and filing bugs. Therefore, if you ever find a bug in any of our applications, please report it on GitHub. See details below.

    What's GitHub?

    GitHub is a version control system, a place where developers store their code. It's the place where our community stores all the code for our entire project.

    GitHub allows groups of developers to collaborate on the same documents (often source code) simultaneously and without overriding each other’s work.

    Create a GitHub account

    In order to report your findings on GitHub, you need to have a GitHub account. If you don't have one yet, you can easily sign up for one for free.

    Please, see: Signing up for a new GitHub account

    Creating a Bug Report

    To report a bug related to MARKET Protocol applications, please create an issue in our GitHub.

    In our GitHub repositories, issues can be created by anyone and are then moderated by our core collaborators.

    To create a new issue in our GitHub click on this link, or you view existing issues and click on the New Issue button to add yours.

    If you are able, please help us by creating the issue in the correct sub project, using the links below.

    When filing a new bug, please include:

    See also: Creating an issue

    Security Issues

    The MARKET Protocol and its implementations are still in early development, which means there may be problems with the protocol or in our implementations. We take security vulnerabilities very seriously. If you discover a security issue, please bring it to our attention right away!

    If you find a vulnerability please send your report privately to support@marketprotocol.io Please DO NOT file a public issue.

    If the issue is a protocol weakness or something not yet deployed, feel free to discuss it openly.