diff options
author | Brandon Millman <brandon.millman@gmail.com> | 2018-08-03 01:55:09 +0800 |
---|---|---|
committer | Brandon Millman <brandon.millman@gmail.com> | 2018-08-06 06:33:52 +0800 |
commit | a016747c36e0bc2c182e3d2b565ca63fb95e2b1b (patch) | |
tree | ada26e57de97e2628ed6bd7431a241a7d74d048f | |
parent | 1c06380ef50ae401670d5de74ef2e32f972177ca (diff) | |
download | dexon-0x-contracts-a016747c36e0bc2c182e3d2b565ca63fb95e2b1b.tar.gz dexon-0x-contracts-a016747c36e0bc2c182e3d2b565ca63fb95e2b1b.tar.zst dexon-0x-contracts-a016747c36e0bc2c182e3d2b565ca63fb95e2b1b.zip |
Add findFeeOrdersThatCoverFeesForTargetOrders to ForwarderWrapper
-rw-r--r-- | packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts | 65 |
1 files changed, 60 insertions, 5 deletions
diff --git a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts index 5e879b3a8..c0961b3a3 100644 --- a/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts +++ b/packages/contract-wrappers/src/contract_wrappers/forwarder_wrapper.ts @@ -27,7 +27,7 @@ export class ForwarderWrapper extends ContractWrapper { /** * Takes an array of orders and returns a subset of those orders that has enough makerAssetAmount (taking into account on-chain balances, * allowances, and partial fills) in order to fill the input makerAssetFillAmount plus slippageBufferAmount. Iterates from first order to last. - * Sort the input by rate in order to get the subset of orders that will cost the least ETH. + * Sort the input by ascending rate in order to get the subset of orders that will cost the least ETH. * @param signedOrders An array of objects that conform to the SignedOrder interface. All orders should specify the same makerAsset. * All orders should specify WETH as the takerAsset. * @param orderStates An array of objects corresponding to the signedOrders parameter that each contain on-chain state @@ -46,20 +46,20 @@ export class ForwarderWrapper extends ContractWrapper { assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); assert.isBigNumber('makerAssetFillAmount', makerAssetFillAmount); assert.isBigNumber('slippageBufferAmount', slippageBufferAmount); - // calculate total amount of makerAsset needed to fill + // calculate total amount of makerAsset needed to be filled const totalFillAmount = makerAssetFillAmount.plus(slippageBufferAmount); // iterate through the signedOrders input from left to right until we have enough makerAsset to fill totalFillAmount const result = _.reduce( signedOrders, ({ resultOrders, remainingFillAmount }, order, index) => { if (remainingFillAmount.lessThanOrEqualTo(constants.ZERO_AMOUNT)) { - return { resultOrders, remainingFillAmount }; + return { resultOrders, remainingFillAmount: constants.ZERO_AMOUNT }; } else { const orderState = orderStates[index]; - const orderRemainingFillableMakerAssetAmount = orderState.remainingFillableMakerAssetAmount; + const makerAssetAmountAvailable = ForwarderWrapper._getMakerAssetAmountAvailable(orderState); return { resultOrders: _.concat(resultOrders, order), - remainingFillAmount: remainingFillAmount.minus(orderState.remainingFillableMakerAssetAmount), + remainingFillAmount: remainingFillAmount.minus(makerAssetAmountAvailable), }; } }, @@ -67,6 +67,61 @@ export class ForwarderWrapper extends ContractWrapper { ); return result; } + /** + * Takes an array of orders and an array of feeOrders. Returns a subset of the feeOrders that has enough ZRX (taking into account + * on-chain balances, allowances, and partial fills) in order to fill the takerFees required by signedOrders plus a + * slippageBufferAmount. Iterates from first feeOrder to last. Sort the feeOrders by ascending rate in order to get the subset of + * feeOrders that will cost the least ETH. + * @param signedOrders An array of objects that conform to the SignedOrder interface. All orders should specify ZRX as + * the makerAsset and WETH as the takerAsset. + * @param orderStates An array of objects corresponding to the signedOrders parameter that each contain on-chain state + * relevant to 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 feeOrderStates An array of objects corresponding to the signedOrders parameter that each contain on-chain state + * relevant to that order. + * @param makerAssetFillAmount The amount of makerAsset desired to be filled. + * @param slippageBufferAmount An additional amount makerAsset to be covered by the result in case of trade collisions or partial fills. + * @return Resulting orders and remaining fill amount that could not be covered by the input. + */ + public static findFeeOrdersThatCoverFeesForTargetOrders( + signedOrders: SignedOrder[], + orderStates: OrderRelevantState[], + signedFeeOrders: SignedOrder[], + feeOrderStates: OrderRelevantState[], + slippageBufferAmount: BigNumber = constants.ZERO_AMOUNT, + ): { resultOrders: SignedOrder[]; remainingFillAmount: BigNumber } { + // type assertions + assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema); + assert.doesConformToSchema('signedFeeOrders', signedFeeOrders, schemas.signedOrdersSchema); + assert.isBigNumber('slippageBufferAmount', slippageBufferAmount); + // calculate total amount of ZRX needed to fill signedOrders + const totalFeeAmount = _.reduce( + signedOrders, + (accFees, order, index) => { + const orderState = orderStates[index]; + const makerAssetAmountAvailable = ForwarderWrapper._getMakerAssetAmountAvailable(orderState); + const feeToFillMakerAssetAmountAvailable = makerAssetAmountAvailable + .div(order.makerAssetAmount) + .mul(order.takerFee); + return feeToFillMakerAssetAmountAvailable; + }, + constants.ZERO_AMOUNT, + ); + return ForwarderWrapper.findOrdersThatCoverMakerAssetFillAmount( + signedFeeOrders, + feeOrderStates, + totalFeeAmount, + slippageBufferAmount, + ); + } + private static _getMakerAssetAmountAvailable(orderState: OrderRelevantState): BigNumber { + return BigNumber.min( + orderState.makerBalance, + orderState.remainingFillableMakerAssetAmount, + orderState.makerProxyAllowance, + ); + } constructor( web3Wrapper: Web3Wrapper, networkId: number, |