NAV Navbar
  • Introduction
  • Solidity Smart Contracts
  • MPX
  • API
  • API - Authentication
  • API - Endpoints
  • API - Data Types
  • FAQ
  • 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

    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/0x2846a3e4c616f652cda0140ceda189363e64e55e'
    
    {
      "data": {
        "type": "json-web-tokens",
        "id": "0x2846a3e4c616f652cda0140ceda189363e64e55e",
        "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/0x2846a3e4c616f652cda0140ceda189363e64e55e' --data '{
      "data": {
        "type": "json-web-tokens",
        "id": "0x2846a3e4c616f652cda0140ceda189363e64e55e",
        "attributes": {
          "nonce": "5c45b580-b1a1-4d42-89c3-34b164c4c242",
          "signature": "0x9c8df72254b38f8a6ab5107b5e977...",
          "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
        }
      }
    }'
    
    {
      "data": {
        "type": "json-web-tokens",
        "id": "0x2846a3e4c616f652cda0140ceda189363e64e55e",
        "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.

    FAQ

    What is MARKET Protocol?

    TLDR: MARKET Protocol, an open and permissionless protocol built on the Ethereum blockchain, provides the framework needed to create Position Tokens representing the prices of either crypto or traditional assets.

    MARKET Protocol provides users with a trustless and secure framework for creating decentralized derivative Position Tokens, including the necessary collateral pool and position clearing infrastructure. Creating (or minting) positions results in ERC-20 tokens that function like derivatives by providing price exposure to a reference asset, either digital or traditional. Reference digital assets are not limited to ERC-20 tokens, allowing price exposure to cryptocurrencies like Bitcoin, Ripple, and Monero. With MARKET Protocol, traders will be able to gain long and short exposure to any asset. By utilizing a prefunded and shared collateral pool, all trades will always be solvent.

    What is the purpose of the MARKET Protocol Token, MKT?

    At launch, MARKET Protocol’s native token MKT can be used to pay reduced Position Token minting fees on MPX.

    There is a fixed supply of 600 million MKT tokens. MKT is listed and available for trading on MPX.

    What are Position Tokens?

    Position Tokens are a way to gain price exposure, with safe leverage, to assets. They are ERC-20 tokens that can be traded on any exchange that supports the ERC-20 token standard. When they are created (through a process we call minting) collateral is locked in a smart contract in return for long and short Position Tokens. The long tokens are worth more if the price of the asset goes up, and short tokens are worth more if the price goes down.

    What is sBTC and LBTC

    sBTC is a position token that is short BTC/DAI. As the price of BTC declines, sBTC increases in value.

    LBTC is a position token that is long BTC/DAI. As the price of BTC goes up, LBTC increases in value.

    How do I price Position Tokens?

    Please check out our blog post for more information on pricing position tokens.

    What are the components that make up a Position Token?

    How do I view the Price Floor and Price Cap of a Position Token?

    You can view a Position Token’s Price Floor and Price Cap by navigating to the MPX Dashboard, selecting the Position Token, and then by clicking the three dots to the right of the expiration countdown.

    Do Position Tokens come with leverage?

    Position Tokens provide implicit leverage to their holders. For a trader acquiring a long token, the amount he trades for the token is the position’s maximum downside. This is always less than the notional value of the position (the current price of the reference asset).

    The amount of leverage depends on the range of the contract (the difference between the Price Cap and Price Floor) relative to the price of a reference asset. All else equal, a narrower range provides more leverage than a wider range.

    Leverage offered through MARKET Protocol Position Tokens differs from traditional leverage, which runs the risk of forced liquidations and unfunded positions. Instead, Position Tokens are fully backed by the collateral contributed during the token minting process. At any point in time, this collateral fully covers the maximum gain and loss of all tokens.

    Where can I view my current Position Tokens?

    You can view your current Position Tokens in your wallet located on the MPX Dashboard.

    How do I know when a Position Token expires?

    At the top of the MPX Dashboard, you will see the current selected trading pair. For a selected Position Token, you can also see the expiration date, as well as a countdown to expiration.

    How do I know when a Position Token that I’m holding has expired?

    You can view your Position Tokens and see if they have expired by navigating to the expired submenu in your wallet, located on the MPX Dashboard. In the future, you will be able to set up personalized notifications.

    How do I redeem Position Tokens after settlement?

    After settlement has occurred, plus a delay of 24 hours to ensure accuracy of settlement pricing, holders of short or long Position Tokens will be able to redeem their tokens. The smart contract will allocate Position Token holders the correct amount of collateral based on the settlement price of the contract. To redeem your tokens, navigate to the MPX Mint/Redeem Positions dashboard.

    What oracle is used to settle Position Tokens?

    Position Tokens use an internal oracle service built for MPX. This oracle sources data from price feeds provided by CoinCap.io.

    What happens if a Position Tokens expires based on an incorrect price?

    We have a support team that can handle these inquiries. Users have 24 hours after expiration to initiate a dispute by contacting our team at support@marketprotocol.io. If an incorrect price is detected, then the contract will enter a disputed state. The value will be corrected, and the smart contract will subsequently distribute funds based on the correct price.

    What is shorting?

    Shorting, or short-selling, is when a trader seeks to profit from a decline in the price of an asset.

    How does trading work?

    BTC/DAI Position Token Trading Example:

    Bob thinks BTC is going to decline in value. By holding short BTC/DAI tokens, he can profit if his view is correct. He has two ways he can go short BTC/DAI:

    1. Go on any exchange (for example MPX) that lists short BTC/DAI and buy those tokens.
    2. Or he could mint a pair of long and short Position Tokens and then sell his long tokens. After that, he’ll be left with only short BTC/DAI tokens.

    How does minting work?

    Minting is the process of creating Position Tokens. The collateral, which is at stake in the trade, is locked in a smart contract. Once the collateral is locked, the minter receives freshly minted long and short Position Tokens in her wallet. She can then trade them with whomever she wants.

    BTC/DAI Position Token Minting Example:

    Alice wants to create BTC/DAI positions tokens. She goes to MPX and clicks the Mint/Redeem Positions icon in the top right. Then she selects “Mint Tokens”. After selecting the BTC/DAI contract, she inputs the quantity of DAI she wants to lock and clicks “Approve Tokens for Minting”. Her DAI is removed from her wallet and locked in the smart contract. She now has both long BTC and short BTC tokens in her wallet.

    How much collateral is required to mint Position Tokens?

    The required amount of collateral for your order will be automatically calculated when you select a quantity and price.

    How is the collateral necessary to mint Position Tokens calculated?

    The amount of collateral required to mint a pair of Position Tokens can be calculated by taking the difference between the Price Cap and the Price Floor multiplied by the Quantity. The Price Cap and Price Floor are defined upon the deployment (creation) of a new Position Token contract. The collateral required to mint a pair of tokens represents the entire possible range of trading outcomes at settlement. A pair of long and short Position Tokens should always be worth this amount since the pair can be redeemed for a return of collateral at any time.

    How does redemption work?

    Redemption is the opposite of minting. While minting creates Position Tokens and locks collateral, redemption is a process that destroys Position Tokens and releases collateral.

    On MPX, click the Mint/Redeem Positions icon on the top right, then click “Redeem Tokens”. Next, select the contract for which you want to redeem tokens. Input the number of tokens you would like to redeem and click “Redeem Tokens”. Please note that prior to expiration, you must redeem an equal amount of long and short tokens. After expiration you will be able to redeem either long or short tokens separately.

    How do I log in to MPX?

    To interact with MPX, you will need to use the MetaMask browser extension. MetaMask allows you to connect to Ethereum dApps using your internet browser.

    Why is MPX not available in my region?

    MPX is currently available only to users who are not residents of the United States, Cuba, Iran, Syria, North Korea, the Crimea region.

    Is there an MPX mobile app or website?

    MPX has been built to provide an optimal experience on desktop browsers. We will deliver a mobile-friendly experience in a future release.

    How do I begin trading Position Tokens?

    To begin trading on MPX, you will need DAI. You can also use DAI as collateral to mint Position Tokens.

    What Position Tokens are available for trading on MPX?

    We currently support trading of both long and short BTC/DAI tokens. Soon we will enable other Position Tokens like ETH/DAI and LTC/DAI, and also off-chain assets.

    Can I use ETH to trade on MPX?

    Currently, ETH is not ERC-20 compliant. Instead, MPX allows for the use of wrapped ETH, or WETH, which itself is ERC-20 compliant. ETH can be wrapped and unwrapped using the 0x Portal. Visit www.weth.io for more information.

    Are there fees to use MPX?

    Peer-to-peer trading is free on MPX, however, minting Position Tokens requires a small fee paid in DAI or MKT. If paid in MKT, then the fee is discounted.

    What is an order book?

    An order book is a ledger containing all outstanding orders – inputs from traders looking to buy or sell an asset. An order to buy is called a ‘bid’ and an order to sell is called an ‘ask’.

    What is the difference between a maker and a taker?

    A maker is a trader creating a new buy or sell order, while a taker is a trader filling an existing order. Makers create or ‘make’ liquidity, while takers take liquidity.

    How do I fill an order?

    To fill an order in the order book, you select the order, choose the quantity you would like to trade, and then confirm the transaction through MetaMask.

    How do I create an order?

    To create an order, you select whether your order is to buy or sell, choose the quantity, choose the price, input the expiration date and time, click to place the order, and then sign the order through MetaMask.

    Where can I view my pending orders?

    You can view your orders on the MPX Dashboard.

    How do I know if my transaction was successful?

    When you create or fill an order, you will receive a notification containing the transaction hash and a link to Etherscan where you can view your transaction.

    Where can I view my completed trades?

    You can view your trade history on the MPX Dashboard.

    Is there a minimum amount required to make a trade?

    No, there is no minimum required trade amount.

    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.