From de4916ccb811e6324692e1b7fccec0940ef0c44f Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Wed, 2 Jan 2019 14:05:51 -0800 Subject: Add individual balances and allowances to OrderRelevantState --- packages/order-utils/src/order_state_utils.ts | 71 +++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'packages/order-utils/src/order_state_utils.ts') diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts index fe0d6c773..9e3e228ba 100644 --- a/packages/order-utils/src/order_state_utils.ts +++ b/packages/order-utils/src/order_state_utils.ts @@ -1,15 +1,21 @@ import { + AssetProxyId, ExchangeContractErrs, + MultiAssetData, + ObjectMap, OrderRelevantState, OrderState, OrderStateInvalid, OrderStateValid, SignedOrder, + SingleAssetData, } from '@0x/types'; import { BigNumber } from '@0x/utils'; +import * as _ from 'lodash'; import { AbstractBalanceAndProxyAllowanceFetcher } from './abstract/abstract_balance_and_proxy_allowance_fetcher'; import { AbstractOrderFilledCancelledFetcher } from './abstract/abstract_order_filled_cancelled_fetcher'; +import { assetDataUtils } from './asset_data_utils'; import { orderHashUtils } from './order_hash'; import { OrderValidationUtils } from './order_validation_utils'; import { RemainingFillableCalculator } from './remaining_fillable_calculator'; @@ -18,7 +24,9 @@ import { utils } from './utils'; interface SidedOrderRelevantState { isMakerSide: boolean; traderBalance: BigNumber; + traderIndividualBalances: ObjectMap; traderProxyAllowance: BigNumber; + traderIndividualProxyAllowances: ObjectMap; traderFeeBalance: BigNumber; traderFeeProxyAllowance: BigNumber; filledTakerAssetAmount: BigNumber; @@ -121,7 +129,9 @@ export class OrderStateUtils { const sidedOrderRelevantState = { isMakerSide: true, traderBalance: orderRelevantState.makerBalance, + traderIndividualBalances: orderRelevantState.makerIndividualBalances, traderProxyAllowance: orderRelevantState.makerProxyAllowance, + traderIndividualProxyAllowances: orderRelevantState.makerIndividualProxyAllowances, traderFeeBalance: orderRelevantState.makerFeeBalance, traderFeeProxyAllowance: orderRelevantState.makerFeeProxyAllowance, filledTakerAssetAmount: orderRelevantState.filledTakerAssetAmount, @@ -165,7 +175,9 @@ export class OrderStateUtils { const orderRelevantState = { makerBalance: sidedOrderRelevantState.traderBalance, + makerIndividualBalances: sidedOrderRelevantState.traderIndividualBalances, makerProxyAllowance: sidedOrderRelevantState.traderProxyAllowance, + makerIndividualProxyAllowances: sidedOrderRelevantState.traderIndividualProxyAllowances, makerFeeBalance: sidedOrderRelevantState.traderFeeBalance, makerFeeProxyAllowance: sidedOrderRelevantState.traderFeeProxyAllowance, filledTakerAssetAmount: sidedOrderRelevantState.filledTakerAssetAmount, @@ -236,10 +248,12 @@ export class OrderStateUtils { const isAssetZRX = assetData === zrxAssetData; const traderBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress); + const traderIndividualBalances = await this._getAssetBalancesAsync(assetData, traderAddress); const traderProxyAllowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync( assetData, traderAddress, ); + const traderIndividualProxyAllowances = await this._getAssetProxyAllowancesAsync(assetData, traderAddress); const traderFeeBalance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync( zrxAssetData, traderAddress, @@ -278,7 +292,9 @@ export class OrderStateUtils { const sidedOrderRelevantState = { isMakerSide, traderBalance, + traderIndividualBalances, traderProxyAllowance, + traderIndividualProxyAllowances, traderFeeBalance, traderFeeProxyAllowance, filledTakerAssetAmount, @@ -287,4 +303,59 @@ export class OrderStateUtils { }; return sidedOrderRelevantState; } + private async _getAssetBalancesAsync( + assetData: string, + traderAddress: string, + initialBalances: ObjectMap = {}, + ): Promise> { + const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); + let balances: ObjectMap = { ...initialBalances }; + switch (decodedAssetData.assetProxyId) { + case AssetProxyId.ERC20: + case AssetProxyId.ERC721: + const balance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress); + const tokenAddress = (decodedAssetData as SingleAssetData).tokenAddress; + balances[tokenAddress] = _.isUndefined(initialBalances[tokenAddress]) + ? balance + : balances[tokenAddress].add(balance); + break; + case AssetProxyId.MultiAsset: + for (const assetDataElement of (decodedAssetData as MultiAssetData).nestedAssetData) { + balances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, balances); + } + break; + default: + throw new Error(`Proxy with id ${decodedAssetData.assetProxyId} not supported`); + } + return balances; + } + private async _getAssetProxyAllowancesAsync( + assetData: string, + traderAddress: string, + initialAllowances: ObjectMap = {}, + ): Promise> { + const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); + let allowances: ObjectMap = { ...initialAllowances }; + switch (decodedAssetData.assetProxyId) { + case AssetProxyId.ERC20: + case AssetProxyId.ERC721: + const allowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync( + assetData, + traderAddress, + ); + const tokenAddress = (decodedAssetData as SingleAssetData).tokenAddress; + allowances[tokenAddress] = _.isUndefined(initialAllowances[tokenAddress]) + ? allowance + : allowances[tokenAddress].add(allowance); + break; + case AssetProxyId.MultiAsset: + for (const assetDataElement of (decodedAssetData as MultiAssetData).nestedAssetData) { + allowances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, allowances); + } + break; + default: + throw new Error(`Proxy with id ${decodedAssetData.assetProxyId} not supported`); + } + return allowances; + } } -- cgit v1.2.3 From 24564b986daa703f66e54f85abf4782d99a40f94 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Fri, 4 Jan 2019 14:31:25 -0800 Subject: Minimize unnecessary type assertions --- packages/order-utils/src/order_state_utils.ts | 61 ++++++++++----------------- 1 file changed, 23 insertions(+), 38 deletions(-) (limited to 'packages/order-utils/src/order_state_utils.ts') diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts index 9e3e228ba..389419587 100644 --- a/packages/order-utils/src/order_state_utils.ts +++ b/packages/order-utils/src/order_state_utils.ts @@ -1,14 +1,11 @@ import { - AssetProxyId, ExchangeContractErrs, - MultiAssetData, ObjectMap, OrderRelevantState, OrderState, OrderStateInvalid, OrderStateValid, SignedOrder, - SingleAssetData, } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; @@ -310,22 +307,16 @@ export class OrderStateUtils { ): Promise> { const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); let balances: ObjectMap = { ...initialBalances }; - switch (decodedAssetData.assetProxyId) { - case AssetProxyId.ERC20: - case AssetProxyId.ERC721: - const balance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress); - const tokenAddress = (decodedAssetData as SingleAssetData).tokenAddress; - balances[tokenAddress] = _.isUndefined(initialBalances[tokenAddress]) - ? balance - : balances[tokenAddress].add(balance); - break; - case AssetProxyId.MultiAsset: - for (const assetDataElement of (decodedAssetData as MultiAssetData).nestedAssetData) { - balances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, balances); - } - break; - default: - throw new Error(`Proxy with id ${decodedAssetData.assetProxyId} not supported`); + if (assetDataUtils.isERC20AssetData(decodedAssetData) || assetDataUtils.isERC721AssetData(decodedAssetData)) { + const balance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress); + const tokenAddress = decodedAssetData.tokenAddress; + balances[tokenAddress] = _.isUndefined(initialBalances[tokenAddress]) + ? balance + : balances[tokenAddress].add(balance); + } else if (assetDataUtils.isMultiAssetData(decodedAssetData)) { + for (const assetDataElement of decodedAssetData.nestedAssetData) { + balances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, balances); + } } return balances; } @@ -336,25 +327,19 @@ export class OrderStateUtils { ): Promise> { const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); let allowances: ObjectMap = { ...initialAllowances }; - switch (decodedAssetData.assetProxyId) { - case AssetProxyId.ERC20: - case AssetProxyId.ERC721: - const allowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync( - assetData, - traderAddress, - ); - const tokenAddress = (decodedAssetData as SingleAssetData).tokenAddress; - allowances[tokenAddress] = _.isUndefined(initialAllowances[tokenAddress]) - ? allowance - : allowances[tokenAddress].add(allowance); - break; - case AssetProxyId.MultiAsset: - for (const assetDataElement of (decodedAssetData as MultiAssetData).nestedAssetData) { - allowances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, allowances); - } - break; - default: - throw new Error(`Proxy with id ${decodedAssetData.assetProxyId} not supported`); + if (assetDataUtils.isERC20AssetData(decodedAssetData) || assetDataUtils.isERC721AssetData(decodedAssetData)) { + const allowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync( + assetData, + traderAddress, + ); + const tokenAddress = decodedAssetData.tokenAddress; + allowances[tokenAddress] = _.isUndefined(initialAllowances[tokenAddress]) + ? allowance + : allowances[tokenAddress].add(allowance); + } else if (assetDataUtils.isMultiAssetData(decodedAssetData)) { + for (const assetDataElement of decodedAssetData.nestedAssetData) { + allowances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, allowances); + } } return allowances; } -- cgit v1.2.3