diff options
author | Leonid Logvinov <logvinov.leon@gmail.com> | 2017-11-23 05:43:17 +0800 |
---|---|---|
committer | Leonid Logvinov <logvinov.leon@gmail.com> | 2017-11-24 05:13:37 +0800 |
commit | db2917b01caa49d74c9ebcae2d36e9c3946b94d8 (patch) | |
tree | 88aa341cb4dc02f1bfbc7d0d00d21966e1bbde20 /packages/0x.js | |
parent | 87d34f9c7f3ccf22e01798c27c4a4d5d4f943816 (diff) | |
download | dexon-sol-tools-db2917b01caa49d74c9ebcae2d36e9c3946b94d8.tar.gz dexon-sol-tools-db2917b01caa49d74c9ebcae2d36e9c3946b94d8.tar.zst dexon-sol-tools-db2917b01caa49d74c9ebcae2d36e9c3946b94d8.zip |
Enable some new linter rules and fix the issues
Diffstat (limited to 'packages/0x.js')
11 files changed, 162 insertions, 159 deletions
diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index 97ea54362..b35219b24 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -559,7 +559,7 @@ export class ExchangeWrapper extends ContractWrapper { if (shouldValidate) { const orderHash = utils.getOrderHashHex(order); const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - this._orderValidationUtils.validateCancelOrderThrowIfInvalid( + OrderValidationUtils.validateCancelOrderThrowIfInvalid( order, cancelTakerTokenAmount, unavailableTakerTokenAmount); } @@ -613,7 +613,7 @@ export class ExchangeWrapper extends ContractWrapper { for (const orderCancellationRequest of orderCancellationRequests) { const orderHash = utils.getOrderHashHex(orderCancellationRequest.order); const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - this._orderValidationUtils.validateCancelOrderThrowIfInvalid( + OrderValidationUtils.validateCancelOrderThrowIfInvalid( orderCancellationRequest.order, orderCancellationRequest.takerTokenCancelAmount, unavailableTakerTokenAmount, ); @@ -767,7 +767,7 @@ export class ExchangeWrapper extends ContractWrapper { assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount); const orderHash = utils.getOrderHashHex(order); const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash); - this._orderValidationUtils.validateCancelOrderThrowIfInvalid( + OrderValidationUtils.validateCancelOrderThrowIfInvalid( order, cancelTakerTokenAmount, unavailableTakerTokenAmount); } /** @@ -884,4 +884,4 @@ export class ExchangeWrapper extends ContractWrapper { const tokenTransferProxyAddressLowerCase = tokenTransferProxyAddress.toLowerCase(); return tokenTransferProxyAddressLowerCase; } -} +} // tslint:disable:max-file-line-count diff --git a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts index 60fe7f33a..468e58350 100644 --- a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts @@ -14,6 +14,18 @@ import {ContractWrapper} from './contract_wrapper'; export class TokenRegistryWrapper extends ContractWrapper { private _tokenRegistryContractIfExists?: TokenRegistryContract; private _contractAddressIfExists?: string; + private static _createTokenFromMetadata(metadata: TokenMetadata): Token|undefined { + if (metadata[0] === constants.NULL_ADDRESS) { + return undefined; + } + const token = { + address: metadata[0], + name: metadata[1], + symbol: metadata[2], + decimals: metadata[3].toNumber(), + }; + return token; + } constructor(web3Wrapper: Web3Wrapper, contractAddressIfExists?: string) { super(web3Wrapper); this._contractAddressIfExists = contractAddressIfExists; @@ -51,7 +63,7 @@ export class TokenRegistryWrapper extends ContractWrapper { const tokenRegistryContract = await this._getTokenRegistryContractAsync(); const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address); - const token = this._createTokenFromMetadata(metadata); + const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); return token; } public async getTokenAddressBySymbolIfExistsAsync(symbol: string): Promise<string|undefined> { @@ -76,14 +88,14 @@ export class TokenRegistryWrapper extends ContractWrapper { assert.isString('symbol', symbol); const tokenRegistryContract = await this._getTokenRegistryContractAsync(); const metadata = await tokenRegistryContract.getTokenBySymbol.callAsync(symbol); - const token = this._createTokenFromMetadata(metadata); + const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); return token; } public async getTokenByNameIfExistsAsync(name: string): Promise<Token|undefined> { assert.isString('name', name); const tokenRegistryContract = await this._getTokenRegistryContractAsync(); const metadata = await tokenRegistryContract.getTokenByName.callAsync(name); - const token = this._createTokenFromMetadata(metadata); + const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); return token; } /** @@ -103,18 +115,6 @@ export class TokenRegistryWrapper extends ContractWrapper { return this._contractAddressIfExists; } } - private _createTokenFromMetadata(metadata: TokenMetadata): Token|undefined { - if (metadata[0] === constants.NULL_ADDRESS) { - return undefined; - } - const token = { - address: metadata[0], - name: metadata[1], - symbol: metadata[2], - decimals: metadata[3].toNumber(), - }; - return token; - } private _invalidateContractInstance(): void { delete this._tokenRegistryContractIfExists; } diff --git a/packages/0x.js/src/order_watcher/order_state_watcher.ts b/packages/0x.js/src/order_watcher/order_state_watcher.ts index 4d57935a1..919a58df7 100644 --- a/packages/0x.js/src/order_watcher/order_state_watcher.ts +++ b/packages/0x.js/src/order_watcher/order_state_watcher.ts @@ -38,7 +38,7 @@ import {ExpirationWatcher} from './expiration_watcher'; interface DependentOrderHashes { [makerAddress: string]: { - [makerToken: string]: Set<string>, + [makerToken: string]: Set<string>; }; } diff --git a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts index 293f75db9..afc40b86d 100644 --- a/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts +++ b/packages/0x.js/src/stores/balance_proxy_allowance_lazy_store.ts @@ -12,13 +12,13 @@ export class BalanceAndProxyAllowanceLazyStore { private token: TokenWrapper; private balance: { [tokenAddress: string]: { - [userAddress: string]: BigNumber, - }, + [userAddress: string]: BigNumber; + }; }; private proxyAllowance: { [tokenAddress: string]: { - [userAddress: string]: BigNumber, - }, + [userAddress: string]: BigNumber; + }; }; constructor(token: TokenWrapper) { this.token = token; diff --git a/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts b/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts index 59c1bb7a7..28b32f9e2 100644 --- a/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts +++ b/packages/0x.js/src/stores/order_filled_cancelled_lazy_store.ts @@ -11,10 +11,10 @@ import {BlockParamLiteral} from '../types'; export class OrderFilledCancelledLazyStore { private exchange: ExchangeWrapper; private filledTakerAmount: { - [orderHash: string]: BigNumber, + [orderHash: string]: BigNumber; }; private cancelledTakerAmount: { - [orderHash: string]: BigNumber, + [orderHash: string]: BigNumber; }; constructor(exchange: ExchangeWrapper) { this.exchange = exchange; diff --git a/packages/0x.js/src/subproviders/empty_wallet_subprovider.ts b/packages/0x.js/src/subproviders/empty_wallet_subprovider.ts index 2f260217c..d707d5652 100644 --- a/packages/0x.js/src/subproviders/empty_wallet_subprovider.ts +++ b/packages/0x.js/src/subproviders/empty_wallet_subprovider.ts @@ -6,6 +6,7 @@ import {JSONRPCPayload} from '../types'; * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js */ export class EmptyWalletSubProvider { + // tslint:disable-next-line:prefer-function-over-method public handleRequest(payload: JSONRPCPayload, next: () => void, end: (err: Error|null, result: any) => void) { switch (payload.method) { case 'eth_accounts': @@ -18,6 +19,7 @@ export class EmptyWalletSubProvider { } } // Required to implement this method despite not needing it for this subprovider + // tslint:disable-next-line:prefer-function-over-method public setEngine(engine: any) { // noop } diff --git a/packages/0x.js/src/utils/abi_decoder.ts b/packages/0x.js/src/utils/abi_decoder.ts index f027026da..f26b057f0 100644 --- a/packages/0x.js/src/utils/abi_decoder.ts +++ b/packages/0x.js/src/utils/abi_decoder.ts @@ -8,6 +8,15 @@ import {AbiType, ContractEventArgs, DecodedLogArgs, LogWithDecodedArgs, RawLog, export class AbiDecoder { private savedABIs: Web3.AbiDefinition[] = []; private methodIds: {[signatureHash: string]: Web3.EventAbi} = {}; + private static padZeros(address: string) { + let formatted = address; + if (_.startsWith(formatted, '0x')) { + formatted = formatted.slice(2); + } + + formatted = _.padStart(formatted, 40, '0'); + return `0x${formatted}`; + } constructor(abiArrays: Web3.AbiDefinition[][]) { _.map(abiArrays, this.addABI.bind(this)); } @@ -32,7 +41,7 @@ export class AbiDecoder { // Indexed parameters are stored in topics. Non-indexed ones in decodedData let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++]; if (param.type === SolidityTypes.Address) { - value = this.padZeros(new BigNumber(value).toString(16)); + value = AbiDecoder.padZeros(new BigNumber(value).toString(16)); } else if (param.type === SolidityTypes.Uint256 || param.type === SolidityTypes.Uint8 || param.type === SolidityTypes.Uint) { @@ -57,13 +66,4 @@ export class AbiDecoder { }); this.savedABIs = this.savedABIs.concat(abiArray); } - private padZeros(address: string) { - let formatted = address; - if (_.startsWith(formatted, '0x')) { - formatted = formatted.slice(2); - } - - formatted = _.padStart(formatted, 40, '0'); - return `0x${formatted}`; - } } diff --git a/packages/0x.js/src/utils/exchange_transfer_simulator.ts b/packages/0x.js/src/utils/exchange_transfer_simulator.ts index c3a2d1585..00a0efd3f 100644 --- a/packages/0x.js/src/utils/exchange_transfer_simulator.ts +++ b/packages/0x.js/src/utils/exchange_transfer_simulator.ts @@ -36,6 +36,11 @@ const ERR_MSG_MAPPING = { export class ExchangeTransferSimulator { private store: BalanceAndProxyAllowanceLazyStore; private UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber; + private static throwValidationError(failureReason: FailureReason, tradeSide: TradeSide, + transferType: TransferType): never { + const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType]; + throw new Error(errMsg); + } constructor(token: TokenWrapper) { this.store = new BalanceAndProxyAllowanceLazyStore(token); this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS = token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; @@ -55,10 +60,10 @@ export class ExchangeTransferSimulator { const balance = await this.store.getBalanceAsync(tokenAddress, from); const proxyAllowance = await this.store.getProxyAllowanceAsync(tokenAddress, from); if (proxyAllowance.lessThan(amountInBaseUnits)) { - this.throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType); + ExchangeTransferSimulator.throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType); } if (balance.lessThan(amountInBaseUnits)) { - this.throwValidationError(FailureReason.Balance, tradeSide, transferType); + ExchangeTransferSimulator.throwValidationError(FailureReason.Balance, tradeSide, transferType); } await this.decreaseProxyAllowanceAsync(tokenAddress, from, amountInBaseUnits); await this.decreaseBalanceAsync(tokenAddress, from, amountInBaseUnits); @@ -81,9 +86,4 @@ export class ExchangeTransferSimulator { const balance = await this.store.getBalanceAsync(tokenAddress, userAddress); this.store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits)); } - private throwValidationError(failureReason: FailureReason, tradeSide: TradeSide, - transferType: TransferType): never { - const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType]; - throw new Error(errMsg); - } } diff --git a/packages/0x.js/src/utils/order_state_utils.ts b/packages/0x.js/src/utils/order_state_utils.ts index 6654b9ae1..7dee89914 100644 --- a/packages/0x.js/src/utils/order_state_utils.ts +++ b/packages/0x.js/src/utils/order_state_utils.ts @@ -25,6 +25,39 @@ const ACCEPTABLE_RELATIVE_ROUNDING_ERROR = 0.0001; export class OrderStateUtils { private balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore; private orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore; + private static validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void { + const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add( + orderRelevantState.filledTakerTokenAmount, + ); + const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); + if (availableTakerTokenAmount.eq(0)) { + throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); + } + + if (orderRelevantState.makerBalance.eq(0)) { + throw new Error(ExchangeContractErrs.InsufficientMakerBalance); + } + if (orderRelevantState.makerProxyAllowance.eq(0)) { + throw new Error(ExchangeContractErrs.InsufficientMakerAllowance); + } + if (!signedOrder.makerFee.eq(0)) { + if (orderRelevantState.makerFeeBalance.eq(0)) { + throw new Error(ExchangeContractErrs.InsufficientMakerFeeBalance); + } + if (orderRelevantState.makerFeeProxyAllowance.eq(0)) { + throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance); + } + } + const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount + .dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR) + .dividedBy(signedOrder.makerTokenAmount); + if (orderRelevantState.remainingFillableTakerTokenAmount + .lessThan(minFillableTakerTokenAmountWithinNoRoundingErrorRange)) { + throw new Error(ExchangeContractErrs.OrderFillRoundingError); + } + // TODO Add linear function solver when maker token is ZRX #badass + // Return the max amount that's fillable + } constructor(balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore, orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore) { this.balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore; @@ -34,7 +67,7 @@ export class OrderStateUtils { const orderRelevantState = await this.getOrderRelevantStateAsync(signedOrder); const orderHash = ZeroEx.getOrderHashHex(signedOrder); try { - this.validateIfOrderIsValid(signedOrder, orderRelevantState); + OrderStateUtils.validateIfOrderIsValid(signedOrder, orderRelevantState); const orderState: OrderStateValid = { isValid: true, orderHash, @@ -103,37 +136,4 @@ export class OrderStateUtils { }; return orderRelevantState; } - private validateIfOrderIsValid(signedOrder: SignedOrder, orderRelevantState: OrderRelevantState): void { - const unavailableTakerTokenAmount = orderRelevantState.cancelledTakerTokenAmount.add( - orderRelevantState.filledTakerTokenAmount, - ); - const availableTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); - if (availableTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); - } - - if (orderRelevantState.makerBalance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerBalance); - } - if (orderRelevantState.makerProxyAllowance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerAllowance); - } - if (!signedOrder.makerFee.eq(0)) { - if (orderRelevantState.makerFeeBalance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerFeeBalance); - } - if (orderRelevantState.makerFeeProxyAllowance.eq(0)) { - throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance); - } - } - const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount - .dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR) - .dividedBy(signedOrder.makerTokenAmount); - if (orderRelevantState.remainingFillableTakerTokenAmount - .lessThan(minFillableTakerTokenAmountWithinNoRoundingErrorRange)) { - throw new Error(ExchangeContractErrs.OrderFillRoundingError); - } - // TODO Add linear function solver when maker token is ZRX #badass - // Return the max amount that's fillable - } } diff --git a/packages/0x.js/src/utils/order_validation_utils.ts b/packages/0x.js/src/utils/order_validation_utils.ts index 06cfca7bd..d514483e0 100644 --- a/packages/0x.js/src/utils/order_validation_utils.ts +++ b/packages/0x.js/src/utils/order_validation_utils.ts @@ -13,6 +13,77 @@ import {ExchangeTransferSimulator} from './exchange_transfer_simulator'; export class OrderValidationUtils { private tokenWrapper: TokenWrapper; private exchangeWrapper: ExchangeWrapper; + public static validateCancelOrderThrowIfInvalid( + order: Order, cancelTakerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber, + ): void { + if (cancelTakerTokenAmount.eq(0)) { + throw new Error(ExchangeContractErrs.OrderCancelAmountZero); + } + if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) { + throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled); + } + const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); + if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { + throw new Error(ExchangeContractErrs.OrderCancelExpired); + } + } + public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, + fillTakerTokenAmount: BigNumber, senderAddress: string, zrxTokenAddress: string, + ): Promise<void> { + const fillMakerTokenAmount = OrderValidationUtils.getPartialAmount( + fillTakerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerTokenAmount, + ); + await exchangeTradeEmulator.transferFromAsync( + signedOrder.makerTokenAddress, signedOrder.maker, senderAddress, fillMakerTokenAmount, + TradeSide.Maker, TransferType.Trade, + ); + await exchangeTradeEmulator.transferFromAsync( + signedOrder.takerTokenAddress, senderAddress, signedOrder.maker, fillTakerTokenAmount, + TradeSide.Taker, TransferType.Trade, + ); + const makerFeeAmount = OrderValidationUtils.getPartialAmount( + fillTakerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.makerFee, + ); + await exchangeTradeEmulator.transferFromAsync( + zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount, TradeSide.Maker, + TransferType.Fee, + ); + const takerFeeAmount = OrderValidationUtils.getPartialAmount( + fillTakerTokenAmount, + signedOrder.takerTokenAmount, + signedOrder.takerFee, + ); + await exchangeTradeEmulator.transferFromAsync( + zrxTokenAddress, senderAddress, signedOrder.feeRecipient, takerFeeAmount, TradeSide.Taker, + TransferType.Fee, + ); + } + private static validateRemainingFillAmountNotZeroOrThrow( + takerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber, + ) { + if (takerTokenAmount.eq(unavailableTakerTokenAmount)) { + throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); + } + } + private static validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) { + const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); + if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { + throw new Error(ExchangeContractErrs.OrderFillExpired); + } + } + private static getPartialAmount(numerator: BigNumber, denominator: BigNumber, + target: BigNumber): BigNumber { + const fillMakerTokenAmount = numerator + .mul(target) + .div(denominator) + .round(0); + return fillMakerTokenAmount; + } constructor(tokenWrapper: TokenWrapper, exchangeWrapper: ExchangeWrapper) { this.tokenWrapper = tokenWrapper; this.exchangeWrapper = exchangeWrapper; @@ -22,15 +93,15 @@ export class OrderValidationUtils { expectedFillTakerTokenAmount?: BigNumber): Promise<void> { const orderHash = utils.getOrderHashHex(signedOrder); const unavailableTakerTokenAmount = await this.exchangeWrapper.getUnavailableTakerAmountAsync(orderHash); - this.validateRemainingFillAmountNotZeroOrThrow( + OrderValidationUtils.validateRemainingFillAmountNotZeroOrThrow( signedOrder.takerTokenAmount, unavailableTakerTokenAmount, ); - this.validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); + OrderValidationUtils.validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); if (!_.isUndefined(expectedFillTakerTokenAmount)) { fillTakerTokenAmount = expectedFillTakerTokenAmount; } - const fillMakerTokenAmount = this.getPartialAmount( + const fillMakerTokenAmount = OrderValidationUtils.getPartialAmount( fillTakerTokenAmount, signedOrder.takerTokenAmount, signedOrder.makerTokenAmount, @@ -39,7 +110,7 @@ export class OrderValidationUtils { signedOrder.makerTokenAddress, signedOrder.maker, signedOrder.taker, fillMakerTokenAmount, TradeSide.Maker, TransferType.Trade, ); - const makerFeeAmount = this.getPartialAmount( + const makerFeeAmount = OrderValidationUtils.getPartialAmount( fillTakerTokenAmount, signedOrder.takerTokenAmount, signedOrder.makerFee, @@ -61,18 +132,18 @@ export class OrderValidationUtils { throw new Error(ZeroExError.InvalidSignature); } const unavailableTakerTokenAmount = await this.exchangeWrapper.getUnavailableTakerAmountAsync(orderHash); - this.validateRemainingFillAmountNotZeroOrThrow( + OrderValidationUtils.validateRemainingFillAmountNotZeroOrThrow( signedOrder.takerTokenAmount, unavailableTakerTokenAmount, ); if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) { throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker); } - this.validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); + OrderValidationUtils.validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec); const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount); const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount) ? remainingTakerTokenAmount : fillTakerTokenAmount; - await this.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, filledTakerTokenAmount, takerAddress, zrxTokenAddress, ); @@ -94,74 +165,4 @@ export class OrderValidationUtils { throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount); } } - public validateCancelOrderThrowIfInvalid( - order: Order, cancelTakerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber, - ): void { - if (cancelTakerTokenAmount.eq(0)) { - throw new Error(ExchangeContractErrs.OrderCancelAmountZero); - } - if (order.takerTokenAmount.eq(unavailableTakerTokenAmount)) { - throw new Error(ExchangeContractErrs.OrderAlreadyCancelledOrFilled); - } - const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); - if (order.expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { - throw new Error(ExchangeContractErrs.OrderCancelExpired); - } - } - public async validateFillOrderBalancesAllowancesThrowIfInvalidAsync( - exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, - fillTakerTokenAmount: BigNumber, senderAddress: string, zrxTokenAddress: string): Promise<void> { - const fillMakerTokenAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerTokenAmount, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.makerTokenAddress, signedOrder.maker, senderAddress, fillMakerTokenAmount, - TradeSide.Maker, TransferType.Trade, - ); - await exchangeTradeEmulator.transferFromAsync( - signedOrder.takerTokenAddress, senderAddress, signedOrder.maker, fillTakerTokenAmount, - TradeSide.Taker, TransferType.Trade, - ); - const makerFeeAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.makerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount, TradeSide.Maker, - TransferType.Fee, - ); - const takerFeeAmount = this.getPartialAmount( - fillTakerTokenAmount, - signedOrder.takerTokenAmount, - signedOrder.takerFee, - ); - await exchangeTradeEmulator.transferFromAsync( - zrxTokenAddress, senderAddress, signedOrder.feeRecipient, takerFeeAmount, TradeSide.Taker, - TransferType.Fee, - ); - } - private validateRemainingFillAmountNotZeroOrThrow( - takerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber, - ) { - if (takerTokenAmount.eq(unavailableTakerTokenAmount)) { - throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero); - } - } - private validateOrderNotExpiredOrThrow(expirationUnixTimestampSec: BigNumber) { - const currentUnixTimestampSec = utils.getCurrentUnixTimestampSec(); - if (expirationUnixTimestampSec.lessThan(currentUnixTimestampSec)) { - throw new Error(ExchangeContractErrs.OrderFillExpired); - } - } - private getPartialAmount(numerator: BigNumber, denominator: BigNumber, - target: BigNumber): BigNumber { - const fillMakerTokenAmount = numerator - .mul(target) - .div(denominator) - .round(0); - return fillMakerTokenAmount; - } } diff --git a/packages/0x.js/test/order_validation_test.ts b/packages/0x.js/test/order_validation_test.ts index 811cd48c4..3282ebb3e 100644 --- a/packages/0x.js/test/order_validation_test.ts +++ b/packages/0x.js/test/order_validation_test.ts @@ -114,7 +114,7 @@ describe('OrderValidation', () => { makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount, ); // 27 <--> 28 - signedOrder.ecSignature.v = 27 + (28 - signedOrder.ecSignature.v); + signedOrder.ecSignature.v = (28 - signedOrder.ecSignature.v) + 27; return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync( signedOrder, fillableAmount, takerAddress, )).to.be.rejectedWith(ZeroExError.InvalidSignature); @@ -230,7 +230,7 @@ describe('OrderValidation', () => { makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress, fillableAmount, feeRecipient, ); - await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress, ); expect(transferFromAsync.callCount).to.be.equal(4); @@ -266,7 +266,7 @@ describe('OrderValidation', () => { makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, ZeroEx.NULL_ADDRESS, fillableAmount, feeRecipient, ); - await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress, ); expect(transferFromAsync.callCount).to.be.equal(4); @@ -301,7 +301,7 @@ describe('OrderValidation', () => { const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync( makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, makerTokenAmount, takerTokenAmount, ); - await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( exchangeTransferSimulator, signedOrder, takerTokenAmount, takerAddress, zrxTokenAddress, ); expect(transferFromAsync.callCount).to.be.equal(4); @@ -316,7 +316,7 @@ describe('OrderValidation', () => { fillableAmount, ZeroEx.NULL_ADDRESS, ); const fillTakerTokenAmount = fillableAmount.div(2).round(0); - await orderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync( exchangeTransferSimulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress, ); const makerPartialFee = makerFee.div(2); |