diff options
-rw-r--r-- | packages/order-utils/src/asset_data_utils.ts | 30 | ||||
-rw-r--r-- | packages/order-utils/src/constants.ts | 1 | ||||
-rw-r--r-- | packages/order-utils/test/asset_data_utils_test.ts | 43 | ||||
-rw-r--r-- | packages/order-utils/test/utils/test_order_factory.ts | 4 |
4 files changed, 68 insertions, 10 deletions
diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts index 3741a683e..b5ce87e3e 100644 --- a/packages/order-utils/src/asset_data_utils.ts +++ b/packages/order-utils/src/asset_data_utils.ts @@ -128,16 +128,32 @@ export const assetDataUtils = { */ decodeMultiAssetDataRecursively(assetData: string): MultiAssetDataWithRecursiveDecoding { const decodedAssetData = assetDataUtils.decodeMultiAssetData(assetData); - const decodedNestedAssetData = _.map(decodedAssetData.nestedAssetData as string[], nestedAssetDataElement => { - const decodedNestedAssetDataElement = assetDataUtils.decodeAssetDataOrThrow(nestedAssetDataElement); - return decodedNestedAssetDataElement.assetProxyId === AssetProxyId.MultiAsset - ? assetDataUtils.decodeMultiAssetDataRecursively(nestedAssetDataElement).nestedAssetData - : (decodedNestedAssetDataElement as SingleAssetData); - }); + const amounts: any[] = []; + const decodedNestedAssetData = _.map( + decodedAssetData.nestedAssetData as string[], + (nestedAssetDataElement, index) => { + const decodedNestedAssetDataElement = assetDataUtils.decodeAssetDataOrThrow(nestedAssetDataElement); + if (decodedNestedAssetDataElement.assetProxyId === AssetProxyId.MultiAsset) { + const recursivelyDecodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively( + nestedAssetDataElement, + ); + amounts.push( + _.map(recursivelyDecodedAssetData.amounts as BigNumber[], amountElement => + amountElement.times(decodedAssetData.amounts[index]), + ), + ); + return recursivelyDecodedAssetData.nestedAssetData; + } else { + amounts.push(decodedAssetData.amounts[index]); + return decodedNestedAssetDataElement as SingleAssetData; + } + }, + ); + const flattenedAmounts = _.flattenDeep(amounts); const flattenedDecodedNestedAssetData = _.flattenDeep(decodedNestedAssetData); return { assetProxyId: decodedAssetData.assetProxyId, - amounts: decodedAssetData.amounts, + amounts: flattenedAmounts, nestedAssetData: flattenedDecodedNestedAssetData as SingleAssetData[], }; }, diff --git a/packages/order-utils/src/constants.ts b/packages/order-utils/src/constants.ts index be7f3a885..1248a5576 100644 --- a/packages/order-utils/src/constants.ts +++ b/packages/order-utils/src/constants.ts @@ -3,6 +3,7 @@ import { BigNumber } from '@0x/utils'; export const constants = { NULL_ADDRESS: '0x0000000000000000000000000000000000000000', NULL_BYTES: '0x', + NULL_ERC20_ASSET_DATA: '0xf47261b00000000000000000000000000000000000000000000000000000000000000000', // tslint:disable-next-line:custom-no-magic-numbers UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1), TESTRPC_NETWORK_ID: 50, diff --git a/packages/order-utils/test/asset_data_utils_test.ts b/packages/order-utils/test/asset_data_utils_test.ts index 6835b6e30..d3d265b5a 100644 --- a/packages/order-utils/test/asset_data_utils_test.ts +++ b/packages/order-utils/test/asset_data_utils_test.ts @@ -1,6 +1,6 @@ import * as chai from 'chai'; -import { AssetProxyId } from '@0x/types'; +import { AssetProxyId, ERC721AssetData } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { assetDataUtils } from '../src/asset_data_utils'; @@ -63,4 +63,45 @@ describe('assetDataUtils', () => { expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts); expect(decodedAssetData.nestedAssetData).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.nestedAssetData); }); + it('should recursively decode ERC20 and ERC721 multiAssetData', () => { + const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(KNOWN_MULTI_ASSET_ENCODING.assetData); + expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset); + expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts); + const decodedErc20AssetData = decodedAssetData.nestedAssetData[0]; + const decodedErc721AssetData = decodedAssetData.nestedAssetData[1] as ERC721AssetData; + expect(decodedErc20AssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); + expect(decodedErc20AssetData.assetProxyId).to.equal(AssetProxyId.ERC20); + expect(decodedErc721AssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); + expect(decodedErc721AssetData.assetProxyId).to.equal(AssetProxyId.ERC721); + expect(decodedErc721AssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId); + }); + it('should recursively decode nested assetData within multiAssetData', () => { + const amounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2)]; + const nestedAssetData = [ + KNOWN_ERC20_ENCODING.assetData, + KNOWN_ERC721_ENCODING.assetData, + KNOWN_MULTI_ASSET_ENCODING.assetData, + ]; + const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(assetData); + expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset); + const expectedAmounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2), new BigNumber(2)]; + expect(decodedAssetData.amounts).to.deep.equal(expectedAmounts); + const expectedLength = 4; + expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedLength); + const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[0]; + const decodedErc721AssetData1 = decodedAssetData.nestedAssetData[1] as ERC721AssetData; + const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[2]; + const decodedErc721AssetData2 = decodedAssetData.nestedAssetData[3] as ERC721AssetData; + expect(decodedErc20AssetData1.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); + expect(decodedErc20AssetData1.assetProxyId).to.equal(AssetProxyId.ERC20); + expect(decodedErc721AssetData1.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); + expect(decodedErc721AssetData1.assetProxyId).to.equal(AssetProxyId.ERC721); + expect(decodedErc721AssetData1.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId); + expect(decodedErc20AssetData2.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address); + expect(decodedErc20AssetData2.assetProxyId).to.equal(AssetProxyId.ERC20); + expect(decodedErc721AssetData2.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address); + expect(decodedErc721AssetData2.assetProxyId).to.equal(AssetProxyId.ERC721); + expect(decodedErc721AssetData2.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId); + }); }); diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts index 145332674..4efe0b38e 100644 --- a/packages/order-utils/test/utils/test_order_factory.ts +++ b/packages/order-utils/test/utils/test_order_factory.ts @@ -7,9 +7,9 @@ import { orderFactory } from '../../src/order_factory'; const BASE_TEST_ORDER: Order = orderFactory.createOrder( constants.NULL_ADDRESS, constants.ZERO_AMOUNT, - constants.NULL_ADDRESS, + constants.NULL_ERC20_ASSET_DATA, constants.ZERO_AMOUNT, - constants.NULL_ADDRESS, + constants.NULL_ERC20_ASSET_DATA, constants.NULL_ADDRESS, ); const BASE_TEST_SIGNED_ORDER: SignedOrder = { |