diff options
Diffstat (limited to 'packages/order-utils/src')
-rw-r--r-- | packages/order-utils/src/asset_data_utils.ts | 36 | ||||
-rw-r--r-- | packages/order-utils/src/constants.ts | 107 | ||||
-rw-r--r-- | packages/order-utils/src/exchange_transfer_simulator.ts | 2 | ||||
-rw-r--r-- | packages/order-utils/src/order_state_utils.ts | 61 |
4 files changed, 109 insertions, 97 deletions
diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts index c2929d426..0526c3d00 100644 --- a/packages/order-utils/src/asset_data_utils.ts +++ b/packages/order-utils/src/asset_data_utils.ts @@ -7,7 +7,6 @@ import { SingleAssetData, } from '@0x/types'; import { AbiEncoder, BigNumber } from '@0x/utils'; -import { MethodAbi } from 'ethereum-types'; import * as _ from 'lodash'; import { constants } from './constants'; @@ -23,7 +22,7 @@ export const assetDataUtils = { * @return The hex encoded assetData string */ encodeERC20AssetData(tokenAddress: string): string { - const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI as MethodAbi); + const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI); const args = [tokenAddress]; const assetData = abiEncoder.encode(args, encodingRules); return assetData; @@ -36,7 +35,7 @@ export const assetDataUtils = { decodeERC20AssetData(assetData: string): ERC20AssetData { assetDataUtils.assertIsERC20AssetData(assetData); const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI as MethodAbi); + const abiEncoder = new AbiEncoder.Method(constants.ERC20_METHOD_ABI); const decodedAssetData = abiEncoder.decode(assetData, decodingRules); return { assetProxyId, @@ -52,7 +51,7 @@ export const assetDataUtils = { * @return The hex encoded assetData string */ encodeERC721AssetData(tokenAddress: string, tokenId: BigNumber): string { - const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI as MethodAbi); + const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI); const args = [tokenAddress, tokenId]; const assetData = abiEncoder.encode(args, encodingRules); return assetData; @@ -65,7 +64,7 @@ export const assetDataUtils = { decodeERC721AssetData(assetData: string): ERC721AssetData { assetDataUtils.assertIsERC721AssetData(assetData); const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI as MethodAbi); + const abiEncoder = new AbiEncoder.Method(constants.ERC721_METHOD_ABI); const decodedAssetData = abiEncoder.decode(assetData, decodingRules); return { assetProxyId, @@ -90,7 +89,7 @@ export const assetDataUtils = { ); } _.forEach(nestedAssetData, assetDataElement => assetDataUtils.validateAssetDataOrThrow(assetDataElement)); - const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI as MethodAbi); + const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI); const args = [amounts, nestedAssetData]; const assetData = abiEncoder.encode(args, encodingRules); return assetData; @@ -103,7 +102,7 @@ export const assetDataUtils = { decodeMultiAssetData(assetData: string): MultiAssetData { assetDataUtils.assertIsMultiAssetData(assetData); const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); - const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI as MethodAbi); + const abiEncoder = new AbiEncoder.Method(constants.MULTI_ASSET_METHOD_ABI); const decodedAssetData = abiEncoder.decode(assetData, decodingRules); // TODO(abandeali1): fix return types for `AbiEncoder.Method.decode` so that we can remove type assertion const amounts = (decodedAssetData as any).amounts; @@ -138,7 +137,7 @@ export const assetDataUtils = { nestedAssetDataElement, ); amounts.push( - _.map(recursivelyDecodedAssetData.amounts as BigNumber[], amountElement => + _.map(recursivelyDecodedAssetData.amounts, amountElement => amountElement.times(decodedAssetData.amounts[index]), ), ); @@ -182,6 +181,27 @@ export const assetDataUtils = { return assetProxyId; }, /** + * Checks if the decoded asset data is valid ERC20 data + * @param decodedAssetData The decoded asset data to check + */ + isERC20AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC20AssetData { + return decodedAssetData.assetProxyId === AssetProxyId.ERC20; + }, + /** + * Checks if the decoded asset data is valid ERC721 data + * @param decodedAssetData The decoded asset data to check + */ + isERC721AssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is ERC721AssetData { + return decodedAssetData.assetProxyId === AssetProxyId.ERC721; + }, + /** + * Checks if the decoded asset data is valid MultiAsset data + * @param decodedAssetData The decoded asset data to check + */ + isMultiAssetData(decodedAssetData: SingleAssetData | MultiAssetData): decodedAssetData is MultiAssetData { + return decodedAssetData.assetProxyId === AssetProxyId.MultiAsset; + }, + /** * Throws if the length or assetProxyId are invalid for the ERC20Proxy. * @param assetData Hex encoded assetData string */ diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts index 1248a5576..a9a687719 100644 --- a/packages/order-utils/src/constants.ts +++ b/packages/order-utils/src/constants.ts @@ -1,4 +1,58 @@ import { BigNumber } from '@0x/utils'; +import { MethodAbi } from 'ethereum-types'; + +const ERC20_METHOD_ABI: MethodAbi = { + constant: false, + inputs: [ + { + name: 'tokenContract', + type: 'address', + }, + ], + name: 'ERC20Token', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', +}; + +const ERC721_METHOD_ABI: MethodAbi = { + constant: false, + inputs: [ + { + name: 'tokenContract', + type: 'address', + }, + { + name: 'tokenId', + type: 'uint256', + }, + ], + name: 'ERC721Token', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', +}; + +const MULTI_ASSET_METHOD_ABI: MethodAbi = { + constant: false, + inputs: [ + { + name: 'amounts', + type: 'uint256[]', + }, + { + name: 'nestedAssetData', + type: 'bytes[]', + }, + ], + name: 'MultiAsset', + outputs: [], + payable: false, + stateMutability: 'nonpayable', + type: 'function', +}; export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', @@ -49,54 +103,7 @@ export const constants = { { name: 'data', type: 'bytes' }, ], }, - ERC20_METHOD_ABI: { - constant: false, - inputs: [ - { - name: 'tokenContract', - type: 'address', - }, - ], - name: 'ERC20Token', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - ERC721_METHOD_ABI: { - constant: false, - inputs: [ - { - name: 'tokenContract', - type: 'address', - }, - { - name: 'tokenId', - type: 'uint256', - }, - ], - name: 'ERC721Token', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, - MULTI_ASSET_METHOD_ABI: { - constant: false, - inputs: [ - { - name: 'amounts', - type: 'uint256[]', - }, - { - name: 'nestedAssetData', - type: 'bytes[]', - }, - ], - name: 'MultiAsset', - outputs: [], - payable: false, - stateMutability: 'nonpayable', - type: 'function', - }, + ERC20_METHOD_ABI, + ERC721_METHOD_ABI, + MULTI_ASSET_METHOD_ABI, }; diff --git a/packages/order-utils/src/exchange_transfer_simulator.ts b/packages/order-utils/src/exchange_transfer_simulator.ts index 0a948fd1f..06621fd9e 100644 --- a/packages/order-utils/src/exchange_transfer_simulator.ts +++ b/packages/order-utils/src/exchange_transfer_simulator.ts @@ -108,7 +108,7 @@ export class ExchangeTransferSimulator { const amountsElement = decodedAssetData.amounts[index]; const totalAmount = amountInBaseUnits.times(amountsElement); await this.transferFromAsync( - nestedAssetDataElement as string, + nestedAssetDataElement, from, to, totalAmount, 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<ObjectMap<BigNumber>> { const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); let balances: ObjectMap<BigNumber> = { ...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<ObjectMap<BigNumber>> { const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); let allowances: ObjectMap<BigNumber> = { ...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; } |