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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
import { sortingUtils } from '@0xproject/order-utils';
import { SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import { ForwarderHelperImplConfig } from '../forwarder_helper_impl';
interface SignedOrderWithAmount extends SignedOrder {
remainingFillAmount: BigNumber;
}
export const forwarderHelperImplConfigUtils = {
sortedConfig(config: ForwarderHelperImplConfig): ForwarderHelperImplConfig {
const { orders, feeOrders, remainingFillableMakerAssetAmounts, remainingFillableFeeAmounts } = config;
// TODO: provide a feeRate to the sorting function to more accurately sort based on the current market for ZRX tokens
const orderSorter = (ordersToSort: SignedOrder[]) => {
return sortingUtils.sortOrdersByFeeAdjustedRate(ordersToSort);
};
const sortOrdersResult = sortOrdersAndRemainingFillAmounts(
orderSorter,
orders,
remainingFillableMakerAssetAmounts,
);
const feeOrderSorter = (ordersToSort: SignedOrder[]) => {
return sortingUtils.sortFeeOrdersByFeeAdjustedRate(ordersToSort);
};
const sortFeeOrdersResult = sortOrdersAndRemainingFillAmounts(
feeOrderSorter,
feeOrders,
remainingFillableFeeAmounts,
);
return {
orders: sortOrdersResult.orders,
feeOrders: sortFeeOrdersResult.orders,
remainingFillableMakerAssetAmounts: sortOrdersResult.remainingFillAmounts,
remainingFillableFeeAmounts: sortFeeOrdersResult.remainingFillAmounts,
};
},
};
type OrderSorter = (orders: SignedOrder[]) => SignedOrder[];
function sortOrdersAndRemainingFillAmounts(
orderSorter: OrderSorter,
orders: SignedOrder[],
remainingFillAmounts?: BigNumber[],
): { orders: SignedOrder[]; remainingFillAmounts?: BigNumber[] } {
if (!_.isUndefined(remainingFillAmounts)) {
// Bundle orders together with their remainingFillAmounts so that we can sort them together
const orderWithAmounts = bundleSignedOrderWithAmounts(orders, remainingFillAmounts);
// Sort
const sortedOrderWithAmounts = orderSorter(orderWithAmounts) as SignedOrderWithAmount[];
// Unbundle after sorting
const unbundledSortedOrderWithAmounts = unbundleSignedOrderWithAmounts(sortedOrderWithAmounts);
return {
orders: unbundledSortedOrderWithAmounts.orders,
remainingFillAmounts: unbundledSortedOrderWithAmounts.amounts,
};
} else {
const sortedOrders = orderSorter(orders);
return {
orders: sortedOrders,
};
}
}
function bundleSignedOrderWithAmounts(orders: SignedOrder[], amounts: BigNumber[]): SignedOrderWithAmount[] {
const ordersAndAmounts = _.map(orders, (order, index) => {
return {
...order,
remainingFillAmount: amounts[index],
};
});
return ordersAndAmounts;
}
function unbundleSignedOrderWithAmounts(
signedOrderWithAmounts: SignedOrderWithAmount[],
): { orders: SignedOrder[]; amounts: BigNumber[] } {
const orders = _.map(signedOrderWithAmounts, order => {
const { remainingFillAmount, ...rest } = order;
return rest;
});
const amounts = _.map(signedOrderWithAmounts, order => {
const { remainingFillAmount } = order;
return remainingFillAmount;
});
return {
orders,
amounts,
};
}
|