Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch Order Matching #41

Closed
hysz opened this issue May 4, 2019 · 0 comments
Closed

Batch Order Matching #41

hysz opened this issue May 4, 2019 · 0 comments
Labels
status: implemented Proposed changes have been implemented (and deployed, if smart contract) type: core

Comments

@hysz
Copy link
Contributor

hysz commented May 4, 2019

Summary

We propose a new feature set that allows multiple orders to be matched with one or more complementary orders. This would extend the exchange contract with batch functions for each matching strategy (see ZEIP 40).

Motivation

This enables more efficient order matching when orders are not maximally filled with a single call to matchOrders or matchOrdersWithMaximalFill. One use case is market fills on matching relayers, where a single taker order is matched against one or more maker orders:

  1. A taker wants to fill one or more maker orders
  2. They submit to the relayer a single complementary taker order
  3. The relayer calls the exchange contract with the respective maker orders and complementary taker order

Specification

Interface

Below are the interfaces for the proposed batch matching functions.

/// @dev Match complementary orders that have a profitable spread.
///      Each order is filled at their respective price point, and
///      the matcher receives a profit denominated in the left maker asset.
/// @param leftOrders Set of orders with the same maker / taker asset.
/// @param rightOrders Set of orders to match against `leftOrders`
/// @param leftSignatures Proof that left orders were created by the left makers.
/// @param rightSignatures Proof that right orders were created by the right makers.
/// @return batchMatchedFillResults Amounts filled and profit generated.
function batchMatchOrders(
    LibOrder.Order[] memory leftOrders,
    LibOrder.Order[] memory rightOrders,
    bytes[] memory leftSignatures,
    bytes[] memory rightSignatures
)
public
nonReentrant
returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults);

/// @dev Match complementary orders that have a profitable spread.
///      Each order is maximally filled at their respective price point, and
///      the matcher receives a profit denominated in either the left maker asset,
///      right maker asset, or a combination of both. 
/// @param leftOrders Set of orders with the same maker / taker asset.
/// @param rightOrders Set of orders to match against `leftOrders`
/// @param leftSignatures Proof that left orders were created by the left makers.
/// @param rightSignatures Proof that right orders were created by the right makers.
/// @return batchMatchedFillResults Amounts filled and profit generated.
function batchMatchOrdersWithMaximalFill(
    LibOrder.Order[] memory leftOrders,
    LibOrder.Order[] memory rightOrders,
    bytes[] memory leftSignatures,
    bytes[] memory rightSignatures
)
public
nonReentrant
returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults);

Fill Results

The LibFillResults contract would be extended to include a results struct for batch matching. One FillResult is created for each order that is filled. The total profit denominated in the left and right maker assets is also included.

contract LibFillResults {
    ...
    struct BatchMatchedFillResults {
        FillResults[] left;              // Fill results for left orders
        FillResults[] right;             // Fill results for right orders
        uint256 profitInLeftMakerAsset;  // Profit taken from left makers
        uint256 profitInRightMakerAsset; // Profit taken from right makers
    }
}

Implementation

The pseudocode below describes the implementation of each batch fill function.

// sanity checks
require(leftOrders.length > 0)
require(leftOrders.length == leftSignatures.length)
require(rightOrders.length > 0)
require(rightOrders.length == rightSignatures.length)

// init
leftIdx = 0
rightIdx = 0
leftOrder = leftOrders[0]
rightOrder = rightOrders[0]
leftSignature = leftSignatures[0]
rightSignature = rightSignatures[0]

// batch match
batchMatchResults = {}
while True:
    // perform match
    matchResult = match(leftOrder, rightOrder, leftSignature, rightSignature)
    batchMatchResults.left.append(matchResult.left)
    batchMatchResults.right.append(matchResult.right)
    batchMatchResults.profitInLeftMakerAsset += matchResult.profitInLeftMakerAsset
    batchMatchResults.profitInRightMakerAsset += matchResult.profitInRightMakerAsset

    // iterate left
    if isFilled(leftOrder):
      leftIdx += 1
      if leftIdx == leftOrders.length:
        // all left orders have been matched
        break
      leftOrder = leftOrders[leftIdx]
      leftSignature = leftSignatures[leftIdx]

    // iterate right
    if isFilled(rightOrder):
      rightIdx += 1
      if rightIdx == rightOrders.length:
        // all right orders have been matched
        break
      rightOrder = rightOrders[rightIdx]
      rightSignature = rightSignatures[rightIdx]

return batchMatchResults

Notes

@dekz dekz added the 3.0 label May 6, 2019
@dekz dekz changed the title [3.0] Batch Order Matching Batch Order Matching May 6, 2019
@dekz dekz mentioned this issue Oct 21, 2019
@hysz hysz mentioned this issue Oct 29, 2019
@mintcloud mintcloud added status: implemented Proposed changes have been implemented (and deployed, if smart contract) type: core and removed 3.0 labels Apr 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: implemented Proposed changes have been implemented (and deployed, if smart contract) type: core
Projects
None yet
Development

No branches or pull requests

3 participants