diff options
author | Amir Bandeali <abandeali1@gmail.com> | 2018-12-05 07:44:46 +0800 |
---|---|---|
committer | Amir Bandeali <abandeali1@gmail.com> | 2019-01-08 02:31:11 +0800 |
commit | eeb07d76fc81b786d83c4ab848cc538e5896e240 (patch) | |
tree | c13339e9b59fb8cf01d94be545d31fd67206633b /packages/order-utils | |
parent | 0abace337c8309b22092519091d10e3474095878 (diff) | |
download | dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.tar dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.tar.gz dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.tar.bz2 dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.tar.lz dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.tar.xz dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.tar.zst dexon-0x-contracts-eeb07d76fc81b786d83c4ab848cc538e5896e240.zip |
Fix transferFrom to work with MAP
Diffstat (limited to 'packages/order-utils')
-rw-r--r-- | packages/order-utils/src/exchange_transfer_simulator.ts | 64 | ||||
-rw-r--r-- | packages/order-utils/test/asset_data_utils_test.ts | 4 |
2 files changed, 48 insertions, 20 deletions
diff --git a/packages/order-utils/src/exchange_transfer_simulator.ts b/packages/order-utils/src/exchange_transfer_simulator.ts index 7a38b35df..06621fd9e 100644 --- a/packages/order-utils/src/exchange_transfer_simulator.ts +++ b/packages/order-utils/src/exchange_transfer_simulator.ts @@ -1,7 +1,8 @@ -import { ExchangeContractErrs } from '@0x/types'; +import { AssetProxyId, ExchangeContractErrs } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { AbstractBalanceAndProxyAllowanceLazyStore } from './abstract/abstract_balance_and_proxy_allowance_lazy_store'; +import { assetDataUtils } from './asset_data_utils'; import { constants } from './constants'; import { TradeSide, TransferType } from './types'; @@ -74,24 +75,51 @@ export class ExchangeTransferSimulator { tradeSide: TradeSide, transferType: TransferType, ): Promise<void> { - // HACK: When simulating an open order (e.g taker is NULL_ADDRESS), we don't want to adjust balances/ - // allowances for the taker. We do however, want to increase the balance of the maker since the maker - // might be relying on those funds to fill subsequent orders or pay the order's fees. - if (from === constants.NULL_ADDRESS && tradeSide === TradeSide.Taker) { - await this._increaseBalanceAsync(assetData, to, amountInBaseUnits); - return; + const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); + switch (assetProxyId) { + case AssetProxyId.ERC20: + case AssetProxyId.ERC721: + // HACK: When simulating an open order (e.g taker is NULL_ADDRESS), we don't want to adjust balances/ + // allowances for the taker. We do however, want to increase the balance of the maker since the maker + // might be relying on those funds to fill subsequent orders or pay the order's fees. + if (from === constants.NULL_ADDRESS && tradeSide === TradeSide.Taker) { + await this._increaseBalanceAsync(assetData, to, amountInBaseUnits); + return; + } + const balance = await this._store.getBalanceAsync(assetData, from); + const proxyAllowance = await this._store.getProxyAllowanceAsync(assetData, from); + if (proxyAllowance.lessThan(amountInBaseUnits)) { + ExchangeTransferSimulator._throwValidationError( + FailureReason.ProxyAllowance, + tradeSide, + transferType, + ); + } + if (balance.lessThan(amountInBaseUnits)) { + ExchangeTransferSimulator._throwValidationError(FailureReason.Balance, tradeSide, transferType); + } + await this._decreaseProxyAllowanceAsync(assetData, from, amountInBaseUnits); + await this._decreaseBalanceAsync(assetData, from, amountInBaseUnits); + await this._increaseBalanceAsync(assetData, to, amountInBaseUnits); + break; + case AssetProxyId.MultiAsset: + const decodedAssetData = assetDataUtils.decodeMultiAssetData(assetData); + for (const [index, nestedAssetDataElement] of decodedAssetData.nestedAssetData.entries()) { + const amountsElement = decodedAssetData.amounts[index]; + const totalAmount = amountInBaseUnits.times(amountsElement); + await this.transferFromAsync( + nestedAssetDataElement, + from, + to, + totalAmount, + tradeSide, + transferType, + ); + } + break; + default: + break; } - const balance = await this._store.getBalanceAsync(assetData, from); - const proxyAllowance = await this._store.getProxyAllowanceAsync(assetData, from); - if (proxyAllowance.lessThan(amountInBaseUnits)) { - ExchangeTransferSimulator._throwValidationError(FailureReason.ProxyAllowance, tradeSide, transferType); - } - if (balance.lessThan(amountInBaseUnits)) { - ExchangeTransferSimulator._throwValidationError(FailureReason.Balance, tradeSide, transferType); - } - await this._decreaseProxyAllowanceAsync(assetData, from, amountInBaseUnits); - await this._decreaseBalanceAsync(assetData, from, amountInBaseUnits); - await this._increaseBalanceAsync(assetData, to, amountInBaseUnits); } private async _decreaseProxyAllowanceAsync( assetData: string, diff --git a/packages/order-utils/test/asset_data_utils_test.ts b/packages/order-utils/test/asset_data_utils_test.ts index a070aaf16..6835b6e30 100644 --- a/packages/order-utils/test/asset_data_utils_test.ts +++ b/packages/order-utils/test/asset_data_utils_test.ts @@ -50,14 +50,14 @@ describe('assetDataUtils', () => { expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.ERC721); expect(decodedAssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId); }); - it('should encode ERC20 and ERC721', () => { + it('should encode ERC20 and ERC721 multiAssetData', () => { const assetData = assetDataUtils.encodeMultiAssetData( KNOWN_MULTI_ASSET_ENCODING.amounts, KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, ); expect(assetData).to.equal(KNOWN_MULTI_ASSET_ENCODING.assetData); }); - it('should decode ERC20 and ERC21', () => { + it('should decode ERC20 and ERC721 multiAssetData', () => { const decodedAssetData = assetDataUtils.decodeMultiAssetData(KNOWN_MULTI_ASSET_ENCODING.assetData); expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset); expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts); |