aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils')
-rw-r--r--packages/order-utils/src/exchange_transfer_simulator.ts64
-rw-r--r--packages/order-utils/test/asset_data_utils_test.ts4
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);