1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import { schemas } from '@0xproject/json-schemas';
import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { assert } from './assert';
import { constants } from './constants';
import { rateUtils } from './rate_utils';
export const sortingUtils = {
/**
* Takes an array of signed orders and sorts them by takerAsset/makerAsset rate in ascending order (best rate first).
* Adjusts the rate of each order according to the feeRate and takerFee for that order.
* @param signedFeeOrders An array of objects that conform to the SignedOrder interface. All orders should specify ZRX as
* the makerAsset and WETH as the takerAsset.
* @param feeRate The market rate of ZRX denominated in takerAssetAmount
* (ex. feeRate is 0.1 takerAsset/ZRX if it takes 1 unit of takerAsset to buy 10 ZRX)
* Defaults to 0
* @return The input orders sorted by rate in ascending order
*/
sortOrdersByFeeAdjustedRate(
signedOrders: SignedOrder[],
feeRate: BigNumber = constants.ZERO_AMOUNT,
): SignedOrder[] {
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
assert.isBigNumber('feeRate', feeRate);
const rateCalculator = (signedOrder: SignedOrder) => rateUtils.getFeeAdjustedRateOfOrder(signedOrder, feeRate);
const sortedOrders = sortOrders(signedOrders, rateCalculator);
return sortedOrders;
},
/**
* Takes an array of signed fee orders (makerAssetData corresponds to ZRX and takerAssetData corresponds to WETH)
* and sorts them by rate in ascending order (best rate first). Adjusts the rate according to the takerFee.
* @param signedFeeOrders An array of objects that conform to the SignedOrder interface. All orders should specify ZRX as
* the makerAsset and WETH as the takerAsset.
* @return The input orders sorted by rate in ascending order
*/
sortFeeOrdersByFeeAdjustedRate(signedFeeOrders: SignedOrder[]): SignedOrder[] {
assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema);
const rateCalculator = rateUtils.getFeeAdjustedRateOfFeeOrder;
const sortedOrders = sortOrders(signedFeeOrders, rateCalculator);
return sortedOrders;
},
};
type RateCalculator = (signedOrder: SignedOrder) => BigNumber;
// takes an array of orders, copies them, and sorts the copy based on the rate definition provided by rateCalculator
const sortOrders = (signedOrders: SignedOrder[], rateCalculator: RateCalculator): SignedOrder[] => {
const copiedOrders = _.cloneDeep(signedOrders);
const feeOrderComparator = getOrderComparator(rateCalculator);
copiedOrders.sort(feeOrderComparator);
return copiedOrders;
};
type Comparator<T> = (first: T, second: T) => number;
// takes a function that calculates rate for a signed order and returns a comparator that sorts based on rate
const getOrderComparator = (rateCalculator: RateCalculator): Comparator<SignedOrder> => (
firstSignedOrder,
secondSignedOrder,
) => {
const firstOrderRate = rateCalculator(firstSignedOrder);
const secondOrderRate = rateCalculator(secondSignedOrder);
if (firstOrderRate.lt(secondOrderRate)) {
return -1;
} else if (firstOrderRate.gt(secondOrderRate)) {
return 1;
} else {
return 0;
}
};
|