NAV Navbar
  • Introduction
  • Solidity Smart Contracts
  • MARKET.js
  • Tutorial #1 - Orders
  • dApp
  • FAQ - General
  • FAQ - MARKET Protocol
  • FAQ - Solidity Smart Contracts
  • FAQ - API
  • FAQ - dApp
  • Getting help
  • Contributing
  • Bug Reporting
  • Introduction

    Welcome to 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 contractName viewable name of this contract (BTC/ETH, LTC/ETH, etc)
    /// @param creatorAddress address of the person creating the contract
    /// @param marketTokenAddress address of our member token
    /// @param collateralTokenAddress address of the ERC20 token that will be used for collateral and pricing
    /// @param collateralPoolFactoryAddress address of the factory creating the collateral pools
    /// @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.
    /// expirationTimeStamp - seconds from epoch that this contract expires and enters settlement
    constructor(
        string contractName,
        address creatorAddress,
        address marketTokenAddress,
        address collateralTokenAddress,
        address collateralPoolFactoryAddress,
        uint[5] contractSpecs
    ) public
    {
        COLLATERAL_POOL_FACTORY_ADDRESS = collateralPoolFactoryAddress;
        MKT_TOKEN_ADDRESS = marketTokenAddress;
        MKT_TOKEN = MarketToken(marketTokenAddress);
        require(MKT_TOKEN.isBalanceSufficientForContractCreation(msg.sender));    // creator must be MKT holder
        PRICE_FLOOR = contractSpecs[0];
        PRICE_CAP = contractSpecs[1];
        require(PRICE_CAP > PRICE_FLOOR);
    
        PRICE_DECIMAL_PLACES = contractSpecs[2];
        QTY_MULTIPLIER = contractSpecs[3];
        EXPIRATION = contractSpecs[4];
        require(EXPIRATION > now);
    
        CONTRACT_NAME = contractName;
        COLLATERAL_TOKEN_ADDRESS = collateralTokenAddress;
        creator = creatorAddress;
    }
    

    The MarketContract represents the main contract responsible for combining needed functionality for trading, settlement and position management. Each MarketContract must be paired with a unique MarketCollateralPool (see below) after instantiation in order to allow trading to become enabled.

    Contract Diagram

    MarketContract is an abstract contract that will allow for implementing classes such as MarketContractOraclize to complete the needed top level functionality around oracle solutions. We intend to expand our offering of oracle solutions offered in the near future.

    Oracle Costs

    The Creator of the MarketContract must pre-fund the contract with enough ETH in order to pay for the gas costs associated with the needed oracle query. Currently from Oraclize.it - the first query for any contract is free, so this need has been removed.

    Parameter Description
    contractName viewable name of this contract, in the future we will implement suggested naming conventions
    marketTokenAddress address of the MKT deployed ERC20 token
    collateralTokenAddress address of the ERC20 token that will be used for collateral
    contractSpecs array of unsigned integers including the below parameters
    floorPrice minimum tradeable price of this contract
    capPrice maximum tradeable price of this contract
    expirationTimeStamp seconds from epoch that this contract expires and enters settlement

    Market Contract Oraclize

    MarketContractOraclize constructor:

    /// @param contractName viewable name of this contract (BTC/ETH, LTC/ETH, etc)
    /// @param creatorAddress address of the person creating the contract
    /// @param marketTokenAddress address of our member token
    /// @param collateralTokenAddress address of the ERC20 token that will be used for collateral and pricing
    /// @param collateralPoolFactoryAddress address of the factory creating the collateral pools
    /// @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.
    /// expirationTimeStamp - seconds from epoch that this contract expires and enters settlement
    /// @param oracleDataSource a data-source such as "URL", "WolframAlpha", "IPFS"
    /// see http://docs.oraclize.it/#ethereum-quick-start-simple-query
    /// @param oracleQuery see http://docs.oraclize.it/#ethereum-quick-start-simple-query for examples
    constructor(
        string contractName,
        address creatorAddress,
        address marketTokenAddress,
        address collateralTokenAddress,
        address collateralPoolFactoryAddress,
        uint[5] contractSpecs,
        string oracleDataSource,
        string oracleQuery
    ) MarketContract(
        contractName,
        creatorAddress,
        marketTokenAddress,
        collateralTokenAddress,
        collateralPoolFactoryAddress,
        contractSpecs
    )  public
    {
        oraclize_setProof(proofType_TLSNotary | proofStorage_IPFS);
        ORACLE_DATA_SOURCE = oracleDataSource;
        ORACLE_QUERY = oracleQuery;
        require(EXPIRATION > now);         // Require expiration time in the future.
    
        // Future timestamp must be within 60 days from now.
        // https://docs.oraclize.it/#ethereum-quick-start-schedule-a-query-in-the-future
        uint secondsPerSixtyDays = 60 * 60 * 24 * 60;
        require(EXPIRATION - now <= secondsPerSixtyDays);
        queryOracle();                      // Schedule a call to oracle at contract expiration time.
    }
    

    MarketContractOraclize is the first fully implemented MarketContract that has been built out. Using Oraclize.it allows for several different sources of truth in order to settle contracts. More information on forming correct queries can be found in their documentation.

    Our dApp additionally has some help in formatting your queries correctly and a test environment to ensure the queries are correct prior to contract deployment.

    Additional parameters

    Parameter Description
    oracleDataSource a data-source such as "URL", "WolframAlpha", "IPFS"
    oracleQuery properly formatted Oraclize.it query

    Market Collateral Pool

    MarketCollateralPool constructor:

    /// @dev instantiates a collateral pool that is unique to the supplied address of a MarketContract. This pairing
    /// is 1:1
    /// @param marketContractAddress deployed address of a MarketContract
    constructor(address marketContractAddress) Linkable(marketContractAddress) public {
        MKT_CONTRACT = MarketContract(marketContractAddress);
        MKT_TOKEN_ADDRESS = MKT_CONTRACT.MKT_TOKEN_ADDRESS();
    }
    

    The MarketCollateralPool is a contract controlled by a specific MarketContract. It holds users balances, locked collateral balances and open positions accounting. These balances and positions are unique to the linked MarketContract and a user must deposit funds for each MarketContract they intend to trade. The ERC20 Token specified are the only accepted form of funding or collateralization.

    Factory deployment

    MarketContractOraclize factory for deployment:

    /// @dev Deploys a new instance of a market contract and adds it to the whitelist.
    /// @param contractName viewable name of this contract (BTC/ETH, LTC/ETH, etc)
    /// @param collateralTokenAddress address of the ERC20 token that will be used for collateral and pricing
    /// @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.
    /// expirationTimeStamp - seconds from epoch that this contract expires and enters settlement
    /// @param oracleDataSource a data-source such as "URL", "WolframAlpha", "IPFS"
    /// see http://docs.oraclize.it/#ethereum-quick-start-simple-query
    /// @param oracleQuery see http://docs.oraclize.it/#ethereum-quick-start-simple-query for examples
    function deployMarketContractOraclize(
        string contractName,
        address collateralTokenAddress,
        uint[5] contractSpecs,
        string oracleDataSource,
        string oracleQuery
    ) external
    {
        MarketContractOraclize mktContract = new MarketContractOraclize(
            contractName,
            msg.sender,
            MKT_TOKEN_ADDRESS,
            collateralTokenAddress,
            collateralPoolFactoryAddress,
            contractSpecs,
            oracleDataSource,
            oracleQuery
        );
        MarketContractRegistryInterface(marketContractRegistry).addAddressToWhiteList(mktContract);
        emit MarketContractCreated(address(mktContract));
    }
    

    MarketCollateralPool factory for deployment:

    /// @dev creates the needed collateral pool and links it to our market contract.
    /// @param marketContractAddress address of the newly deployed market contract.
    function deployMarketCollateralPool(address marketContractAddress) external {
        require(MarketContractRegistryInterface(marketContractRegistry).isAddressWhiteListed(marketContractAddress));
        MarketCollateralPool marketCollateralPool = new MarketCollateralPool(marketContractAddress);
        MarketContract(marketContractAddress).setCollateralPoolContractAddress(marketCollateralPool);
    }
    

    Currently two factories exist to aid in the deployment of linked contracts and the whitelisting of these contracts in the MarketContractRegistry, which holds a record of all currently deployed and functional contracts.

    MarketContractOraclize deployment

    First, a user calls deployMarketContractOraclize on the MarketContractFactoryOraclize in order to begin the deployment process.

    This function call creates the new MarketContractOraclize and then adds the address to the MarketContractRegistry so that others may find the contract for trading. A second call to the deployMarketCollateralPool of the MarketCollateralPoolFactory then deploys the needed MarketCollateralPool and links it to the MarketContract. At this point the contract is ready to be traded.

    Collateral

    Depositing funds for trading

    depositTokensForTrading function

    /// @notice deposits tokens to the smart contract to fund the user account and provide needed tokens for collateral
    /// pool upon trade matching.
    /// @param depositAmount qty of ERC20 tokens to deposit to the smart contract to cover open orders and collateral
    function depositTokensForTrading(uint256 depositAmount) external {
        // user must call approve!
        require(MarketToken(MKT_TOKEN_ADDRESS).isUserEnabledForContract(MKT_CONTRACT, msg.sender));
        uint256 balanceAfterDeposit = userAddressToAccountBalance[msg.sender].add(depositAmount);
        ERC20(MKT_CONTRACT.COLLATERAL_TOKEN_ADDRESS()).safeTransferFrom(msg.sender, this, depositAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterDeposit;
        emit UpdatedUserBalance(msg.sender, balanceAfterDeposit);
    }
    

    Funds deposited by a user are allocated to their address's account balance until a point at which a new position is opened and the funds then become allocated to collateralPoolBalance and are locked until the user exits their position or the contract expires. In this way, all open positions are always fully collateralized eliminating any counter party risk and ensuring the solvency of the contract.

    Calculating needed collateral and maximum possible loss

    calculateNeededCollateral function

    /// @notice determines the amount of needed collateral for a given position (qty and price)
    /// @param priceFloor lowest price the contract is allowed to trade before expiration
    /// @param priceCap highest price the contract is allowed to trade before expiration
    /// @param qtyMultiplier multiplier for qty from base units
    /// @param qty signed integer corresponding to the traded quantity
    /// @param price of the trade
    function calculateNeededCollateral(
        uint priceFloor,
        uint priceCap,
        uint qtyMultiplier,
        int qty,
        uint price
    ) pure internal returns (uint neededCollateral)
    {
    
        uint maxLoss;
        if (qty > 0) {   // this qty is long, calculate max loss from entry price to floor
            if (price <= priceFloor) {
                maxLoss = 0;
            } else {
                maxLoss = subtract(price, priceFloor);
            }
        } else { // this qty is short, calculate max loss from entry price to ceiling;
            if (price >= priceCap) {
                maxLoss = 0;
            } else {
                maxLoss = subtract(priceCap, price);
            }
        }
        neededCollateral = maxLoss * abs(qty) * qtyMultiplier;
    }
    

    The amount of funds that are allocated to the collateralPoolBalance upon entering a trade is defined by that positions maximum possible loss.

    All positions are always fully collateralized, meaning the maximum possible loss for a position is the required amount of collateral to open that position. This can be calculated from the price and qty of the position and the defined specifications of the MarketContract.

    For a buyer, the maximum possible loss is calculated as the price of the trade minus the priceFloor times the qty transacted. Conversely, if you are opening a short position the maximum loss is calculated as priceCap minus the price of the trade, multiplied by the qty transacted. Upon filling an order both parties commit their respective maximum loss to the collateral pool.

    Parameter Description
    priceFloor as defined in the MarketContract
    priceCap as defined in the MarketContract
    qtyMultiplier as defined in the MarketContract
    qty signed integer corresponding to the traded quantity
    price agreed upon execution price

    Withdrawing funds

    withdrawTokens function

    /// @notice removes token from users trading account
    /// @param withdrawAmount qty of token to attempt to withdraw
    function withdrawTokens(uint256 withdrawAmount) public {
        //require(userAddressToAccountBalance[msg.sender] >= withdrawAmount);  subtract call below will enforce this
        uint256 balanceAfterWithdrawal = userAddressToAccountBalance[msg.sender].subtract(withdrawAmount);
        userAddressToAccountBalance[msg.sender] = balanceAfterWithdrawal;   // update balance before external call!
        ERC20(MKT_CONTRACT.COLLATERAL_TOKEN_ADDRESS()).safeTransfer(msg.sender, withdrawAmount);
        emit UpdatedUserBalance(msg.sender, balanceAfterWithdrawal);
    }
    

    At any time, tokens that are not allocated to an open position held by the user, are able to be withdrawn.

    Upon exiting a position funds are returned to the user's account balance, net of any profit or loss. Similarly, if the contract expires with the user maintaining an open position, their position settles to the final settlement price of the contract and funds are then eligible for immediate withdraw.

    Orders

    MARKET's Order struct

    struct Order {
        address maker;
        address taker;
        address feeRecipient;
        uint makerFee;
        uint takerFee;
        uint price;
        uint expirationTimeStamp;
        int qty;
        bytes32 orderHash;
    }
    

    Generating and confirming Order signatures

    /// @notice creates the hash for the given order parameters.
    /// @param contractAddress address of the calling contract, orders are unique to each contract
    /// @param orderAddresses array of 3 address. maker, taker, and feeRecipient
    /// @param unsignedOrderValues array of 5 unsigned integers. makerFee, takerFee, price, expirationTimeStamp and salt
    /// @param orderQty signed qty of the original order.
    function createOrderHash(
        address contractAddress,
        address[3] orderAddresses,
        uint[5] unsignedOrderValues,
        int orderQty
    ) public pure returns (bytes32)
    {
        return keccak256(
            abi.encodePacked(
                contractAddress,
                orderAddresses[0],
                orderAddresses[1],
                orderAddresses[2],
                unsignedOrderValues[0],
                unsignedOrderValues[1],
                unsignedOrderValues[2],
                unsignedOrderValues[3],
                unsignedOrderValues[4],
                orderQty
            )
        );
    }
    
    /// @notice confirms hash originated from signer
    /// @param signerAddress - address of order originator
    /// @param hash - original order hash
    /// @param v order signature
    /// @param r order signature
    /// @param s order signature
    function isValidSignature(
        address signerAddress,
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public pure returns (bool)
    {
        return signerAddress == ecrecover(
            keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)),
            v,
            r,
            s
        );
    }
    

    MARKET utilizes off chain orders to reduce the number of needed transactions that must occur on the blockchain. Third party Nodes will provide order book hosting and aggregation services on top of the protocol to facilitate liquidity. Orders however are cryptographically signed to ensure no manipulation and facilitate trust-less executions.

    Makers create orders and sign them (making liquidity), while takers select signed orders to trade against (taking liquidity).

    Parameter Description
    maker address of user who originated and signed this order
    taker address of counter-party to fill order or null to allow any counter-party
    feeRecipient address of fee recipient node, if any (MARKET does not charge any fees, but nodes may)
    makerFee fee to paid by the maker in MKT tokens to the feeRecipient
    takerFee fee to paid by the taker in MKT tokens to the feeRecipient
    price agreed upon execution price
    expirationTimeStamp timestamp that the order is valid until
    qty agreed upon execution qty
    orderHash hash created by maker to ensure all order parameters are valid and originated from maker

    A maker creates an order with the specified parameters and calls createOrderHash that is transmitted along with the order. Any part can verify the veracity of the hash with isValidSignature which will match the signer's address if all parameters of the order are valid.

    Makers may cancel an order at any time, unfortunately this transaction happens on chain and will require gas to complete. Alternatively, an Order can be created with an expirationTimeStamp expiring the order automatically without the additional gas cost.

    Trading

    // @notice called by a participant wanting to trade a specific order
    /// @param orderAddresses - maker, taker and feeRecipient addresses
    /// @param unsignedOrderValues makerFee, takerFree, price, expirationTimeStamp, and salt (for hashing)
    /// @param orderQty quantity of the order
    /// @param qtyToFill quantity taker is willing to fill of original order(max)
    /// @param v order signature
    /// @param r order signature
    /// @param s order signature
    function tradeOrder(
        address[3] orderAddresses,
        uint[5] unsignedOrderValues,
        int orderQty,
        int qtyToFill,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (int filledQty)
    {
        require(isCollateralPoolContractLinked && !isSettled); // no trading past settlement
        require(orderQty != 0 && qtyToFill != 0 && orderQty.isSameSign(qtyToFill));   // no zero trades, sings match
        require(MKT_TOKEN.isUserEnabledForContract(this, msg.sender));
        OrderLib.Order memory order = address(this).createOrder(orderAddresses, unsignedOrderValues, orderQty);
        require(MKT_TOKEN.isUserEnabledForContract(this, order.maker));
    
        // taker can be anyone, or specifically the caller!
        require(order.taker == address(0) || order.taker == msg.sender);
        // do not allow self trade
        require(order.maker != address(0) && order.maker != msg.sender);
        require(
            order.maker.isValidSignature(
                order.orderHash,
                v,
                r,
                s
        ));
    
    
        if (now >= order.expirationTimeStamp) {
            emit Error(ErrorCodes.ORDER_EXPIRED, order.orderHash);
            return 0;
        }
    
        int remainingQty = orderQty.subtract(getQtyFilledOrCancelledFromOrder(order.orderHash));
        if (remainingQty == 0) { // there is no qty remaining  - cannot fill!
            emit Error(ErrorCodes.ORDER_DEAD, order.orderHash);
            return 0;
        }
    
        filledQty = MathLib.absMin(remainingQty, qtyToFill);
        marketCollateralPool.updatePositions(
            order.maker,
            msg.sender,
            filledQty,
            order.price
        );
        orderMappings.addFilledQtyToOrder(order.orderHash, filledQty);
    
        uint paidMakerFee = 0;
        uint paidTakerFee = 0;
    
        if (order.feeRecipient != address(0)) {
            // we need to transfer fees to recipient
            uint filledAbsQty = filledQty.abs();
            uint orderAbsQty = filledQty.abs();
            if (order.makerFee > 0) {
                paidMakerFee = order.makerFee.divideFractional(filledAbsQty, orderAbsQty);
                MKT_TOKEN.safeTransferFrom(
                    order.maker,
                    order.feeRecipient,
                    paidMakerFee
                );
            }
    
            if (order.takerFee > 0) {
                paidTakerFee = order.takerFee.divideFractional(filledAbsQty, orderAbsQty);
                MKT_TOKEN.safeTransferFrom(
                    msg.sender,
                    order.feeRecipient,
                    paidTakerFee
                );
            }
        }
    
        emit OrderFilled(
            order.maker,
            msg.sender,
            order.feeRecipient,
            filledQty,
            paidMakerFee,
            paidTakerFee,
            order.orderHash
        );
    
        return filledQty;
    }
    

    When a taker finds an order they would like to transact against, they call the tradeOrder function.

    This function, verifies the order signature, ensures all contracts and users are allowed to trade and if successful handles the accounting with the associated resulting fills (either open a new position, or perhaps, closing out an existing open position).

    A taker is not required to fill the entire maker order and specifies the qty they are willing to transact. The price however is static as set and signed by the maker.

    Market Contract Registry

    A registry will exist of all MARKET contracts that are approved for trading. Eventually there will be some mechanism for the community to flag contracts that are not valid, or reasonable for removal from the white list. At first this may be more centralized, but eventually the goal is to have a fully decentralized community in charge of such matters.

    MKT Tokens

    alt text

    MKT Tokens are the lifeblood of the MARKET ecosystem. All fees charged by nodes will be transacted in MKT and additionally anyone who wishes to create a new MarketContract will be forced to have some minimum balance of MKT. Finally, for every MarketContract a user desires to trade, some amount of MKT must be locked to enable access to that contract. These can be unlocked at any time the user wishes to stop trading that MarketContract.

    MARKET.js

    All code for this library can be found here. If you have any issues to report or features to request please do so by opening an issue on GitHub.

    Under Construction

    Order Life Cycle

    Note: this is the generalized lifecycle, function calls will be replaced with MARKET.js function calls that provide a simplified abstraction to the underlying solidity calls.

    1. An order is generated from a maker as described here. Signing and hashing this order allows for us to confirm its validity.
    2. Depending on the application, this order may then be broadcast to a third party order book host who may provide further verifications before publishing the order to their orders books, including:
      • Verifying sufficient funding in the MARKET Contract for the maker's address
      • Validating user has locked MKT to allow for access for trading the specified MARKET Protocol smart contract.
    3. The specified taker, or an arbitrary taker (if none specified) is able to call the traderOrder function filling all or a partial qty of the order. This transaction happens on-chain and therefore validates all aspects of the transaction are successful.
    4. Third party order book hosts will be responsible for removing completely filled or completely cancelled orders from their order books. Orders can be cancelled by setting an expirationTimeStamp or by calling the function cancelOrder at any time

    Requirements for a successful traderOrder call

    In order for a taker to not waste gas on a call to traderOrder that will ultimately fail it is important to note the following requirements in order for a transaction to be executed.

    1. MarketContract must be deployed correctly, linked to a MarketCollateralPool and not be in an isSettled state
    2. Both maker and taker must have locked the requisite amount of MKT to enable trading for the specific contract. This can be verified by calling isUserEnabledForContract in the MarketToken smart contract (not enforced on Rinkeby currently).
    3. caller of tradeOrder is either the specified taker in the order, or no taker was specified
    4. the maker and taker are not the same address (no wash trading)
    5. the order has not expired, been cancelled, nor been completely filled
    6. both maker and taker have sufficient balances to lock collateral for attempted trade

    Tutorial #1 - Orders

    This tutorial will go over creating, validating and filling an order using our library MARKET.js. This tutorial utilizes a local development environment in which we have MARKET Protocol Smart Contracts deployed to and trading accounts created that are already pre-funded with the needed tokens for trading.

    Installation

    Clone needed repos:

    
    # 1. clone our demo-project
    git clone https://github.com/MARKETProtocol/demo-projects.git
    
    # 2. clone the ethereum-bridge to allow deployment of our contracts connect to Oraclize.it
    git clone https://github.com/MARKETProtocol/ethereum-bridge.git
    
    # 3. install needed dependencies
    npm install -g truffle
    cd ~/demo-projects
    npm install
    cd ~/ethereum-bridge
    npm install
    
    

    In order to simplify developers interaction with our underlying smart contracts and the ethereum blockchain, we have created the MARKET.js library. It provides a standardized and simplified API to interact with MARKET Protocol. In order to create a development environment, you will need to have a local instance of the blockchain to interact with. For this we recommend using Truffle

    We have also created a demo starter project to help with these tutorials available on github.

    You can clone the repo locally to run the tutorial and begin working with MARKET Protocol. You will also need to clone the ethereum-bridge which allows for our contracts to interact with Oraclize.it for demonstration purposes

    Development Environment

    Start truffle:

    cd ~/demo-projects
    truffle develop
    

    Start the ethereum bridge (in a separate console) :

    cd ~/ethereum-bridge
    node bridge -H localhost:9545 -a 9 --dev
    

    Deploy contracts to the local truffle instance

    # inside truffle console, 
    truffle(develop)> migrate --reset
    
    

    After you have installed these projects and the needed dependencies, you can begin to create the needed development environment.

    1. Start truffle
    2. Start the ethereum bridge (in a separate console)
    3. Once the ethereum bridge has initialized, you will see a log message similiar to [2018-08-22T18:49:30.289Z] INFO Listening @ 0xf7e3e47e06f1bddecb1b2f3a7f60b6b25fd2e233 (Oraclize Connector) you can now run the migrations to deploy our contracts to the local truffle instance.

    If you have followed along this along, congratulations, you have a working local MARKET Protocol environment to work against. We can now move on to our tutorial.

    If you are unable to get the environment set up please come find us in Discord, there are several core dev team members in #engineering that will be happy to help!

    Essential Packages

    Import the needed packages:

    
    import * as Web3 from 'web3';
    import { Constants, Market, MARKETProtocolConfig, Utils } from '@marketprotocol/marketjs';
    
    

    There are a few essential packages for interacting with our protocol, and the ethereum blockchain. Web3 provides the needed functionality for us to connect with our local truffle node, and marketjs is our MARKET.js library designed to simplify your interactions with the underlying MARKET Protocol Smart Contracts.

    Instantiation

    Creating a web3 instance and the Market object:

    
    const web3Instance = new Web3(new Web3.providers.HttpProvider('http://localhost:9545'));
    const config: MARKETProtocolConfig = {
      networkId: Constants.NETWORK_ID_TRUFFLE
    };
    
    const market: Market = new Market(web3Instance.currentProvider, config);
    

    Once we have imported these packages, we can now create an instance of web3, connected to our local truffle node as the provider. Using this provider, we can create a new Market object, which is the main entry point for all functionality contained in MARKET.js

    Contract Specifications

    Getting whitelisted addresses and contract specs:

    
    const marketContractAddress: string[] = await market.getAddressWhiteListAsync();
    const demoContractAddress: string = marketContractAddress[0];
    const contractMetaData = await market.getContractMetaDataAsync(demoContractAddress);
    
    

    The Market class provide methods for getting the current collection of white listed MARKET Protocol Smart Contract addresses and well as meta data about those deployed contracts. It is also important to note, that there is an off chain API that can provide this information to users who need higher level functionality such as queries.

    Deposit Collateral

    Approving collateral transfer and deposit to the smart contract:

    
    const traderA = web3Instance.eth.accounts[0];
    const traderB = web3Instance.eth.accounts[1];
    
    await market.approveCollateralDepositAsync(demoContractAddress, 1e25, {from: traderA});
    await market.approveCollateralDepositAsync(demoContractAddress, 1e25, {from: traderB});
    
    await market.depositCollateralAsync(demoContractAddress, 1e25, {from: traderA});
    await market.depositCollateralAsync(demoContractAddress, 1e25, {from: traderB});
    
    

    Each MARKET Protocol Smart Contract has a unique collateral pool. In order to enable trading, a user must first approve the transfer of funds (an ERC20 token, as defined by the contract) and then call the depositCollateralAsync method. This will allow for ERC20 tokens to be moved from a user's address to the smart contract for trading. Deposited funds, that have not been committed to a trade, may be withdrawn at any time by the user. Upon executing a trade, the users maximum loss will become locked into the collateral pool, and that amount is no longer able to be withdrawn until the trade is exited, or the contract settled.

    Order Creation

    Creating a signed order:

    
    const orderExpirationTimeStamp = new BigNumber(Math.floor(Date.now() / 1000) + 60 * 60); // expires in 1 hour
    const fees = new BigNumber(0);
    const orderQty = new BigNumber(1);
    const orderPrice = new BigNumber(7500000);
    const feeRecipient = Constants.NULL_ADDRESS;
    const signedOrder = await market.createSignedOrderAsync(
      demoContractAddress,
      orderExpirationTimeStamp,
      feeRecipient,
      traderA,
      fees,
      traderB,
      fees,
      orderQty,
      orderPrice,
      Utils.generatePseudoRandomSalt(),
      false
    );
    
    

    After collateral has been deposited, a user is able to create a valid order for trading. This order is signed by the user in order to ensure its origin. Market.js provides several methods for validation of orders that can be used for proper pruning of order books by exchanges.

    Filling an Order

    trading against a signed order:

    
    const orderTransactionInfo: OrderTransactionInfo =
        await market.tradeOrderAsync(signedOrder, orderQty, { from: traderB, gas: 400000 });
    
    // we can now display the information about this filled transaction
    console.log(orderTransactionInfo.txHash, await orderTransactionInfo.filledQtyAsync);
    

    By calling traderOrderAsync against a validated SignedOrder, a user may fill a portion or all of an order. To avoid wasting gas by a call to traderOrderAsync that will ultimately fail, MARKET.js provides as much verification as is possible prior to calling the on-chain transaction.

    If a trade is successfully executed, both counter-parties (TraderA and TraderB) will have their collateral locked, and a newly recorded open position.

    Open Positions

    Querying open positions:

    const isConsolidatePositions: boolean = true;   // consolidate positions from the same price
    const isSortPositions: boolean = true;          // positions sorted by price
    
    console.log('\n Trader A - Open Positions =');
    console.log(await market.getUserPositionsAsync(
        demoContractAddress, traderA, isSortPositions, isConsolidatePositions));
    
    console.log('\n Trader B - Open Positions =');
    console.log(await market.getUserPositionsAsync(
        demoContractAddress, traderB, isSortPositions, isConsolidatePositions));
    
    

    A trader's open positions are recorded onto the blockchain and can be accessed with the getUserPositionsAsync function. Additional functionality is provided for sorting and consolidating the reporting of these positions.

    Remaining Balances

    Retrieving remaining balances:

    console.log('\n Trader A Collateral Balance Remaining =',
        (await market.getUserUnallocatedCollateralBalanceAsync(demoContractAddress, traderA)).toString());
    console.log('\n Trader B Collateral Balance Remaining =',
        (await market.getUserUnallocatedCollateralBalanceAsync(demoContractAddress, traderB)).toString());
    

    The remaining collateral available for trading in the smart contract can be accessed via a call to getUserUnallocatedCollateralBalanceAsync.

    dApp

    The MARKET Protocol dApp provides tools for contract creation, oracle testing and deployment. Additionally, users are able to easily search previously deployed MARKET contracts they would like to trade.

    A simulated trading environment allows user to place test trades and participate in beta releases of the protocol.

    Our beta dApp is currently running on the Rinkeby testnet here.

    Using an Ethereum-enabled browser

    For testing and interacting with our dApp, 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.

    Acquire Test ETH

    Our smart contracts are currently deployed on the Rinkeby testnet. You will need to have test ETH to use this library. You can request test funds from the Rinkeby faucet.

    Contract Deployment

    MARKET Protocol creates a flexible contract specification which allows users to easily implement their desired contract prior to trading. First time users, can use our Guided Deploy process walking them through the step by step process to deployment. Expert users, can opt for a more condensed process with the Quick Deploy

    Guided Deploy

    MARKET Protocol Guided Deploy provides a step by step guide to first time deployment. Below are the needed variables to deploy a contract to the Ethereum Blockchain

    1. Name - the contract name should be as descriptive as possible capturing the underlying asset relationship as well as possibly the expiration. Something like ETH/BTC-Kraken_YYYY-MM-DD may help others understand the underlying asset, the data source, and expiration date in a nice human readable and searchable way. In the future, MARKET will implement a standardized naming convention and guidelines to formalize this process
    2. Collateral Token - every contract should be backed by an ERC20 Token that will be used a collateral for the contract. Traders must deposit tokens to the smart contract prior to trading, and upon execution of a trade, the appropriate amount of collateral becomes locked until that position is exited. In this fashion, all open positions always remain 100% collateralized removing counter party risk from the traders. Please specify a ERC20 Token address for this contract. In the future, users will be able to easily select from well known ERC20 tokens to ensure more safety and avoid dealing with long addresses.
    3. Oraclize.it data source - Oraclize.it offers several data-sources such as "URL" and "WolframAlpha"
    4. Price Decimal Places - Ethereum currently does not support floating points numbers. Therefore all prices reported by oracles must be converted to a whole number (integer). This variable is how many decimal places one needs to move the decimal in order to go from the oracle query price to an integer. For example, if the oracle query results returned a value of 190.22, we need to move the decimal two (2) places to convert to a whole number of 19022, so we would enter 2.
    5. Price Floor - this is the lower bound of price exposure this contract will trade. If the oracle reports a price below this value the contract will enter into settlement. This should also be represented as a whole number. If we take the example above of a price of 190.22 and decide the Floor for our contract should be 150.00, we would enter 15000.
    6. Price Cap - This is the upper bound of price exposure this contract will trade. If the oracle reports a price above this value the contract will enter into settlement. Following our example, if we decide the Cap for our contract should be 230.00, we would enter 23000 as our Cap.
    7. Qty Multiplier - The quantity multiplier allows the user to specify how many base units (for Ethereum, this would be wei) each integer price movement changes the value of the contract. If our integerized price was 19022 with a qty multiplier of 1, and the price moved to 19023, then the value will have change by 1 wei. If however the multiplier was set at 1,000,000,000 the price movement of 1 unit would now correspond to a value of 1 gwei (not wei). Please see here for an ethereum unit converter.
    8. Expiration Time - upon reaching the expiration timestamp all open positions will settle against the final price query returned by the oracle.

    Quick Deploy

    MARKET Protocol Quick Deploy provides a scaled down interface for easy deployment of contracts to the Ethereum blockchain. Expert users can enter variables, that are validated with error checking prior to deploying.

    Parameter Description
    Name Viewable name of this contract, in the future we will implement suggested naming conventions
    Collateral Token Address address of the ERC20 token that will be used for collateral
    Price Floor minimum tradeable price of this contract
    Price Cap maximum tradeable price of this contract
    Price Decimal Places Since all numbers must be represented as integers on the Ethereum blockchain, this is how many decimal places one needs to move the decimal in order to go from the oracle query price to an integer. For instance if the oracle query results returned a value such as 190.22, we need to move the decimal two (2) places to convert to an integer value of 19022.
    Qty Multiplier The qty multiplier allows the user to specify how many base units (for ethereum, this would be wei) each integer price movement changes the value of the contract. If our integerized price was 19022 with a qty multiplier of 1, and the price moved to 19023, then the value will have change by 1 wei. If however the multiplier was set at 1,000,000,000 the price movement of 1 unit would now correspond to a value of 1 gwei (not wei)
    Expiration Time Expiration timestamp for all open positions to settle.
    Oraclize.it data source Available data sources from Oraclize.it
    Oraclize.it Query Properly structured Oraclize.it query, please use the test query page for clarification

    Explore Contracts

    MARKET Protocol's dApp provides the needed functionality to easily search, filter, and sort already deployed MARKET Smart Contracts.

    Find Contracts

    The Find Contracts screen allows for a reverse lookup for MARKET Contracts using the ethereum address of the deployed contract. Users can enter a known address, if valid, the dApp will display the current specifications of the MARKET Contract deployed to this address.

    Test Query

    Simulated Exchange

    Coming soon...

    FAQ - General

    What blockchain is used?

    MARKET Protocol has chosen to build on top of Ethereum.

    What is the token name?

    MARKET Protocol Token

    What is the token ticker symbol?

    MKT

    How can I receive updates from MARKET Protocol?

    Check out our telegram room and join our newsletter!

    What's the total supply of the token?

    600 million MKT tokens (600,000,000)

    Can extra MKT Tokens be added to the total supply?

    No, there is a fixed supply.

    Can you mine the tokens?

    No. All tokens will be minted upon main net launch.

    What wallet should I use to keep my MKT tokens?

    MKT is an ERC20 token, so a wallet that supports ERC20 tokens will be needed.

    When will the main net launch occur?

    The proposed launch date is in Q1 2019

    I don't understand how qty's work in your contracts, can you explain?

    Yes! The first thing to understand is that all numbers used in the ethereum blockchain must be integers (whole numbers) and not floating point (decimals). Therefore, all prices and qtys need to be represented on the backend as such. Each contract then defines a Qty Multplier that in turn determines exposure (and therefore collateral) per unit. To help understand this, lets go through a few examples.

    Contract 1. ETH vs DAI

    Price Cap - 31476

    Price Floor - 10492

    Price Decimal Places - 2

    Qty Multiplier - 1e16

    In the above contract, we are using the stable coin Dai which has 18 decimal places to trade the price of ETH. The contract is created in such a way, that the smallest increment price movement of 1, from say 27585 to 27586 is worth .01 of Dai, or in base units of Dai 1e+16. In other words, every penny of price movement in ETH is worth a penny in Dai.

    This contract could be created in other ways as well. For instance, maybe a contract with much larger exposure is desired, we can increase the Qty Multiplier to achieve a contract where every penny of price movement in ETH is worth 1 dollar of Dai.

    Contract 2. ETH vs DAI X 100

    Price Cap - 31476

    Price Floor - 10492

    Price Decimal Places - 2

    Qty Multiplier - 1e18

    In Contract 2, each integer price movement is equivalent to 1e+18 Dai, or a whole Dai / dollar. End users could theoretically achieve the same position in either contract by trading larger. For instance, 100 units of Contract 1 would be equal exposure to a single unit of Contract 2.

    FAQ - MARKET Protocol

    What is a derivative?

    A derivative represents a contract between a buyer and a seller. The value is derived from on an underlying asset or assets. Common derivatives use stocks, commodities, currencies, bonds, or interest rates as the underlying asset for the contract.

    Are you a decentralized exchange?

    No, MARKET is a protocol to enable the trading of decentralized derivative like contracts. Third parties will write the application layers on top of the protocol and we hope to create an API layer to facilitate this as well.

    Who will host MARKET's order books?

    Third party order book hosts, called nodes will be provided with an API that easy allows them to host an order book. Nodes, in turn may charge fees for the services they provide. These fee's are not determined by MARKET and are set directly by the node.

    Does MARKET charge a fee to use the protocol?

    MARKET doesn't charge any fees. Nodes however may set a fee for their services of hosting order books.

    How is the needed collateral for an open position calculated?

    All positions are always fully collateralized, meaning the maximum possible loss for a position is the required amount of collateral to open that position. For a buyer, the maximum possible loss is calculated as the price of the trade minus the PRICE_FLOOR times the qty transacted. Conversely, if you are opening a short position the maximum loss is calculated as PRICE_CAP minus the price of the trade, multiplied by the qty transacted. Upon filling an order both parties commit their respective maximum loss to the collateral pool.

    If I want to open a short position do I need to borrow the asset?

    No, there is no borrowing, fees to be paid, or locates to deal with for shorting. Due to the unique nature of our derivative like contracts, a trader is able to open a short position without owning the underlying asset. This is similar to how financial futures work, where a seller of the SP500 futures, doesn't need to own, locate, or borrow the SP500 in order to gain the short price exposure to the SP500.

    When is my collateral returned to me and able to be withdrawn?

    Collateral is credited to a users address and able to be withdrawn upon expiration of the contract or if the user trades out of their open position. For instance, if a trader holding a long open position, sells to close out that position prior to expiration, they will immediately be able to withdraw the collateral associated (plus or minus any profit or loss) with their trade.

    What happens if I hold an open position through contract expiration?

    Upon expiration, the contract will reach a settlement price via the agreed upon oracle solution. At this point, all funds will be able to be withdrawn for all open positions. The amount of collateral that is credited back to the user will be determined by their execution price and the settlement price of the contract. Note, that there will probably be some short delay between contract expiration and the settlement period to allow for disputes to be raised.

    When I trade out of an open position, how is my profit or loss allocated?

    When a position is closed, the appropriate amount of funds are allocated back to the user and are immediately available for withdrawal from the smart contract. If the trade that was made was profitable, more funds will be available for withdrawal than originally posted, and if the trade represented a loser for the user, less funds than originally posted would now be available for withdrawal. As an example, let us imagine a contract with a PRICE_FLOOR of 50 and a PRICE_CAP of 150 using Token A as collateral. Bob enters into a long position for a qty of 1 at a price of 85. At this point 35 units of Token A would be committed to the collateral pool (representing his max possible loss). Later, Bob exits his position by selling at a price of 95. The amount of Token A now allocated to Bob's account is 45 (35 of which is his original collateral and 10 of which represents his profit from his trade) and is now able to be withdrawn from the smart contract if Bob so wishes.

    Can a contract be created based on a different blockchain or off chain asset?

    Yes, by using oracle solutions for settlement users can create contracts for any type of real world asset such as the SP500, or cross chain asset prices like Bitcoin or Monero. This opens endless opportunities and diversification for the holders of ERC20 tokens who do not want to convert into fiat but want to gain market exposure to non digital or cross chain assets.

    Do you have a white paper available?

    Yes! Please select a language below

    How will disputes be resolved?

    This is an area of active research and discussion. We would love for community feedback to help shape the process. Our current working theory is that once a contract settlement enters into a disputed state, that a second attempt may be made to use the originally agreed upon oracle, and if that still fails to enter into a crowd sourced voting from community members that are incentivized for a fair resolution. We do anticipate that even in the best of circumstances oracle solutions will fail, or receive bad data. The problem of bad or inaccurate market data is not new or unique in the world of finance, but the need to resolve these problems when they arise in a trust-less manner will be essential.

    How do I get involved?

    We are actively looking to expand our team. For more info please send an email to info@marketprotocol.io

    FAQ - Solidity Smart Contracts

    How to debug MARKET Protocol tests?

    First option is to use console.log() to display Javascript objects and their properties on the console during test execution. This works well for simple cases, for more difficult scenarios one should set an asynchronous event watcher and expect events sent from Solidity contracts. For tests that have expectation on price or asynchronously wait for contract settlement it is also possible to manually update price using TestableMarketContractOraclize contract to verify correctness of the contract flow.

    FAQ - API

    FAQ - dApp

    Getting help

    Discord

    We work in public and our company Discord is open to all. If you have questions or need help getting started, our Discord #engineering channel is a great place to get assistance from our team of engineers and developers.

    Email

    You can also 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, and helping us improve our community.

    Please, start reading about our:

    Dive Right In

    If you're ready to start helping us to build the decentralized future right now and you just need an issue to focus on, check out this list of open issues.

    There are three main repositories that are considered as core components of the MARKET Protocol:

    Note that the README file of each one of these repositories has a helpful Getting Started section. Plus, you will find a CONTRIBUTING.md file with additional details in all of them as well.

    Remember to join our Discord Community to get in touch with our dev staff and other contributors. We will love to see you there.

    We appreciate your contribution and we hope you have lots of fun while working on MARKET Protocol!

    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 your 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 create 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
    website website
    dApp dApp
    MARKETProtocol MARKETProtocol
    MARKET.js MARKET.js

    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.

    Engineering Weekly

    Once a week, we all get together to talk about the project.

    In the Engineering Weekly meeting, the core engineering team and contributors check in to discuss the progress of the project, to call attention to particular items, to make announcements, or to seek discussion of a topic.

    Everyone is welcome! Check details here.

    And you can find the notes from previous meetings 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.