aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils/order_validation_utils.ts
diff options
context:
space:
mode:
authorLeonid <logvinov.leon@gmail.com>2017-07-26 04:26:14 +0800
committerGitHub <noreply@github.com>2017-07-26 04:26:14 +0800
commit89aa19f6e4042ffcda906e4fa6a7de3d6d2e57c1 (patch)
tree357d487f6f4442a04457d85b55853a78bb4b4e85 /src/utils/order_validation_utils.ts
parent97e680aba1a68c509e903e929a848db53182722f (diff)
parent660aa224ca990af27867cdd1523553f50ba50b77 (diff)
downloaddexon-0x-contracts-89aa19f6e4042ffcda906e4fa6a7de3d6d2e57c1.tar.gz
dexon-0x-contracts-89aa19f6e4042ffcda906e4fa6a7de3d6d2e57c1.tar.zst
dexon-0x-contracts-89aa19f6e4042ffcda906e4fa6a7de3d6d2e57c1.zip
Merge pull request #109 from 0xProject/fees-balance-allowance-validation
Fees balance allowance validation
Diffstat (limited to 'src/utils/order_validation_utils.ts')
-rw-r--r--src/utils/order_validation_utils.ts81
1 files changed, 81 insertions, 0 deletions
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);
+ }
+ }
+ }
+}