From cd25d38118de90f8282dc8e5e2b4ffb02fde9990 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 8 Jun 2017 17:28:09 +0200 Subject: Implement fillOrderUpToAsync --- src/contract_wrappers/exchange_wrapper.ts | 66 +++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'src/contract_wrappers') diff --git a/src/contract_wrappers/exchange_wrapper.ts b/src/contract_wrappers/exchange_wrapper.ts index 72ae0d07e..524ebdc0f 100644 --- a/src/contract_wrappers/exchange_wrapper.ts +++ b/src/contract_wrappers/exchange_wrapper.ts @@ -175,6 +175,72 @@ export class ExchangeWrapper extends ContractWrapper { ); this.throwErrorLogsAsErrors(response.logs); } + /** + * Sequentially and atomically fills signedOrders up to takerTokenFillAmount. + * If fill amount is reached - it succeeds and doesn't fill the rest of the orders. + * If fill amount is not reached - it just fills all the orders. + */ + public async fillOrderUpToAsync(signedOrders: SignedOrder[], takerTokenFillAmount: BigNumber.BigNumber, + shouldCheckTransfer: boolean, takerAddress: string): Promise { + const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress); + assert.assert(_.uniq(takerTokenAddresses).length === 1, + ExchangeContractErrs.MULTIPLE_TAKER_TOKENS_IN_FILL_UP_TO); + assert.isBigNumber('takerTokenFillAmount', takerTokenFillAmount); + assert.isBoolean('shouldCheckTransfer', shouldCheckTransfer); + await assert.isSenderAddressAsync('takerAddress', takerAddress, this.web3Wrapper); + _.forEach(signedOrders, + async (signedOrder: SignedOrder, i: number) => { + assert.doesConformToSchema(`signedOrder[${i}]`, + SchemaValidator.convertToJSONSchemaCompatibleObject(signedOrder as object), + signedOrderSchema); + await this.validateFillOrderAndThrowIfInvalidAsync( + signedOrder, takerTokenFillAmount, takerAddress); + }); + if (_.isEmpty(signedOrders)) { + return; // no-op + } + + const orderAddressesValuesAndSignatureArray = _.map(signedOrders, signedOrder => { + return [ + ...ExchangeWrapper.getOrderAddressesAndValues(signedOrder), + signedOrder.ecSignature.v, + signedOrder.ecSignature.r, + signedOrder.ecSignature.s, + ]; + }); + // We use _.unzip because _.unzip doesn't type check if values have different types :'( + const [orderAddressesArray, orderValuesArray, vArray, rArray, sArray] = _.unzip( + orderAddressesValuesAndSignatureArray, + ); + + const exchangeInstance = await this.getExchangeContractAsync(); + const gas = await exchangeInstance.fillUpTo.estimateGas( + orderAddressesArray, + orderValuesArray, + takerTokenFillAmount, + shouldCheckTransfer, + vArray, + rArray, + sArray, + { + from: takerAddress, + }, + ); + const response: ContractResponse = await exchangeInstance.fillUpTo( + orderAddressesArray, + orderValuesArray, + takerTokenFillAmount, + shouldCheckTransfer, + vArray, + rArray, + sArray, + { + from: takerAddress, + gas, + }, + ); + this.throwErrorLogsAsErrors(response.logs); + } /** * Batch version of fillOrderAsync. * Executes multiple fills atomically in a single transaction. -- cgit v1.2.3