diff options
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/assert.ts | 1 | ||||
-rw-r--r-- | src/utils/order_validation_utils.ts | 81 |
2 files changed, 81 insertions, 1 deletions
diff --git a/src/utils/assert.ts b/src/utils/assert.ts index dab796c4e..969209208 100644 --- a/src/utils/assert.ts +++ b/src/utils/assert.ts @@ -3,7 +3,6 @@ import * as BigNumber from 'bignumber.js'; import * as Web3 from 'web3'; import {Web3Wrapper} from '../web3_wrapper'; import {SchemaValidator} from './schema_validator'; -import {utils} from './utils'; const HEX_REGEX = /^0x[0-9A-F]*$/i; diff --git a/src/utils/order_validation_utils.ts b/src/utils/order_validation_utils.ts new file mode 100644 index 000000000..8a737040c --- /dev/null +++ b/src/utils/order_validation_utils.ts @@ -0,0 +1,81 @@ +import {ExchangeContractErrs, SignedOrder} from '../types'; +import {TokenWrapper} from '../contract_wrappers/token_wrapper'; + +export class OrderValidationUtils { + private tokenWrapper: TokenWrapper; + constructor(tokenWrapper: TokenWrapper) { + this.tokenWrapper = tokenWrapper; + } + public async validateFillOrderBalancesAllowancesThrowIfInvalidAsync( + signedOrder: SignedOrder, fillTakerAmount: BigNumber.BigNumber, senderAddress: string, zrxTokenAddress: string, + ): Promise<void> { + await this.validateFillOrderMakerBalancesAllowancesThrowIfInvalidAsync( + signedOrder, fillTakerAmount, zrxTokenAddress, + ); + await this.validateFillOrderTakerBalancesAllowancesThrowIfInvalidAsync( + signedOrder, fillTakerAmount, senderAddress, zrxTokenAddress, + ); + } + private async validateFillOrderMakerBalancesAllowancesThrowIfInvalidAsync( + signedOrder: SignedOrder, fillTakerAmount: BigNumber.BigNumber, zrxTokenAddress: string, + ): Promise<void> { + const makerBalance = await this.tokenWrapper.getBalanceAsync(signedOrder.makerTokenAddress, signedOrder.maker); + const makerAllowance = await this.tokenWrapper.getProxyAllowanceAsync( + signedOrder.makerTokenAddress, signedOrder.maker); + + const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress; + // exchangeRate is the price of one maker token denominated in taker tokens + const exchangeRate = signedOrder.takerTokenAmount.div(signedOrder.makerTokenAmount); + const fillMakerAmount = fillTakerAmount.div(exchangeRate); + + const requiredMakerAmount = isMakerTokenZRX ? fillMakerAmount.plus(signedOrder.makerFee) : fillMakerAmount; + if (requiredMakerAmount.greaterThan(makerBalance)) { + throw new Error(ExchangeContractErrs.InsufficientMakerBalance); + } + if (requiredMakerAmount.greaterThan(makerAllowance)) { + throw new Error(ExchangeContractErrs.InsufficientMakerAllowance); + } + + if (!isMakerTokenZRX) { + const makerZRXBalance = await this.tokenWrapper.getBalanceAsync(zrxTokenAddress, signedOrder.maker); + const makerZRXAllowance = await this.tokenWrapper.getProxyAllowanceAsync( + zrxTokenAddress, signedOrder.maker); + + if (signedOrder.makerFee.greaterThan(makerZRXBalance)) { + throw new Error(ExchangeContractErrs.InsufficientMakerFeeBalance); + } + if (signedOrder.makerFee.greaterThan(makerZRXAllowance)) { + throw new Error(ExchangeContractErrs.InsufficientMakerFeeAllowance); + } + } + } + private async validateFillOrderTakerBalancesAllowancesThrowIfInvalidAsync( + signedOrder: SignedOrder, fillTakerAmount: BigNumber.BigNumber, senderAddress: string, zrxTokenAddress: string, + ): Promise<void> { + const takerBalance = await this.tokenWrapper.getBalanceAsync(signedOrder.takerTokenAddress, senderAddress); + const takerAllowance = await this.tokenWrapper.getProxyAllowanceAsync( + signedOrder.takerTokenAddress, senderAddress); + + const isTakerTokenZRX = signedOrder.takerTokenAddress === zrxTokenAddress; + + const requiredTakerAmount = isTakerTokenZRX ? fillTakerAmount.plus(signedOrder.takerFee) : fillTakerAmount; + if (requiredTakerAmount.greaterThan(takerBalance)) { + throw new Error(ExchangeContractErrs.InsufficientTakerBalance); + } + if (requiredTakerAmount.greaterThan(takerAllowance)) { + throw new Error(ExchangeContractErrs.InsufficientTakerAllowance); + } + + if (!isTakerTokenZRX) { + const takerZRXBalance = await this.tokenWrapper.getBalanceAsync(zrxTokenAddress, senderAddress); + const takerZRXAllowance = await this.tokenWrapper.getProxyAllowanceAsync(zrxTokenAddress, senderAddress); + + if (signedOrder.takerFee.greaterThan(takerZRXBalance)) { + throw new Error(ExchangeContractErrs.InsufficientTakerFeeBalance); + } + if (signedOrder.takerFee.greaterThan(takerZRXAllowance)) { + throw new Error(ExchangeContractErrs.InsufficientTakerFeeAllowance); + } + } + } +} |