aboutsummaryrefslogtreecommitdiffstats
path: root/contracts/core/test/utils
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2018-12-11 06:37:48 +0800
committerLeonid Logvinov <logvinov.leon@gmail.com>2018-12-11 06:44:49 +0800
commit9f5eeed30930eea59e9922569a15cb5d689f3eeb (patch)
tree74dac8603dae440bcaa28245fd5af49815284840 /contracts/core/test/utils
parent14ea4ee1d3fd1a34c1747b928d9b463787e603e7 (diff)
downloaddexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.tar
dexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.tar.gz
dexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.tar.bz2
dexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.tar.lz
dexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.tar.xz
dexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.tar.zst
dexon-sol-tools-9f5eeed30930eea59e9922569a15cb5d689f3eeb.zip
Rename core package to protocol
Diffstat (limited to 'contracts/core/test/utils')
-rw-r--r--contracts/core/test/utils/asset_proxy_owner_wrapper.ts70
-rw-r--r--contracts/core/test/utils/asset_wrapper.ts222
-rw-r--r--contracts/core/test/utils/erc20_wrapper.ts179
-rw-r--r--contracts/core/test/utils/erc721_wrapper.ts236
-rw-r--r--contracts/core/test/utils/exchange_wrapper.ts281
-rw-r--r--contracts/core/test/utils/fill_order_combinatorial_utils.ts928
-rw-r--r--contracts/core/test/utils/index.ts3
-rw-r--r--contracts/core/test/utils/match_order_tester.ts562
-rw-r--r--contracts/core/test/utils/order_factory_from_scenario.ts294
-rw-r--r--contracts/core/test/utils/simple_asset_balance_and_proxy_allowance_fetcher.ts19
-rw-r--r--contracts/core/test/utils/simple_order_filled_cancelled_fetcher.ts31
11 files changed, 0 insertions, 2825 deletions
diff --git a/contracts/core/test/utils/asset_proxy_owner_wrapper.ts b/contracts/core/test/utils/asset_proxy_owner_wrapper.ts
deleted file mode 100644
index df23658d8..000000000
--- a/contracts/core/test/utils/asset_proxy_owner_wrapper.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { LogDecoder } from '@0x/contracts-test-utils';
-import { artifacts as tokensArtifacts } from '@0x/contracts-tokens';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
-import * as _ from 'lodash';
-
-import { AssetProxyOwnerContract } from '../../generated-wrappers/asset_proxy_owner';
-import { artifacts } from '../../src/artifacts';
-
-export class AssetProxyOwnerWrapper {
- private readonly _assetProxyOwner: AssetProxyOwnerContract;
- private readonly _web3Wrapper: Web3Wrapper;
- private readonly _logDecoder: LogDecoder;
- constructor(assetproxyOwnerContract: AssetProxyOwnerContract, provider: Provider) {
- this._assetProxyOwner = assetproxyOwnerContract;
- this._web3Wrapper = new Web3Wrapper(provider);
- this._logDecoder = new LogDecoder(this._web3Wrapper, { ...artifacts, ...tokensArtifacts });
- }
- public async submitTransactionAsync(
- destination: string,
- data: string,
- from: string,
- opts: { value?: BigNumber } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const value = _.isUndefined(opts.value) ? new BigNumber(0) : opts.value;
- const txHash = await this._assetProxyOwner.submitTransaction.sendTransactionAsync(destination, value, data, {
- from,
- });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async confirmTransactionAsync(txId: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
- const txHash = await this._assetProxyOwner.confirmTransaction.sendTransactionAsync(txId, { from });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async revokeConfirmationAsync(txId: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
- const txHash = await this._assetProxyOwner.revokeConfirmation.sendTransactionAsync(txId, { from });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async executeTransactionAsync(
- txId: BigNumber,
- from: string,
- opts: { gas?: number } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const txHash = await this._assetProxyOwner.executeTransaction.sendTransactionAsync(txId, {
- from,
- gas: opts.gas,
- });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async executeRemoveAuthorizedAddressAtIndexAsync(
- txId: BigNumber,
- from: string,
- ): Promise<TransactionReceiptWithDecodedLogs> {
- // tslint:disable-next-line:no-unnecessary-type-assertion
- const txHash = await (this
- ._assetProxyOwner as AssetProxyOwnerContract).executeRemoveAuthorizedAddressAtIndex.sendTransactionAsync(
- txId,
- {
- from,
- },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
-}
diff --git a/contracts/core/test/utils/asset_wrapper.ts b/contracts/core/test/utils/asset_wrapper.ts
deleted file mode 100644
index e4090ad74..000000000
--- a/contracts/core/test/utils/asset_wrapper.ts
+++ /dev/null
@@ -1,222 +0,0 @@
-import { AbstractAssetWrapper, constants } from '@0x/contracts-test-utils';
-import { assetDataUtils } from '@0x/order-utils';
-import { AssetProxyId } from '@0x/types';
-import { BigNumber, errorUtils } from '@0x/utils';
-import * as _ from 'lodash';
-
-import { ERC20Wrapper } from './erc20_wrapper';
-import { ERC721Wrapper } from './erc721_wrapper';
-
-interface ProxyIdToAssetWrappers {
- [proxyId: string]: AbstractAssetWrapper;
-}
-
-/**
- * This class abstracts away the differences between ERC20 and ERC721 tokens so that
- * the logic that uses it does not need to care what standard a token belongs to.
- */
-export class AssetWrapper {
- private readonly _proxyIdToAssetWrappers: ProxyIdToAssetWrappers;
- constructor(assetWrappers: AbstractAssetWrapper[]) {
- this._proxyIdToAssetWrappers = {};
- _.each(assetWrappers, assetWrapper => {
- const proxyId = assetWrapper.getProxyId();
- this._proxyIdToAssetWrappers[proxyId] = assetWrapper;
- });
- }
- public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
- const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (proxyId) {
- case AssetProxyId.ERC20: {
- const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
- const balance = await erc20Wrapper.getBalanceAsync(userAddress, assetData);
- return balance;
- }
- case AssetProxyId.ERC721: {
- const assetWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
- const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData);
- const isOwner = await assetWrapper.isOwnerAsync(
- userAddress,
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- );
- const balance = isOwner ? new BigNumber(1) : new BigNumber(0);
- return balance;
- }
- default:
- throw errorUtils.spawnSwitchErr('proxyId', proxyId);
- }
- }
- public async setBalanceAsync(userAddress: string, assetData: string, desiredBalance: BigNumber): Promise<void> {
- const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (proxyId) {
- case AssetProxyId.ERC20: {
- const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
- await erc20Wrapper.setBalanceAsync(userAddress, assetData, desiredBalance);
- return;
- }
- case AssetProxyId.ERC721: {
- if (!desiredBalance.eq(0) && !desiredBalance.eq(1)) {
- throw new Error(`Balance for ERC721 token can only be set to 0 or 1. Got: ${desiredBalance}`);
- }
- const erc721Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
- const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData);
- const doesTokenExist = erc721Wrapper.doesTokenExistAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- );
- if (!doesTokenExist && desiredBalance.eq(1)) {
- await erc721Wrapper.mintAsync(assetProxyData.tokenAddress, assetProxyData.tokenId, userAddress);
- return;
- } else if (!doesTokenExist && desiredBalance.eq(0)) {
- return; // noop
- }
- const tokenOwner = await erc721Wrapper.ownerOfAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- );
- if (userAddress !== tokenOwner && desiredBalance.eq(1)) {
- await erc721Wrapper.transferFromAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- tokenOwner,
- userAddress,
- );
- } else if (tokenOwner === userAddress && desiredBalance.eq(0)) {
- // Transfer token to someone else
- const userAddresses = await (erc721Wrapper as any)._web3Wrapper.getAvailableAddressesAsync();
- const nonOwner = _.find(userAddresses, a => a !== userAddress);
- await erc721Wrapper.transferFromAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- tokenOwner,
- nonOwner,
- );
- return;
- } else if (
- (userAddress !== tokenOwner && desiredBalance.eq(0)) ||
- (tokenOwner === userAddress && desiredBalance.eq(1))
- ) {
- return; // noop
- }
- break;
- }
- default:
- throw errorUtils.spawnSwitchErr('proxyId', proxyId);
- }
- }
- public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
- const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (proxyId) {
- case AssetProxyId.ERC20: {
- const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
- const allowance = await erc20Wrapper.getProxyAllowanceAsync(userAddress, assetData);
- return allowance;
- }
- case AssetProxyId.ERC721: {
- const assetWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
- const erc721ProxyData = assetDataUtils.decodeERC721AssetData(assetData);
- const isProxyApprovedForAll = await assetWrapper.isProxyApprovedForAllAsync(
- userAddress,
- erc721ProxyData.tokenAddress,
- );
- if (isProxyApprovedForAll) {
- return constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
- }
-
- const isProxyApproved = await assetWrapper.isProxyApprovedAsync(
- erc721ProxyData.tokenAddress,
- erc721ProxyData.tokenId,
- );
- const allowance = isProxyApproved ? new BigNumber(1) : new BigNumber(0);
- return allowance;
- }
- default:
- throw errorUtils.spawnSwitchErr('proxyId', proxyId);
- }
- }
- public async setProxyAllowanceAsync(
- userAddress: string,
- assetData: string,
- desiredAllowance: BigNumber,
- ): Promise<void> {
- const proxyId = assetDataUtils.decodeAssetProxyId(assetData);
- switch (proxyId) {
- case AssetProxyId.ERC20: {
- const erc20Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC20Wrapper;
- await erc20Wrapper.setAllowanceAsync(userAddress, assetData, desiredAllowance);
- return;
- }
- case AssetProxyId.ERC721: {
- if (
- !desiredAllowance.eq(0) &&
- !desiredAllowance.eq(1) &&
- !desiredAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)
- ) {
- throw new Error(
- `Allowance for ERC721 token can only be set to 0, 1 or 2^256-1. Got: ${desiredAllowance}`,
- );
- }
- const erc721Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper;
- const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData);
-
- const doesTokenExist = await erc721Wrapper.doesTokenExistAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- );
- if (!doesTokenExist) {
- throw new Error(
- `Cannot setProxyAllowance on non-existent token: ${assetProxyData.tokenAddress} ${
- assetProxyData.tokenId
- }`,
- );
- }
- const isProxyApprovedForAll = await erc721Wrapper.isProxyApprovedForAllAsync(
- userAddress,
- assetProxyData.tokenAddress,
- );
- if (!isProxyApprovedForAll && desiredAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
- const isApproved = true;
- await erc721Wrapper.approveProxyForAllAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- isApproved,
- );
- } else if (isProxyApprovedForAll && desiredAllowance.eq(0)) {
- const isApproved = false;
- await erc721Wrapper.approveProxyForAllAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- isApproved,
- );
- } else if (isProxyApprovedForAll && desiredAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
- return; // Noop
- }
-
- const isProxyApproved = await erc721Wrapper.isProxyApprovedAsync(
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- );
- if (!isProxyApproved && desiredAllowance.eq(1)) {
- await erc721Wrapper.approveProxyAsync(assetProxyData.tokenAddress, assetProxyData.tokenId);
- } else if (isProxyApproved && desiredAllowance.eq(0)) {
- // Remove approval
- await erc721Wrapper.approveAsync(
- constants.NULL_ADDRESS,
- assetProxyData.tokenAddress,
- assetProxyData.tokenId,
- );
- } else if (
- (!isProxyApproved && desiredAllowance.eq(0)) ||
- (isProxyApproved && desiredAllowance.eq(1))
- ) {
- return; // noop
- }
-
- break;
- }
- default:
- throw errorUtils.spawnSwitchErr('proxyId', proxyId);
- }
- }
-}
diff --git a/contracts/core/test/utils/erc20_wrapper.ts b/contracts/core/test/utils/erc20_wrapper.ts
deleted file mode 100644
index e5ab0e36c..000000000
--- a/contracts/core/test/utils/erc20_wrapper.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-import { constants, ERC20BalancesByOwner, txDefaults } from '@0x/contracts-test-utils';
-import { artifacts as tokensArtifacts, DummyERC20TokenContract } from '@0x/contracts-tokens';
-import { assetDataUtils } from '@0x/order-utils';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider } from 'ethereum-types';
-import * as _ from 'lodash';
-
-import { ERC20ProxyContract } from '../../generated-wrappers/erc20_proxy';
-import { artifacts } from '../../src/artifacts';
-
-export class ERC20Wrapper {
- private readonly _tokenOwnerAddresses: string[];
- private readonly _contractOwnerAddress: string;
- private readonly _web3Wrapper: Web3Wrapper;
- private readonly _provider: Provider;
- private readonly _dummyTokenContracts: DummyERC20TokenContract[];
- private _proxyContract?: ERC20ProxyContract;
- private _proxyIdIfExists?: string;
- /**
- * Instanitates an ERC20Wrapper
- * @param provider Web3 provider to use for all JSON RPC requests
- * @param tokenOwnerAddresses Addresses that we want to endow as owners for dummy ERC20 tokens
- * @param contractOwnerAddress Desired owner of the contract
- * Instance of ERC20Wrapper
- */
- constructor(provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
- this._dummyTokenContracts = [];
- this._web3Wrapper = new Web3Wrapper(provider);
- this._provider = provider;
- this._tokenOwnerAddresses = tokenOwnerAddresses;
- this._contractOwnerAddress = contractOwnerAddress;
- }
- public async deployDummyTokensAsync(
- numberToDeploy: number,
- decimals: BigNumber,
- ): Promise<DummyERC20TokenContract[]> {
- for (let i = 0; i < numberToDeploy; i++) {
- this._dummyTokenContracts.push(
- await DummyERC20TokenContract.deployFrom0xArtifactAsync(
- tokensArtifacts.DummyERC20Token,
- this._provider,
- txDefaults,
- constants.DUMMY_TOKEN_NAME,
- constants.DUMMY_TOKEN_SYMBOL,
- decimals,
- constants.DUMMY_TOKEN_TOTAL_SUPPLY,
- ),
- );
- }
- return this._dummyTokenContracts;
- }
- public async deployProxyAsync(): Promise<ERC20ProxyContract> {
- this._proxyContract = await ERC20ProxyContract.deployFrom0xArtifactAsync(
- artifacts.ERC20Proxy,
- this._provider,
- txDefaults,
- );
- this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
- return this._proxyContract;
- }
- public getProxyId(): string {
- this._validateProxyContractExistsOrThrow();
- return this._proxyIdIfExists as string;
- }
- public async setBalancesAndAllowancesAsync(): Promise<void> {
- this._validateDummyTokenContractsExistOrThrow();
- this._validateProxyContractExistsOrThrow();
- for (const dummyTokenContract of this._dummyTokenContracts) {
- for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await dummyTokenContract.setBalance.sendTransactionAsync(
- tokenOwnerAddress,
- constants.INITIAL_ERC20_BALANCE,
- { from: this._contractOwnerAddress },
- ),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await dummyTokenContract.approve.sendTransactionAsync(
- (this._proxyContract as ERC20ProxyContract).address,
- constants.INITIAL_ERC20_ALLOWANCE,
- { from: tokenOwnerAddress },
- ),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- }
- }
- public async getBalanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
- const tokenContract = this._getTokenContractFromAssetData(assetData);
- const balance = new BigNumber(await tokenContract.balanceOf.callAsync(userAddress));
- return balance;
- }
- public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(assetData);
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.setBalance.sendTransactionAsync(userAddress, amount, {
- from: this._contractOwnerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise<BigNumber> {
- const tokenContract = this._getTokenContractFromAssetData(assetData);
- const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
- const allowance = new BigNumber(await tokenContract.allowance.callAsync(userAddress, proxyAddress));
- return allowance;
- }
- public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(assetData);
- const proxyAddress = (this._proxyContract as ERC20ProxyContract).address;
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.approve.sendTransactionAsync(proxyAddress, amount, {
- from: userAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async getBalancesAsync(): Promise<ERC20BalancesByOwner> {
- this._validateDummyTokenContractsExistOrThrow();
- const balancesByOwner: ERC20BalancesByOwner = {};
- const balances: BigNumber[] = [];
- const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = [];
- for (const dummyTokenContract of this._dummyTokenContracts) {
- for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
- balances.push(await dummyTokenContract.balanceOf.callAsync(tokenOwnerAddress));
- balanceInfo.push({
- tokenOwnerAddress,
- tokenAddress: dummyTokenContract.address,
- });
- }
- }
- _.forEach(balances, (balance, balanceIndex) => {
- const tokenAddress = balanceInfo[balanceIndex].tokenAddress;
- const tokenOwnerAddress = balanceInfo[balanceIndex].tokenOwnerAddress;
- if (_.isUndefined(balancesByOwner[tokenOwnerAddress])) {
- balancesByOwner[tokenOwnerAddress] = {};
- }
- const wrappedBalance = new BigNumber(balance);
- balancesByOwner[tokenOwnerAddress][tokenAddress] = wrappedBalance;
- });
- return balancesByOwner;
- }
- public addDummyTokenContract(dummy: DummyERC20TokenContract): void {
- if (!_.isUndefined(this._dummyTokenContracts)) {
- this._dummyTokenContracts.push(dummy);
- }
- }
- public addTokenOwnerAddress(address: string): void {
- this._tokenOwnerAddresses.push(address);
- }
- public getTokenOwnerAddresses(): string[] {
- return this._tokenOwnerAddresses;
- }
- public getTokenAddresses(): string[] {
- const tokenAddresses = _.map(this._dummyTokenContracts, dummyTokenContract => dummyTokenContract.address);
- return tokenAddresses;
- }
- private _getTokenContractFromAssetData(assetData: string): DummyERC20TokenContract {
- const erc20ProxyData = assetDataUtils.decodeERC20AssetData(assetData);
- const tokenAddress = erc20ProxyData.tokenAddress;
- const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
- if (_.isUndefined(tokenContractIfExists)) {
- throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
- }
- return tokenContractIfExists;
- }
- private _validateDummyTokenContractsExistOrThrow(): void {
- if (_.isUndefined(this._dummyTokenContracts)) {
- throw new Error('Dummy ERC20 tokens not yet deployed, please call "deployDummyTokensAsync"');
- }
- }
- private _validateProxyContractExistsOrThrow(): void {
- if (_.isUndefined(this._proxyContract)) {
- throw new Error('ERC20 proxy contract not yet deployed, please call "deployProxyAsync"');
- }
- }
-}
diff --git a/contracts/core/test/utils/erc721_wrapper.ts b/contracts/core/test/utils/erc721_wrapper.ts
deleted file mode 100644
index 1f658ce86..000000000
--- a/contracts/core/test/utils/erc721_wrapper.ts
+++ /dev/null
@@ -1,236 +0,0 @@
-import { constants, ERC721TokenIdsByOwner, txDefaults } from '@0x/contracts-test-utils';
-import { artifacts as tokensArtifacts, DummyERC721TokenContract } from '@0x/contracts-tokens';
-import { generatePseudoRandomSalt } from '@0x/order-utils';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider } from 'ethereum-types';
-import * as _ from 'lodash';
-
-import { ERC721ProxyContract } from '../../generated-wrappers/erc721_proxy';
-import { artifacts } from '../../src/artifacts';
-
-export class ERC721Wrapper {
- private readonly _tokenOwnerAddresses: string[];
- private readonly _contractOwnerAddress: string;
- private readonly _web3Wrapper: Web3Wrapper;
- private readonly _provider: Provider;
- private readonly _dummyTokenContracts: DummyERC721TokenContract[];
- private _proxyContract?: ERC721ProxyContract;
- private _proxyIdIfExists?: string;
- private _initialTokenIdsByOwner: ERC721TokenIdsByOwner = {};
- constructor(provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
- this._web3Wrapper = new Web3Wrapper(provider);
- this._provider = provider;
- this._dummyTokenContracts = [];
- this._tokenOwnerAddresses = tokenOwnerAddresses;
- this._contractOwnerAddress = contractOwnerAddress;
- }
- public async deployDummyTokensAsync(): Promise<DummyERC721TokenContract[]> {
- // tslint:disable-next-line:no-unused-variable
- for (const i of _.times(constants.NUM_DUMMY_ERC721_TO_DEPLOY)) {
- this._dummyTokenContracts.push(
- await DummyERC721TokenContract.deployFrom0xArtifactAsync(
- tokensArtifacts.DummyERC721Token,
- this._provider,
- txDefaults,
- constants.DUMMY_TOKEN_NAME,
- constants.DUMMY_TOKEN_SYMBOL,
- ),
- );
- }
- return this._dummyTokenContracts;
- }
- public async deployProxyAsync(): Promise<ERC721ProxyContract> {
- this._proxyContract = await ERC721ProxyContract.deployFrom0xArtifactAsync(
- artifacts.ERC721Proxy,
- this._provider,
- txDefaults,
- );
- this._proxyIdIfExists = await this._proxyContract.getProxyId.callAsync();
- return this._proxyContract;
- }
- public getProxyId(): string {
- this._validateProxyContractExistsOrThrow();
- return this._proxyIdIfExists as string;
- }
- public async setBalancesAndAllowancesAsync(): Promise<void> {
- this._validateDummyTokenContractsExistOrThrow();
- this._validateProxyContractExistsOrThrow();
- this._initialTokenIdsByOwner = {};
- for (const dummyTokenContract of this._dummyTokenContracts) {
- for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
- // tslint:disable-next-line:no-unused-variable
- for (const i of _.times(constants.NUM_ERC721_TOKENS_TO_MINT)) {
- const tokenId = generatePseudoRandomSalt();
- await this.mintAsync(dummyTokenContract.address, tokenId, tokenOwnerAddress);
- if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress])) {
- this._initialTokenIdsByOwner[tokenOwnerAddress] = {
- [dummyTokenContract.address]: [],
- };
- }
- if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address])) {
- this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] = [];
- }
- this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address].push(tokenId);
-
- await this.approveProxyAsync(dummyTokenContract.address, tokenId);
- }
- }
- }
- }
- public async doesTokenExistAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const owner = await tokenContract.ownerOf.callAsync(tokenId);
- const doesExist = owner !== constants.NULL_ADDRESS;
- return doesExist;
- }
- public async approveProxyAsync(tokenAddress: string, tokenId: BigNumber): Promise<void> {
- const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
- await this.approveAsync(proxyAddress, tokenAddress, tokenId);
- }
- public async approveProxyForAllAsync(tokenAddress: string, tokenId: BigNumber, isApproved: boolean): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
- const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.setApprovalForAll.sendTransactionAsync(proxyAddress, isApproved, {
- from: tokenOwner,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async approveAsync(to: string, tokenAddress: string, tokenId: BigNumber): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const tokenOwner = await this.ownerOfAsync(tokenAddress, tokenId);
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.approve.sendTransactionAsync(to, tokenId, {
- from: tokenOwner,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async transferFromAsync(
- tokenAddress: string,
- tokenId: BigNumber,
- currentOwner: string,
- userAddress: string,
- ): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.transferFrom.sendTransactionAsync(currentOwner, userAddress, tokenId, {
- from: currentOwner,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async mintAsync(tokenAddress: string, tokenId: BigNumber, userAddress: string): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.mint.sendTransactionAsync(userAddress, tokenId, {
- from: this._contractOwnerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async burnAsync(tokenAddress: string, tokenId: BigNumber, owner: string): Promise<void> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- await this._web3Wrapper.awaitTransactionSuccessAsync(
- await tokenContract.burn.sendTransactionAsync(owner, tokenId, {
- from: this._contractOwnerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- }
- public async ownerOfAsync(tokenAddress: string, tokenId: BigNumber): Promise<string> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const owner = await tokenContract.ownerOf.callAsync(tokenId);
- return owner;
- }
- public async isOwnerAsync(userAddress: string, tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const tokenOwner = await tokenContract.ownerOf.callAsync(tokenId);
- const isOwner = tokenOwner === userAddress;
- return isOwner;
- }
- public async isProxyApprovedForAllAsync(userAddress: string, tokenAddress: string): Promise<boolean> {
- this._validateProxyContractExistsOrThrow();
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const operator = (this._proxyContract as ERC721ProxyContract).address;
- const didApproveAll = await tokenContract.isApprovedForAll.callAsync(userAddress, operator);
- return didApproveAll;
- }
- public async isProxyApprovedAsync(tokenAddress: string, tokenId: BigNumber): Promise<boolean> {
- this._validateProxyContractExistsOrThrow();
- const tokenContract = this._getTokenContractFromAssetData(tokenAddress);
- const approvedAddress = await tokenContract.getApproved.callAsync(tokenId);
- const proxyAddress = (this._proxyContract as ERC721ProxyContract).address;
- const isProxyAnApprovedOperator = approvedAddress === proxyAddress;
- return isProxyAnApprovedOperator;
- }
- public async getBalancesAsync(): Promise<ERC721TokenIdsByOwner> {
- this._validateDummyTokenContractsExistOrThrow();
- this._validateBalancesAndAllowancesSetOrThrow();
- const tokenIdsByOwner: ERC721TokenIdsByOwner = {};
- const tokenOwnerAddresses: string[] = [];
- const tokenInfo: Array<{ tokenId: BigNumber; tokenAddress: string }> = [];
- for (const dummyTokenContract of this._dummyTokenContracts) {
- for (const tokenOwnerAddress of this._tokenOwnerAddresses) {
- const initialTokenOwnerIds = this._initialTokenIdsByOwner[tokenOwnerAddress][
- dummyTokenContract.address
- ];
- for (const tokenId of initialTokenOwnerIds) {
- tokenOwnerAddresses.push(await dummyTokenContract.ownerOf.callAsync(tokenId));
- tokenInfo.push({
- tokenId,
- tokenAddress: dummyTokenContract.address,
- });
- }
- }
- }
- _.forEach(tokenOwnerAddresses, (tokenOwnerAddress, ownerIndex) => {
- const tokenAddress = tokenInfo[ownerIndex].tokenAddress;
- const tokenId = tokenInfo[ownerIndex].tokenId;
- if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress])) {
- tokenIdsByOwner[tokenOwnerAddress] = {
- [tokenAddress]: [],
- };
- }
- if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress][tokenAddress])) {
- tokenIdsByOwner[tokenOwnerAddress][tokenAddress] = [];
- }
- tokenIdsByOwner[tokenOwnerAddress][tokenAddress].push(tokenId);
- });
- return tokenIdsByOwner;
- }
- public getTokenOwnerAddresses(): string[] {
- return this._tokenOwnerAddresses;
- }
- public getTokenAddresses(): string[] {
- const tokenAddresses = _.map(this._dummyTokenContracts, dummyTokenContract => dummyTokenContract.address);
- return tokenAddresses;
- }
- private _getTokenContractFromAssetData(tokenAddress: string): DummyERC721TokenContract {
- const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress);
- if (_.isUndefined(tokenContractIfExists)) {
- throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`);
- }
- return tokenContractIfExists;
- }
- private _validateDummyTokenContractsExistOrThrow(): void {
- if (_.isUndefined(this._dummyTokenContracts)) {
- throw new Error('Dummy ERC721 tokens not yet deployed, please call "deployDummyTokensAsync"');
- }
- }
- private _validateProxyContractExistsOrThrow(): void {
- if (_.isUndefined(this._proxyContract)) {
- throw new Error('ERC721 proxy contract not yet deployed, please call "deployProxyAsync"');
- }
- }
- private _validateBalancesAndAllowancesSetOrThrow(): void {
- if (_.keys(this._initialTokenIdsByOwner).length === 0) {
- throw new Error(
- 'Dummy ERC721 balances and allowances not yet set, please call "setBalancesAndAllowancesAsync"',
- );
- }
- }
-}
diff --git a/contracts/core/test/utils/exchange_wrapper.ts b/contracts/core/test/utils/exchange_wrapper.ts
deleted file mode 100644
index 075d2cb96..000000000
--- a/contracts/core/test/utils/exchange_wrapper.ts
+++ /dev/null
@@ -1,281 +0,0 @@
-import {
- FillResults,
- formatters,
- LogDecoder,
- OrderInfo,
- orderUtils,
- SignedTransaction,
-} from '@0x/contracts-test-utils';
-import { artifacts as tokensArtifacts } from '@0x/contracts-tokens';
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
-
-import { ExchangeContract } from '../../generated-wrappers/exchange';
-import { artifacts } from '../../src/artifacts';
-
-export class ExchangeWrapper {
- private readonly _exchange: ExchangeContract;
- private readonly _web3Wrapper: Web3Wrapper;
- private readonly _logDecoder: LogDecoder;
- constructor(exchangeContract: ExchangeContract, provider: Provider) {
- this._exchange = exchangeContract;
- this._web3Wrapper = new Web3Wrapper(provider);
- this._logDecoder = new LogDecoder(this._web3Wrapper, { ...artifacts, ...tokensArtifacts });
- }
- public async fillOrderAsync(
- signedOrder: SignedOrder,
- from: string,
- opts: { takerAssetFillAmount?: BigNumber } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
- const txHash = await this._exchange.fillOrder.sendTransactionAsync(
- params.order,
- params.takerAssetFillAmount,
- params.signature,
- { from },
- );
- const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return txReceipt;
- }
- public async cancelOrderAsync(signedOrder: SignedOrder, from: string): Promise<TransactionReceiptWithDecodedLogs> {
- const params = orderUtils.createCancel(signedOrder);
- const txHash = await this._exchange.cancelOrder.sendTransactionAsync(params.order, { from });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async fillOrKillOrderAsync(
- signedOrder: SignedOrder,
- from: string,
- opts: { takerAssetFillAmount?: BigNumber } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
- const txHash = await this._exchange.fillOrKillOrder.sendTransactionAsync(
- params.order,
- params.takerAssetFillAmount,
- params.signature,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async fillOrderNoThrowAsync(
- signedOrder: SignedOrder,
- from: string,
- opts: { takerAssetFillAmount?: BigNumber; gas?: number } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
- const txHash = await this._exchange.fillOrderNoThrow.sendTransactionAsync(
- params.order,
- params.takerAssetFillAmount,
- params.signature,
- { from, gas: opts.gas },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async batchFillOrdersAsync(
- orders: SignedOrder[],
- from: string,
- opts: { takerAssetFillAmounts?: BigNumber[] } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
- const txHash = await this._exchange.batchFillOrders.sendTransactionAsync(
- params.orders,
- params.takerAssetFillAmounts,
- params.signatures,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async batchFillOrKillOrdersAsync(
- orders: SignedOrder[],
- from: string,
- opts: { takerAssetFillAmounts?: BigNumber[] } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
- const txHash = await this._exchange.batchFillOrKillOrders.sendTransactionAsync(
- params.orders,
- params.takerAssetFillAmounts,
- params.signatures,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async batchFillOrdersNoThrowAsync(
- orders: SignedOrder[],
- from: string,
- opts: { takerAssetFillAmounts?: BigNumber[]; gas?: number } = {},
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
- const txHash = await this._exchange.batchFillOrdersNoThrow.sendTransactionAsync(
- params.orders,
- params.takerAssetFillAmounts,
- params.signatures,
- { from, gas: opts.gas },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async marketSellOrdersAsync(
- orders: SignedOrder[],
- from: string,
- opts: { takerAssetFillAmount: BigNumber },
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount);
- const txHash = await this._exchange.marketSellOrders.sendTransactionAsync(
- params.orders,
- params.takerAssetFillAmount,
- params.signatures,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async marketSellOrdersNoThrowAsync(
- orders: SignedOrder[],
- from: string,
- opts: { takerAssetFillAmount: BigNumber; gas?: number },
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount);
- const txHash = await this._exchange.marketSellOrdersNoThrow.sendTransactionAsync(
- params.orders,
- params.takerAssetFillAmount,
- params.signatures,
- { from, gas: opts.gas },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async marketBuyOrdersAsync(
- orders: SignedOrder[],
- from: string,
- opts: { makerAssetFillAmount: BigNumber },
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount);
- const txHash = await this._exchange.marketBuyOrders.sendTransactionAsync(
- params.orders,
- params.makerAssetFillAmount,
- params.signatures,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async marketBuyOrdersNoThrowAsync(
- orders: SignedOrder[],
- from: string,
- opts: { makerAssetFillAmount: BigNumber; gas?: number },
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount);
- const txHash = await this._exchange.marketBuyOrdersNoThrow.sendTransactionAsync(
- params.orders,
- params.makerAssetFillAmount,
- params.signatures,
- { from, gas: opts.gas },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async batchCancelOrdersAsync(
- orders: SignedOrder[],
- from: string,
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = formatters.createBatchCancel(orders);
- const txHash = await this._exchange.batchCancelOrders.sendTransactionAsync(params.orders, { from });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async cancelOrdersUpToAsync(salt: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
- const txHash = await this._exchange.cancelOrdersUpTo.sendTransactionAsync(salt, { from });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async registerAssetProxyAsync(
- assetProxyAddress: string,
- from: string,
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const txHash = await this._exchange.registerAssetProxy.sendTransactionAsync(assetProxyAddress, { from });
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async executeTransactionAsync(
- signedTx: SignedTransaction,
- from: string,
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const txHash = await this._exchange.executeTransaction.sendTransactionAsync(
- signedTx.salt,
- signedTx.signerAddress,
- signedTx.data,
- signedTx.signature,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
- const filledAmount = await this._exchange.filled.callAsync(orderHashHex);
- return filledAmount;
- }
- public async isCancelledAsync(orderHashHex: string): Promise<boolean> {
- const isCancelled = await this._exchange.cancelled.callAsync(orderHashHex);
- return isCancelled;
- }
- public async getOrderEpochAsync(makerAddress: string, senderAddress: string): Promise<BigNumber> {
- const orderEpoch = await this._exchange.orderEpoch.callAsync(makerAddress, senderAddress);
- return orderEpoch;
- }
- public async getOrderInfoAsync(signedOrder: SignedOrder): Promise<OrderInfo> {
- const orderInfo = (await this._exchange.getOrderInfo.callAsync(signedOrder)) as OrderInfo;
- return orderInfo;
- }
- public async getOrdersInfoAsync(signedOrders: SignedOrder[]): Promise<OrderInfo[]> {
- const ordersInfo = (await this._exchange.getOrdersInfo.callAsync(signedOrders)) as OrderInfo[];
- return ordersInfo;
- }
- public async matchOrdersAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- from: string,
- ): Promise<TransactionReceiptWithDecodedLogs> {
- const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
- const txHash = await this._exchange.matchOrders.sendTransactionAsync(
- params.left,
- params.right,
- params.leftSignature,
- params.rightSignature,
- { from },
- );
- const tx = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
- return tx;
- }
- public async getFillOrderResultsAsync(
- signedOrder: SignedOrder,
- from: string,
- opts: { takerAssetFillAmount?: BigNumber } = {},
- ): Promise<FillResults> {
- const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
- const fillResults = await this._exchange.fillOrder.callAsync(
- params.order,
- params.takerAssetFillAmount,
- params.signature,
- { from },
- );
- return fillResults;
- }
- public abiEncodeFillOrder(signedOrder: SignedOrder, opts: { takerAssetFillAmount?: BigNumber } = {}): string {
- const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
- const data = this._exchange.fillOrder.getABIEncodedTransactionData(
- params.order,
- params.takerAssetFillAmount,
- params.signature,
- );
- return data;
- }
- public getExchangeAddress(): string {
- return this._exchange.address;
- }
-}
diff --git a/contracts/core/test/utils/fill_order_combinatorial_utils.ts b/contracts/core/test/utils/fill_order_combinatorial_utils.ts
deleted file mode 100644
index 5d0ea07a8..000000000
--- a/contracts/core/test/utils/fill_order_combinatorial_utils.ts
+++ /dev/null
@@ -1,928 +0,0 @@
-import { artifacts as libsArtifacts, TestLibsContract } from '@0x/contracts-libs';
-import {
- AllowanceAmountScenario,
- AssetDataScenario,
- BalanceAmountScenario,
- chaiSetup,
- constants,
- expectTransactionFailedAsync,
- ExpirationTimeSecondsScenario,
- FeeRecipientAddressScenario,
- FillScenario,
- OrderAssetAmountScenario,
- orderUtils,
- signingUtils,
- TakerAssetFillAmountScenario,
- TakerScenario,
- TraderStateScenario,
-} from '@0x/contracts-test-utils';
-import {
- assetDataUtils,
- BalanceAndProxyAllowanceLazyStore,
- ExchangeTransferSimulator,
- orderHashUtils,
- OrderStateUtils,
- OrderValidationUtils,
-} from '@0x/order-utils';
-import { AssetProxyId, RevertReason, SignatureType, SignedOrder } from '@0x/types';
-import { BigNumber, errorUtils, logUtils } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as chai from 'chai';
-import { LogWithDecodedArgs, Provider, TxData } from 'ethereum-types';
-import * as _ from 'lodash';
-import 'make-promises-safe';
-
-import { ExchangeContract, ExchangeFillEventArgs } from '../../generated-wrappers/exchange';
-import { artifacts } from '../../src/artifacts';
-
-import { AssetWrapper } from './asset_wrapper';
-import { ERC20Wrapper } from './erc20_wrapper';
-import { ERC721Wrapper } from './erc721_wrapper';
-import { ExchangeWrapper } from './exchange_wrapper';
-import { OrderFactoryFromScenario } from './order_factory_from_scenario';
-import { SimpleAssetBalanceAndProxyAllowanceFetcher } from './simple_asset_balance_and_proxy_allowance_fetcher';
-import { SimpleOrderFilledCancelledFetcher } from './simple_order_filled_cancelled_fetcher';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-/**
- * Instantiates a new instance of FillOrderCombinatorialUtils. Since this method has some
- * required async setup, a factory method is required.
- * @param web3Wrapper Web3Wrapper instance
- * @param txDefaults Default Ethereum tx options
- * @return FillOrderCombinatorialUtils instance
- */
-export async function fillOrderCombinatorialUtilsFactoryAsync(
- web3Wrapper: Web3Wrapper,
- txDefaults: Partial<TxData>,
-): Promise<FillOrderCombinatorialUtils> {
- const accounts = await web3Wrapper.getAvailableAddressesAsync();
- const userAddresses = _.slice(accounts, 0, 5);
- const [ownerAddress, makerAddress, takerAddress] = userAddresses;
- const makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[userAddresses.indexOf(makerAddress)];
-
- const provider = web3Wrapper.getProvider();
- const erc20Wrapper = new ERC20Wrapper(provider, userAddresses, ownerAddress);
- const erc721Wrapper = new ERC721Wrapper(provider, userAddresses, ownerAddress);
-
- const erc20EighteenDecimalTokenCount = 3;
- const eighteenDecimals = new BigNumber(18);
- const [
- erc20EighteenDecimalTokenA,
- erc20EighteenDecimalTokenB,
- zrxToken,
- ] = await erc20Wrapper.deployDummyTokensAsync(erc20EighteenDecimalTokenCount, eighteenDecimals);
- const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address);
-
- const erc20FiveDecimalTokenCount = 2;
- const fiveDecimals = new BigNumber(5);
- const [erc20FiveDecimalTokenA, erc20FiveDecimalTokenB] = await erc20Wrapper.deployDummyTokensAsync(
- erc20FiveDecimalTokenCount,
- fiveDecimals,
- );
- const zeroDecimals = new BigNumber(0);
- const erc20ZeroDecimalTokenCount = 2;
- const [erc20ZeroDecimalTokenA, erc20ZeroDecimalTokenB] = await erc20Wrapper.deployDummyTokensAsync(
- erc20ZeroDecimalTokenCount,
- zeroDecimals,
- );
- const erc20Proxy = await erc20Wrapper.deployProxyAsync();
- await erc20Wrapper.setBalancesAndAllowancesAsync();
-
- const [erc721Token] = await erc721Wrapper.deployDummyTokensAsync();
- const erc721Proxy = await erc721Wrapper.deployProxyAsync();
- await erc721Wrapper.setBalancesAndAllowancesAsync();
- const erc721Balances = await erc721Wrapper.getBalancesAsync();
-
- const assetWrapper = new AssetWrapper([erc20Wrapper, erc721Wrapper]);
-
- const exchangeContract = await ExchangeContract.deployFrom0xArtifactAsync(
- artifacts.Exchange,
- provider,
- txDefaults,
- zrxAssetData,
- );
- const exchangeWrapper = new ExchangeWrapper(exchangeContract, provider);
- await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, ownerAddress);
- await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, ownerAddress);
-
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc20Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeContract.address, {
- from: ownerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(
- await erc721Proxy.addAuthorizedAddress.sendTransactionAsync(exchangeContract.address, {
- from: ownerAddress,
- }),
- constants.AWAIT_TRANSACTION_MINED_MS,
- );
-
- const orderFactory = new OrderFactoryFromScenario(
- userAddresses,
- zrxToken.address,
- [erc20EighteenDecimalTokenA.address, erc20EighteenDecimalTokenB.address],
- [erc20FiveDecimalTokenA.address, erc20FiveDecimalTokenB.address],
- [erc20ZeroDecimalTokenA.address, erc20ZeroDecimalTokenB.address],
- erc721Token,
- erc721Balances,
- exchangeContract.address,
- );
-
- const testLibsContract = await TestLibsContract.deployFrom0xArtifactAsync(
- libsArtifacts.TestLibs,
- provider,
- txDefaults,
- );
-
- const fillOrderCombinatorialUtils = new FillOrderCombinatorialUtils(
- orderFactory,
- ownerAddress,
- makerAddress,
- makerPrivateKey,
- takerAddress,
- zrxAssetData,
- exchangeWrapper,
- assetWrapper,
- testLibsContract,
- );
- return fillOrderCombinatorialUtils;
-}
-
-export class FillOrderCombinatorialUtils {
- public orderFactory: OrderFactoryFromScenario;
- public ownerAddress: string;
- public makerAddress: string;
- public makerPrivateKey: Buffer;
- public takerAddress: string;
- public zrxAssetData: string;
- public exchangeWrapper: ExchangeWrapper;
- public assetWrapper: AssetWrapper;
- public testLibsContract: TestLibsContract;
- public static generateFillOrderCombinations(): FillScenario[] {
- const takerScenarios = [
- TakerScenario.Unspecified,
- // TakerScenario.CorrectlySpecified,
- // TakerScenario.IncorrectlySpecified,
- ];
- const feeRecipientScenarios = [
- FeeRecipientAddressScenario.EthUserAddress,
- // FeeRecipientAddressScenario.BurnAddress,
- ];
- const makerAssetAmountScenario = [
- OrderAssetAmountScenario.Large,
- // OrderAssetAmountScenario.Zero,
- // OrderAssetAmountScenario.Small,
- ];
- const takerAssetAmountScenario = [
- OrderAssetAmountScenario.Large,
- // OrderAssetAmountScenario.Zero,
- // OrderAssetAmountScenario.Small,
- ];
- const makerFeeScenario = [
- OrderAssetAmountScenario.Large,
- // OrderAssetAmountScenario.Small,
- // OrderAssetAmountScenario.Zero,
- ];
- const takerFeeScenario = [
- OrderAssetAmountScenario.Large,
- // OrderAssetAmountScenario.Small,
- // OrderAssetAmountScenario.Zero,
- ];
- const expirationTimeSecondsScenario = [
- ExpirationTimeSecondsScenario.InFuture,
- ExpirationTimeSecondsScenario.InPast,
- ];
- const makerAssetDataScenario = [
- AssetDataScenario.ERC20FiveDecimals,
- AssetDataScenario.ERC20NonZRXEighteenDecimals,
- AssetDataScenario.ERC721,
- AssetDataScenario.ZRXFeeToken,
- ];
- const takerAssetDataScenario = [
- AssetDataScenario.ERC20FiveDecimals,
- AssetDataScenario.ERC20NonZRXEighteenDecimals,
- AssetDataScenario.ERC721,
- AssetDataScenario.ZRXFeeToken,
- ];
- const takerAssetFillAmountScenario = [
- TakerAssetFillAmountScenario.ExactlyRemainingFillableTakerAssetAmount,
- // TakerAssetFillAmountScenario.GreaterThanRemainingFillableTakerAssetAmount,
- // TakerAssetFillAmountScenario.LessThanRemainingFillableTakerAssetAmount,
- ];
- const makerAssetBalanceScenario = [
- BalanceAmountScenario.Higher,
- // BalanceAmountScenario.Exact,
- // BalanceAmountScenario.TooLow,
- ];
- const makerAssetAllowanceScenario = [
- AllowanceAmountScenario.Higher,
- // AllowanceAmountScenario.Exact,
- // AllowanceAmountScenario.TooLow,
- // AllowanceAmountScenario.Unlimited,
- ];
- const makerZRXBalanceScenario = [
- BalanceAmountScenario.Higher,
- // BalanceAmountScenario.Exact,
- // BalanceAmountScenario.TooLow,
- ];
- const makerZRXAllowanceScenario = [
- AllowanceAmountScenario.Higher,
- // AllowanceAmountScenario.Exact,
- // AllowanceAmountScenario.TooLow,
- // AllowanceAmountScenario.Unlimited,
- ];
- const takerAssetBalanceScenario = [
- BalanceAmountScenario.Higher,
- // BalanceAmountScenario.Exact,
- // BalanceAmountScenario.TooLow,
- ];
- const takerAssetAllowanceScenario = [
- AllowanceAmountScenario.Higher,
- // AllowanceAmountScenario.Exact,
- // AllowanceAmountScenario.TooLow,
- // AllowanceAmountScenario.Unlimited,
- ];
- const takerZRXBalanceScenario = [
- BalanceAmountScenario.Higher,
- // BalanceAmountScenario.Exact,
- // BalanceAmountScenario.TooLow,
- ];
- const takerZRXAllowanceScenario = [
- AllowanceAmountScenario.Higher,
- // AllowanceAmountScenario.Exact,
- // AllowanceAmountScenario.TooLow,
- // AllowanceAmountScenario.Unlimited,
- ];
- const fillScenarioArrays = FillOrderCombinatorialUtils._getAllCombinations([
- takerScenarios,
- feeRecipientScenarios,
- makerAssetAmountScenario,
- takerAssetAmountScenario,
- makerFeeScenario,
- takerFeeScenario,
- expirationTimeSecondsScenario,
- makerAssetDataScenario,
- takerAssetDataScenario,
- takerAssetFillAmountScenario,
- makerAssetBalanceScenario,
- makerAssetAllowanceScenario,
- makerZRXBalanceScenario,
- makerZRXAllowanceScenario,
- takerAssetBalanceScenario,
- takerAssetAllowanceScenario,
- takerZRXBalanceScenario,
- takerZRXAllowanceScenario,
- ]);
-
- const fillScenarios = _.map(fillScenarioArrays, fillScenarioArray => {
- // tslint:disable:custom-no-magic-numbers
- const fillScenario: FillScenario = {
- orderScenario: {
- takerScenario: fillScenarioArray[0] as TakerScenario,
- feeRecipientScenario: fillScenarioArray[1] as FeeRecipientAddressScenario,
- makerAssetAmountScenario: fillScenarioArray[2] as OrderAssetAmountScenario,
- takerAssetAmountScenario: fillScenarioArray[3] as OrderAssetAmountScenario,
- makerFeeScenario: fillScenarioArray[4] as OrderAssetAmountScenario,
- takerFeeScenario: fillScenarioArray[5] as OrderAssetAmountScenario,
- expirationTimeSecondsScenario: fillScenarioArray[6] as ExpirationTimeSecondsScenario,
- makerAssetDataScenario: fillScenarioArray[7] as AssetDataScenario,
- takerAssetDataScenario: fillScenarioArray[8] as AssetDataScenario,
- },
- takerAssetFillAmountScenario: fillScenarioArray[9] as TakerAssetFillAmountScenario,
- makerStateScenario: {
- traderAssetBalance: fillScenarioArray[10] as BalanceAmountScenario,
- traderAssetAllowance: fillScenarioArray[11] as AllowanceAmountScenario,
- zrxFeeBalance: fillScenarioArray[12] as BalanceAmountScenario,
- zrxFeeAllowance: fillScenarioArray[13] as AllowanceAmountScenario,
- },
- takerStateScenario: {
- traderAssetBalance: fillScenarioArray[14] as BalanceAmountScenario,
- traderAssetAllowance: fillScenarioArray[15] as AllowanceAmountScenario,
- zrxFeeBalance: fillScenarioArray[16] as BalanceAmountScenario,
- zrxFeeAllowance: fillScenarioArray[17] as AllowanceAmountScenario,
- },
- };
- // tslint:enable:custom-no-magic-numbers
- return fillScenario;
- });
-
- return fillScenarios;
- }
- /**
- * Recursive implementation of generating all combinations of the supplied
- * string-containing arrays.
- */
- private static _getAllCombinations(arrays: string[][]): string[][] {
- // Base case
- if (arrays.length === 1) {
- const remainingValues = _.map(arrays[0], val => {
- return [val];
- });
- return remainingValues;
- } else {
- const result = [];
- const restOfArrays = arrays.slice(1);
- const allCombinationsOfRemaining = FillOrderCombinatorialUtils._getAllCombinations(restOfArrays); // recur with the rest of array
- // tslint:disable:prefer-for-of
- for (let i = 0; i < allCombinationsOfRemaining.length; i++) {
- for (let j = 0; j < arrays[0].length; j++) {
- result.push([arrays[0][j], ...allCombinationsOfRemaining[i]]);
- }
- }
- // tslint:enable:prefer-for-of
- return result;
- }
- }
- constructor(
- orderFactory: OrderFactoryFromScenario,
- ownerAddress: string,
- makerAddress: string,
- makerPrivateKey: Buffer,
- takerAddress: string,
- zrxAssetData: string,
- exchangeWrapper: ExchangeWrapper,
- assetWrapper: AssetWrapper,
- testLibsContract: TestLibsContract,
- ) {
- this.orderFactory = orderFactory;
- this.ownerAddress = ownerAddress;
- this.makerAddress = makerAddress;
- this.makerPrivateKey = makerPrivateKey;
- this.takerAddress = takerAddress;
- this.zrxAssetData = zrxAssetData;
- this.exchangeWrapper = exchangeWrapper;
- this.assetWrapper = assetWrapper;
- this.testLibsContract = testLibsContract;
- }
- public async testFillOrderScenarioAsync(
- provider: Provider,
- fillScenario: FillScenario,
- isVerbose: boolean = false,
- ): Promise<void> {
- // 1. Generate order
- const order = this.orderFactory.generateOrder(fillScenario.orderScenario);
-
- // 2. Sign order
- const orderHashBuff = orderHashUtils.getOrderHashBuffer(order);
- const signature = signingUtils.signMessage(orderHashBuff, this.makerPrivateKey, SignatureType.EthSign);
- const signedOrder = {
- ...order,
- signature: `0x${signature.toString('hex')}`,
- };
-
- const balanceAndProxyAllowanceFetcher = new SimpleAssetBalanceAndProxyAllowanceFetcher(this.assetWrapper);
- const orderFilledCancelledFetcher = new SimpleOrderFilledCancelledFetcher(
- this.exchangeWrapper,
- this.zrxAssetData,
- );
-
- // 3. Figure out fill amount
- const takerAssetFillAmount = await this._getTakerAssetFillAmountAsync(
- signedOrder,
- fillScenario.takerAssetFillAmountScenario,
- balanceAndProxyAllowanceFetcher,
- orderFilledCancelledFetcher,
- );
-
- // 4. Permutate the maker and taker balance/allowance scenarios
- await this._modifyTraderStateAsync(
- fillScenario.makerStateScenario,
- fillScenario.takerStateScenario,
- signedOrder,
- takerAssetFillAmount,
- );
-
- // 5. If I fill it by X, what are the resulting balances/allowances/filled amounts expected?
- const orderValidationUtils = new OrderValidationUtils(orderFilledCancelledFetcher, provider);
- const lazyStore = new BalanceAndProxyAllowanceLazyStore(balanceAndProxyAllowanceFetcher);
- const exchangeTransferSimulator = new ExchangeTransferSimulator(lazyStore);
-
- let fillRevertReasonIfExists;
- try {
- await orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
- exchangeTransferSimulator,
- provider,
- signedOrder,
- takerAssetFillAmount,
- this.takerAddress,
- this.zrxAssetData,
- );
- if (isVerbose) {
- logUtils.log(`Expecting fillOrder to succeed.`);
- }
- } catch (err) {
- fillRevertReasonIfExists = err.message;
- if (isVerbose) {
- logUtils.log(`Expecting fillOrder to fail with:`);
- logUtils.log(err);
- }
- }
-
- // 6. Fill the order
- await this._fillOrderAndAssertOutcomeAsync(
- signedOrder,
- takerAssetFillAmount,
- lazyStore,
- fillRevertReasonIfExists,
- );
-
- await this._abiEncodeFillOrderAndAssertOutcomeAsync(signedOrder, takerAssetFillAmount);
- }
- private async _fillOrderAndAssertOutcomeAsync(
- signedOrder: SignedOrder,
- takerAssetFillAmount: BigNumber,
- lazyStore: BalanceAndProxyAllowanceLazyStore,
- fillRevertReasonIfExists: RevertReason | undefined,
- ): Promise<void> {
- if (!_.isUndefined(fillRevertReasonIfExists)) {
- return expectTransactionFailedAsync(
- this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, { takerAssetFillAmount }),
- fillRevertReasonIfExists,
- );
- }
-
- const makerAddress = signedOrder.makerAddress;
- const makerAssetData = signedOrder.makerAssetData;
- const takerAssetData = signedOrder.takerAssetData;
- const feeRecipient = signedOrder.feeRecipientAddress;
-
- const expMakerAssetBalanceOfMaker = await lazyStore.getBalanceAsync(makerAssetData, makerAddress);
- const expMakerAssetAllowanceOfMaker = await lazyStore.getProxyAllowanceAsync(makerAssetData, makerAddress);
- const expTakerAssetBalanceOfMaker = await lazyStore.getBalanceAsync(takerAssetData, makerAddress);
- const expZRXAssetBalanceOfMaker = await lazyStore.getBalanceAsync(this.zrxAssetData, makerAddress);
- const expZRXAssetAllowanceOfMaker = await lazyStore.getProxyAllowanceAsync(this.zrxAssetData, makerAddress);
- const expTakerAssetBalanceOfTaker = await lazyStore.getBalanceAsync(takerAssetData, this.takerAddress);
- const expTakerAssetAllowanceOfTaker = await lazyStore.getProxyAllowanceAsync(takerAssetData, this.takerAddress);
- const expMakerAssetBalanceOfTaker = await lazyStore.getBalanceAsync(makerAssetData, this.takerAddress);
- const expZRXAssetBalanceOfTaker = await lazyStore.getBalanceAsync(this.zrxAssetData, this.takerAddress);
- const expZRXAssetAllowanceOfTaker = await lazyStore.getProxyAllowanceAsync(
- this.zrxAssetData,
- this.takerAddress,
- );
- const expZRXAssetBalanceOfFeeRecipient = await lazyStore.getBalanceAsync(this.zrxAssetData, feeRecipient);
-
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const alreadyFilledTakerAmount = await this.exchangeWrapper.getTakerAssetFilledAmountAsync(orderHash);
- const remainingTakerAmountToFill = signedOrder.takerAssetAmount.minus(alreadyFilledTakerAmount);
- const expFilledTakerAmount = takerAssetFillAmount.gt(remainingTakerAmountToFill)
- ? remainingTakerAmountToFill
- : alreadyFilledTakerAmount.add(takerAssetFillAmount);
-
- const expFilledMakerAmount = orderUtils.getPartialAmountFloor(
- expFilledTakerAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerAssetAmount,
- );
- const expMakerFeePaid = orderUtils.getPartialAmountFloor(
- expFilledTakerAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerFee,
- );
- const expTakerFeePaid = orderUtils.getPartialAmountFloor(
- expFilledTakerAmount,
- signedOrder.takerAssetAmount,
- signedOrder.takerFee,
- );
- const fillResults = await this.exchangeWrapper.getFillOrderResultsAsync(signedOrder, this.takerAddress, {
- takerAssetFillAmount,
- });
- expect(fillResults.takerAssetFilledAmount).to.be.bignumber.equal(
- expFilledTakerAmount,
- 'takerAssetFilledAmount',
- );
- expect(fillResults.makerAssetFilledAmount).to.be.bignumber.equal(
- expFilledMakerAmount,
- 'makerAssetFilledAmount',
- );
- expect(fillResults.takerFeePaid).to.be.bignumber.equal(expTakerFeePaid, 'takerFeePaid');
- expect(fillResults.makerFeePaid).to.be.bignumber.equal(expMakerFeePaid, 'makerFeePaid');
-
- // - Let's fill the order!
- const txReceipt = await this.exchangeWrapper.fillOrderAsync(signedOrder, this.takerAddress, {
- takerAssetFillAmount,
- });
-
- const actFilledTakerAmount = await this.exchangeWrapper.getTakerAssetFilledAmountAsync(orderHash);
- expect(actFilledTakerAmount).to.be.bignumber.equal(expFilledTakerAmount, 'filledTakerAmount');
-
- const exchangeLogs = _.filter(
- txReceipt.logs,
- txLog => txLog.address === this.exchangeWrapper.getExchangeAddress(),
- );
- expect(exchangeLogs.length).to.be.equal(1, 'logs length');
- // tslint:disable-next-line:no-unnecessary-type-assertion
- const log = txReceipt.logs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>;
- expect(log.args.makerAddress).to.be.equal(makerAddress, 'log.args.makerAddress');
- expect(log.args.takerAddress).to.be.equal(this.takerAddress, 'log.args.this.takerAddress');
- expect(log.args.feeRecipientAddress).to.be.equal(feeRecipient, 'log.args.feeRecipientAddress');
- expect(log.args.makerAssetFilledAmount).to.be.bignumber.equal(
- expFilledMakerAmount,
- 'log.args.makerAssetFilledAmount',
- );
- expect(log.args.takerAssetFilledAmount).to.be.bignumber.equal(
- expFilledTakerAmount,
- 'log.args.takerAssetFilledAmount',
- );
- expect(log.args.makerFeePaid).to.be.bignumber.equal(expMakerFeePaid, 'log.args.makerFeePaid');
- expect(log.args.takerFeePaid).to.be.bignumber.equal(expTakerFeePaid, 'logs.args.takerFeePaid');
- expect(log.args.orderHash).to.be.equal(orderHash, 'log.args.orderHash');
- expect(log.args.makerAssetData).to.be.equal(makerAssetData, 'log.args.makerAssetData');
- expect(log.args.takerAssetData).to.be.equal(takerAssetData, 'log.args.takerAssetData');
-
- const actMakerAssetBalanceOfMaker = await this.assetWrapper.getBalanceAsync(makerAddress, makerAssetData);
- expect(actMakerAssetBalanceOfMaker).to.be.bignumber.equal(
- expMakerAssetBalanceOfMaker,
- 'makerAssetBalanceOfMaker',
- );
-
- const actMakerAssetAllowanceOfMaker = await this.assetWrapper.getProxyAllowanceAsync(
- makerAddress,
- makerAssetData,
- );
- expect(actMakerAssetAllowanceOfMaker).to.be.bignumber.equal(
- expMakerAssetAllowanceOfMaker,
- 'makerAssetAllowanceOfMaker',
- );
-
- const actTakerAssetBalanceOfMaker = await this.assetWrapper.getBalanceAsync(makerAddress, takerAssetData);
- expect(actTakerAssetBalanceOfMaker).to.be.bignumber.equal(
- expTakerAssetBalanceOfMaker,
- 'takerAssetBalanceOfMaker',
- );
-
- const actZRXAssetBalanceOfMaker = await this.assetWrapper.getBalanceAsync(makerAddress, this.zrxAssetData);
- expect(actZRXAssetBalanceOfMaker).to.be.bignumber.equal(expZRXAssetBalanceOfMaker, 'ZRXAssetBalanceOfMaker');
-
- const actZRXAssetAllowanceOfMaker = await this.assetWrapper.getProxyAllowanceAsync(
- makerAddress,
- this.zrxAssetData,
- );
- expect(actZRXAssetAllowanceOfMaker).to.be.bignumber.equal(
- expZRXAssetAllowanceOfMaker,
- 'ZRXAssetAllowanceOfMaker',
- );
-
- const actTakerAssetBalanceOfTaker = await this.assetWrapper.getBalanceAsync(this.takerAddress, takerAssetData);
- expect(actTakerAssetBalanceOfTaker).to.be.bignumber.equal(
- expTakerAssetBalanceOfTaker,
- 'TakerAssetBalanceOfTaker',
- );
-
- const actTakerAssetAllowanceOfTaker = await this.assetWrapper.getProxyAllowanceAsync(
- this.takerAddress,
- takerAssetData,
- );
-
- expect(actTakerAssetAllowanceOfTaker).to.be.bignumber.equal(
- expTakerAssetAllowanceOfTaker,
- 'TakerAssetAllowanceOfTaker',
- );
-
- const actMakerAssetBalanceOfTaker = await this.assetWrapper.getBalanceAsync(this.takerAddress, makerAssetData);
- expect(actMakerAssetBalanceOfTaker).to.be.bignumber.equal(
- expMakerAssetBalanceOfTaker,
- 'MakerAssetBalanceOfTaker',
- );
-
- const actZRXAssetBalanceOfTaker = await this.assetWrapper.getBalanceAsync(this.takerAddress, this.zrxAssetData);
- expect(actZRXAssetBalanceOfTaker).to.be.bignumber.equal(expZRXAssetBalanceOfTaker, 'ZRXAssetBalanceOfTaker');
-
- const actZRXAssetAllowanceOfTaker = await this.assetWrapper.getProxyAllowanceAsync(
- this.takerAddress,
- this.zrxAssetData,
- );
- expect(actZRXAssetAllowanceOfTaker).to.be.bignumber.equal(
- expZRXAssetAllowanceOfTaker,
- 'ZRXAssetAllowanceOfTaker',
- );
-
- const actZRXAssetBalanceOfFeeRecipient = await this.assetWrapper.getBalanceAsync(
- feeRecipient,
- this.zrxAssetData,
- );
- expect(actZRXAssetBalanceOfFeeRecipient).to.be.bignumber.equal(
- expZRXAssetBalanceOfFeeRecipient,
- 'ZRXAssetBalanceOfFeeRecipient',
- );
- }
- private async _abiEncodeFillOrderAndAssertOutcomeAsync(
- signedOrder: SignedOrder,
- takerAssetFillAmount: BigNumber,
- ): Promise<void> {
- const params = orderUtils.createFill(signedOrder, takerAssetFillAmount);
- const expectedAbiEncodedData = this.exchangeWrapper.abiEncodeFillOrder(signedOrder, { takerAssetFillAmount });
- const libsAbiEncodedData = await this.testLibsContract.publicAbiEncodeFillOrder.callAsync(
- params.order,
- params.takerAssetFillAmount,
- params.signature,
- );
- expect(libsAbiEncodedData).to.be.equal(expectedAbiEncodedData, 'ABIEncodedFillOrderData');
- }
- private async _getTakerAssetFillAmountAsync(
- signedOrder: SignedOrder,
- takerAssetFillAmountScenario: TakerAssetFillAmountScenario,
- balanceAndProxyAllowanceFetcher: SimpleAssetBalanceAndProxyAllowanceFetcher,
- orderFilledCancelledFetcher: SimpleOrderFilledCancelledFetcher,
- ): Promise<BigNumber> {
- const orderStateUtils = new OrderStateUtils(balanceAndProxyAllowanceFetcher, orderFilledCancelledFetcher);
- const fillableTakerAssetAmount = await orderStateUtils.getMaxFillableTakerAssetAmountAsync(
- signedOrder,
- this.takerAddress,
- );
-
- let takerAssetFillAmount;
- switch (takerAssetFillAmountScenario) {
- case TakerAssetFillAmountScenario.Zero:
- takerAssetFillAmount = new BigNumber(0);
- break;
-
- case TakerAssetFillAmountScenario.ExactlyRemainingFillableTakerAssetAmount:
- takerAssetFillAmount = fillableTakerAssetAmount;
- break;
-
- case TakerAssetFillAmountScenario.GreaterThanRemainingFillableTakerAssetAmount:
- takerAssetFillAmount = fillableTakerAssetAmount.add(1);
- break;
-
- case TakerAssetFillAmountScenario.LessThanRemainingFillableTakerAssetAmount:
- const takerAssetProxyId = assetDataUtils.decodeAssetProxyId(signedOrder.takerAssetData);
- const makerAssetProxyId = assetDataUtils.decodeAssetProxyId(signedOrder.makerAssetData);
- const isEitherAssetERC721 =
- takerAssetProxyId === AssetProxyId.ERC721 || makerAssetProxyId === AssetProxyId.ERC721;
- if (isEitherAssetERC721) {
- throw new Error(
- 'Cannot test `TakerAssetFillAmountScenario.LessThanRemainingFillableTakerAssetAmount` together with ERC721 assets since orders involving ERC721 must always be filled exactly.',
- );
- }
- takerAssetFillAmount = fillableTakerAssetAmount.div(2).floor();
- break;
-
- default:
- throw errorUtils.spawnSwitchErr('TakerAssetFillAmountScenario', takerAssetFillAmountScenario);
- }
-
- return takerAssetFillAmount;
- }
- private async _modifyTraderStateAsync(
- makerStateScenario: TraderStateScenario,
- takerStateScenario: TraderStateScenario,
- signedOrder: SignedOrder,
- takerAssetFillAmount: BigNumber,
- ): Promise<void> {
- const makerAssetFillAmount = orderUtils.getPartialAmountFloor(
- takerAssetFillAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerAssetAmount,
- );
- switch (makerStateScenario.traderAssetBalance) {
- case BalanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case BalanceAmountScenario.TooLow:
- if (makerAssetFillAmount.eq(0)) {
- throw new Error(`Cannot set makerAssetBalanceOfMaker TooLow if makerAssetFillAmount is 0`);
- }
- const tooLowBalance = makerAssetFillAmount.minus(1);
- await this.assetWrapper.setBalanceAsync(
- signedOrder.makerAddress,
- signedOrder.makerAssetData,
- tooLowBalance,
- );
- break;
-
- case BalanceAmountScenario.Exact:
- const exactBalance = makerAssetFillAmount;
- await this.assetWrapper.setBalanceAsync(
- signedOrder.makerAddress,
- signedOrder.makerAssetData,
- exactBalance,
- );
- break;
-
- default:
- throw errorUtils.spawnSwitchErr(
- 'makerStateScenario.traderAssetBalance',
- makerStateScenario.traderAssetBalance,
- );
- }
-
- const makerFee = orderUtils.getPartialAmountFloor(
- takerAssetFillAmount,
- signedOrder.takerAssetAmount,
- signedOrder.makerFee,
- );
- switch (makerStateScenario.zrxFeeBalance) {
- case BalanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case BalanceAmountScenario.TooLow:
- if (makerFee.eq(0)) {
- throw new Error(`Cannot set zrxAsserBalanceOfMaker TooLow if makerFee is 0`);
- }
- const tooLowBalance = makerFee.minus(1);
- await this.assetWrapper.setBalanceAsync(signedOrder.makerAddress, this.zrxAssetData, tooLowBalance);
- break;
-
- case BalanceAmountScenario.Exact:
- const exactBalance = makerFee;
- await this.assetWrapper.setBalanceAsync(signedOrder.makerAddress, this.zrxAssetData, exactBalance);
- break;
-
- default:
- throw errorUtils.spawnSwitchErr('makerStateScenario.zrxFeeBalance', makerStateScenario.zrxFeeBalance);
- }
-
- switch (makerStateScenario.traderAssetAllowance) {
- case AllowanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case AllowanceAmountScenario.TooLow:
- const tooLowAllowance = makerAssetFillAmount.minus(1);
- await this.assetWrapper.setProxyAllowanceAsync(
- signedOrder.makerAddress,
- signedOrder.makerAssetData,
- tooLowAllowance,
- );
- break;
-
- case AllowanceAmountScenario.Exact:
- const exactAllowance = makerAssetFillAmount;
- await this.assetWrapper.setProxyAllowanceAsync(
- signedOrder.makerAddress,
- signedOrder.makerAssetData,
- exactAllowance,
- );
- break;
-
- case AllowanceAmountScenario.Unlimited:
- await this.assetWrapper.setProxyAllowanceAsync(
- signedOrder.makerAddress,
- signedOrder.makerAssetData,
- constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- );
- break;
-
- default:
- throw errorUtils.spawnSwitchErr(
- 'makerStateScenario.traderAssetAllowance',
- makerStateScenario.traderAssetAllowance,
- );
- }
-
- switch (makerStateScenario.zrxFeeAllowance) {
- case AllowanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case AllowanceAmountScenario.TooLow:
- const tooLowAllowance = makerFee.minus(1);
- await this.assetWrapper.setProxyAllowanceAsync(
- signedOrder.makerAddress,
- this.zrxAssetData,
- tooLowAllowance,
- );
- break;
-
- case AllowanceAmountScenario.Exact:
- const exactAllowance = makerFee;
- await this.assetWrapper.setProxyAllowanceAsync(
- signedOrder.makerAddress,
- this.zrxAssetData,
- exactAllowance,
- );
- break;
-
- case AllowanceAmountScenario.Unlimited:
- await this.assetWrapper.setProxyAllowanceAsync(
- signedOrder.makerAddress,
- this.zrxAssetData,
- constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- );
- break;
-
- default:
- throw errorUtils.spawnSwitchErr(
- 'makerStateScenario.zrxFeeAllowance',
- makerStateScenario.zrxFeeAllowance,
- );
- }
-
- switch (takerStateScenario.traderAssetBalance) {
- case BalanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case BalanceAmountScenario.TooLow:
- if (takerAssetFillAmount.eq(0)) {
- throw new Error(`Cannot set takerAssetBalanceOfTaker TooLow if takerAssetFillAmount is 0`);
- }
- const tooLowBalance = takerAssetFillAmount.minus(1);
- await this.assetWrapper.setBalanceAsync(this.takerAddress, signedOrder.takerAssetData, tooLowBalance);
- break;
-
- case BalanceAmountScenario.Exact:
- const exactBalance = takerAssetFillAmount;
- await this.assetWrapper.setBalanceAsync(this.takerAddress, signedOrder.takerAssetData, exactBalance);
- break;
-
- default:
- throw errorUtils.spawnSwitchErr(
- 'takerStateScenario.traderAssetBalance',
- takerStateScenario.traderAssetBalance,
- );
- }
-
- const takerFee = orderUtils.getPartialAmountFloor(
- takerAssetFillAmount,
- signedOrder.takerAssetAmount,
- signedOrder.takerFee,
- );
- switch (takerStateScenario.zrxFeeBalance) {
- case BalanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case BalanceAmountScenario.TooLow:
- if (takerFee.eq(0)) {
- throw new Error(`Cannot set zrxAssetBalanceOfTaker TooLow if takerFee is 0`);
- }
- const tooLowBalance = takerFee.minus(1);
- await this.assetWrapper.setBalanceAsync(this.takerAddress, this.zrxAssetData, tooLowBalance);
- break;
-
- case BalanceAmountScenario.Exact:
- const exactBalance = takerFee;
- await this.assetWrapper.setBalanceAsync(this.takerAddress, this.zrxAssetData, exactBalance);
- break;
-
- default:
- throw errorUtils.spawnSwitchErr('takerStateScenario.zrxFeeBalance', takerStateScenario.zrxFeeBalance);
- }
-
- switch (takerStateScenario.traderAssetAllowance) {
- case AllowanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case AllowanceAmountScenario.TooLow:
- const tooLowAllowance = takerAssetFillAmount.minus(1);
- await this.assetWrapper.setProxyAllowanceAsync(
- this.takerAddress,
- signedOrder.takerAssetData,
- tooLowAllowance,
- );
- break;
-
- case AllowanceAmountScenario.Exact:
- const exactAllowance = takerAssetFillAmount;
- await this.assetWrapper.setProxyAllowanceAsync(
- this.takerAddress,
- signedOrder.takerAssetData,
- exactAllowance,
- );
- break;
-
- case AllowanceAmountScenario.Unlimited:
- await this.assetWrapper.setProxyAllowanceAsync(
- this.takerAddress,
- signedOrder.takerAssetData,
- constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- );
- break;
-
- default:
- throw errorUtils.spawnSwitchErr(
- 'takerStateScenario.traderAssetAllowance',
- takerStateScenario.traderAssetAllowance,
- );
- }
-
- switch (takerStateScenario.zrxFeeAllowance) {
- case AllowanceAmountScenario.Higher:
- break; // Noop since this is already the default
-
- case AllowanceAmountScenario.TooLow:
- const tooLowAllowance = takerFee.minus(1);
- await this.assetWrapper.setProxyAllowanceAsync(this.takerAddress, this.zrxAssetData, tooLowAllowance);
- break;
-
- case AllowanceAmountScenario.Exact:
- const exactAllowance = takerFee;
- await this.assetWrapper.setProxyAllowanceAsync(this.takerAddress, this.zrxAssetData, exactAllowance);
- break;
-
- case AllowanceAmountScenario.Unlimited:
- await this.assetWrapper.setProxyAllowanceAsync(
- this.takerAddress,
- this.zrxAssetData,
- constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- );
- break;
-
- default:
- throw errorUtils.spawnSwitchErr(
- 'takerStateScenario.zrxFeeAllowance',
- takerStateScenario.zrxFeeAllowance,
- );
- }
- }
-} // tslint:disable:max-file-line-count
diff --git a/contracts/core/test/utils/index.ts b/contracts/core/test/utils/index.ts
deleted file mode 100644
index 75cd88666..000000000
--- a/contracts/core/test/utils/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './exchange_wrapper';
-export * from './erc20_wrapper';
-export * from './erc721_wrapper';
diff --git a/contracts/core/test/utils/match_order_tester.ts b/contracts/core/test/utils/match_order_tester.ts
deleted file mode 100644
index 8f574704e..000000000
--- a/contracts/core/test/utils/match_order_tester.ts
+++ /dev/null
@@ -1,562 +0,0 @@
-import {
- chaiSetup,
- ERC20BalancesByOwner,
- ERC721TokenIdsByOwner,
- OrderInfo,
- OrderStatus,
- TransferAmountsByMatchOrders as TransferAmounts,
- TransferAmountsLoggedByMatchOrders as LoggedTransferAmounts,
-} from '@0x/contracts-test-utils';
-import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
-import { AssetProxyId, SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import * as chai from 'chai';
-import * as _ from 'lodash';
-
-import { TransactionReceiptWithDecodedLogs } from '../../../../node_modules/ethereum-types';
-
-import { ERC20Wrapper } from './erc20_wrapper';
-import { ERC721Wrapper } from './erc721_wrapper';
-import { ExchangeWrapper } from './exchange_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-
-export class MatchOrderTester {
- private readonly _exchangeWrapper: ExchangeWrapper;
- private readonly _erc20Wrapper: ERC20Wrapper;
- private readonly _erc721Wrapper: ERC721Wrapper;
- private readonly _feeTokenAddress: string;
- /// @dev Checks values from the logs produced by Exchange.matchOrders against the expected transfer amounts.
- /// Values include the amounts transferred from the left/right makers and taker, along with
- /// the fees paid on each matched order. These are also the return values of MatchOrders.
- /// @param signedOrderLeft First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param transactionReceipt Transaction receipt and logs produced by Exchange.matchOrders.
- /// @param takerAddress Address of taker (account that called Exchange.matchOrders)
- /// @param expectedTransferAmounts Expected amounts transferred as a result of order matching.
- private static async _assertLogsAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- transactionReceipt: TransactionReceiptWithDecodedLogs,
- takerAddress: string,
- expectedTransferAmounts: TransferAmounts,
- ): Promise<void> {
- // Should have two fill event logs -- one for each order.
- const transactionFillLogs = _.filter(transactionReceipt.logs, ['event', 'Fill']);
- expect(transactionFillLogs.length, 'Checking number of logs').to.be.equal(2);
- // First log is for left fill
- const leftLog = (transactionFillLogs[0] as any).args as LoggedTransferAmounts;
- expect(leftLog.makerAddress, 'Checking logged maker address of left order').to.be.equal(
- signedOrderLeft.makerAddress,
- );
- expect(leftLog.takerAddress, 'Checking logged taker address of right order').to.be.equal(takerAddress);
- const amountBoughtByLeftMaker = new BigNumber(leftLog.takerAssetFilledAmount);
- const amountSoldByLeftMaker = new BigNumber(leftLog.makerAssetFilledAmount);
- const feePaidByLeftMaker = new BigNumber(leftLog.makerFeePaid);
- const feePaidByTakerLeft = new BigNumber(leftLog.takerFeePaid);
- // Second log is for right fill
- const rightLog = (transactionFillLogs[1] as any).args as LoggedTransferAmounts;
- expect(rightLog.makerAddress, 'Checking logged maker address of right order').to.be.equal(
- signedOrderRight.makerAddress,
- );
- expect(rightLog.takerAddress, 'Checking loggerd taker address of right order').to.be.equal(takerAddress);
- const amountBoughtByRightMaker = new BigNumber(rightLog.takerAssetFilledAmount);
- const amountSoldByRightMaker = new BigNumber(rightLog.makerAssetFilledAmount);
- const feePaidByRightMaker = new BigNumber(rightLog.makerFeePaid);
- const feePaidByTakerRight = new BigNumber(rightLog.takerFeePaid);
- // Derive amount received by taker
- const amountReceivedByTaker = amountSoldByLeftMaker.sub(amountBoughtByRightMaker);
- // Assert log values - left order
- expect(amountBoughtByLeftMaker, 'Checking logged amount bought by left maker').to.be.bignumber.equal(
- expectedTransferAmounts.amountBoughtByLeftMaker,
- );
- expect(amountSoldByLeftMaker, 'Checking logged amount sold by left maker').to.be.bignumber.equal(
- expectedTransferAmounts.amountSoldByLeftMaker,
- );
- expect(feePaidByLeftMaker, 'Checking logged fee paid by left maker').to.be.bignumber.equal(
- expectedTransferAmounts.feePaidByLeftMaker,
- );
- expect(feePaidByTakerLeft, 'Checking logged fee paid on left order by taker').to.be.bignumber.equal(
- expectedTransferAmounts.feePaidByTakerLeft,
- );
- // Assert log values - right order
- expect(amountBoughtByRightMaker, 'Checking logged amount bought by right maker').to.be.bignumber.equal(
- expectedTransferAmounts.amountBoughtByRightMaker,
- );
- expect(amountSoldByRightMaker, 'Checking logged amount sold by right maker').to.be.bignumber.equal(
- expectedTransferAmounts.amountSoldByRightMaker,
- );
- expect(feePaidByRightMaker, 'Checking logged fee paid by right maker').to.be.bignumber.equal(
- expectedTransferAmounts.feePaidByRightMaker,
- );
- expect(feePaidByTakerRight, 'Checking logged fee paid on right order by taker').to.be.bignumber.equal(
- expectedTransferAmounts.feePaidByTakerRight,
- );
- // Assert derived amount received by taker
- expect(amountReceivedByTaker, 'Checking logged amount received by taker').to.be.bignumber.equal(
- expectedTransferAmounts.amountReceivedByTaker,
- );
- }
- /// @dev Asserts all expected ERC20 and ERC721 account holdings match the real holdings.
- /// @param expectedERC20BalancesByOwner Expected ERC20 balances.
- /// @param realERC20BalancesByOwner Real ERC20 balances.
- /// @param expectedERC721TokenIdsByOwner Expected ERC721 token owners.
- /// @param realERC721TokenIdsByOwner Real ERC20 token owners.
- private static async _assertAllKnownBalancesAsync(
- expectedERC20BalancesByOwner: ERC20BalancesByOwner,
- realERC20BalancesByOwner: ERC20BalancesByOwner,
- expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner,
- realERC721TokenIdsByOwner: ERC721TokenIdsByOwner,
- ): Promise<void> {
- // ERC20 Balances
- const areERC20BalancesEqual = _.isEqual(expectedERC20BalancesByOwner, realERC20BalancesByOwner);
- expect(areERC20BalancesEqual, 'Checking all known ERC20 account balances').to.be.true();
- // ERC721 Token Ids
- const sortedExpectedNewERC721TokenIdsByOwner = _.mapValues(expectedERC721TokenIdsByOwner, tokenIdsByOwner => {
- _.mapValues(tokenIdsByOwner, tokenIds => {
- _.sortBy(tokenIds);
- });
- });
- const sortedNewERC721TokenIdsByOwner = _.mapValues(realERC721TokenIdsByOwner, tokenIdsByOwner => {
- _.mapValues(tokenIdsByOwner, tokenIds => {
- _.sortBy(tokenIds);
- });
- });
- const areERC721TokenIdsEqual = _.isEqual(
- sortedExpectedNewERC721TokenIdsByOwner,
- sortedNewERC721TokenIdsByOwner,
- );
- expect(areERC721TokenIdsEqual, 'Checking all known ERC721 account balances').to.be.true();
- }
- /// @dev Constructs new MatchOrderTester.
- /// @param exchangeWrapper Used to call to the Exchange.
- /// @param erc20Wrapper Used to fetch ERC20 balances.
- /// @param erc721Wrapper Used to fetch ERC721 token owners.
- /// @param feeTokenAddress Address of ERC20 fee token.
- constructor(
- exchangeWrapper: ExchangeWrapper,
- erc20Wrapper: ERC20Wrapper,
- erc721Wrapper: ERC721Wrapper,
- feeTokenAddress: string,
- ) {
- this._exchangeWrapper = exchangeWrapper;
- this._erc20Wrapper = erc20Wrapper;
- this._erc721Wrapper = erc721Wrapper;
- this._feeTokenAddress = feeTokenAddress;
- }
- /// @dev Matches two complementary orders and asserts results.
- /// @param signedOrderLeft First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param takerAddress Address of taker (the address who matched the two orders)
- /// @param erc20BalancesByOwner Current ERC20 balances.
- /// @param erc721TokenIdsByOwner Current ERC721 token owners.
- /// @param expectedTransferAmounts Expected amounts transferred as a result of order matching.
- /// @param initialLeftOrderFilledAmount How much left order has been filled, prior to matching orders.
- /// @param initialRightOrderFilledAmount How much the right order has been filled, prior to matching orders.
- /// @return New ERC20 balances & ERC721 token owners.
- public async matchOrdersAndAssertEffectsAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- takerAddress: string,
- erc20BalancesByOwner: ERC20BalancesByOwner,
- erc721TokenIdsByOwner: ERC721TokenIdsByOwner,
- expectedTransferAmounts: TransferAmounts,
- initialLeftOrderFilledAmount: BigNumber = new BigNumber(0),
- initialRightOrderFilledAmount: BigNumber = new BigNumber(0),
- ): Promise<[ERC20BalancesByOwner, ERC721TokenIdsByOwner]> {
- // Assert initial order states
- await this._assertInitialOrderStatesAsync(
- signedOrderLeft,
- signedOrderRight,
- initialLeftOrderFilledAmount,
- initialRightOrderFilledAmount,
- );
- // Match left & right orders
- const transactionReceipt = await this._exchangeWrapper.matchOrdersAsync(
- signedOrderLeft,
- signedOrderRight,
- takerAddress,
- );
- const newERC20BalancesByOwner = await this._erc20Wrapper.getBalancesAsync();
- const newERC721TokenIdsByOwner = await this._erc721Wrapper.getBalancesAsync();
- // Assert logs
- await MatchOrderTester._assertLogsAsync(
- signedOrderLeft,
- signedOrderRight,
- transactionReceipt,
- takerAddress,
- expectedTransferAmounts,
- );
- // Assert exchange state
- await this._assertExchangeStateAsync(
- signedOrderLeft,
- signedOrderRight,
- initialLeftOrderFilledAmount,
- initialRightOrderFilledAmount,
- expectedTransferAmounts,
- );
- // Assert balances of makers, taker, and fee recipients
- await this._assertBalancesAsync(
- signedOrderLeft,
- signedOrderRight,
- erc20BalancesByOwner,
- erc721TokenIdsByOwner,
- newERC20BalancesByOwner,
- newERC721TokenIdsByOwner,
- expectedTransferAmounts,
- takerAddress,
- );
- return [newERC20BalancesByOwner, newERC721TokenIdsByOwner];
- }
- /// @dev Asserts initial exchange state for the left and right orders.
- /// @param signedOrderLeft First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param expectedOrderFilledAmountLeft How much left order has been filled, prior to matching orders.
- /// @param expectedOrderFilledAmountRight How much the right order has been filled, prior to matching orders.
- private async _assertInitialOrderStatesAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- expectedOrderFilledAmountLeft: BigNumber,
- expectedOrderFilledAmountRight: BigNumber,
- ): Promise<void> {
- // Assert left order initial state
- const orderTakerAssetFilledAmountLeft = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderHashUtils.getOrderHashHex(signedOrderLeft),
- );
- expect(orderTakerAssetFilledAmountLeft, 'Checking inital state of left order').to.be.bignumber.equal(
- expectedOrderFilledAmountLeft,
- );
- // Assert right order initial state
- const orderTakerAssetFilledAmountRight = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderHashUtils.getOrderHashHex(signedOrderRight),
- );
- expect(orderTakerAssetFilledAmountRight, 'Checking inital state of right order').to.be.bignumber.equal(
- expectedOrderFilledAmountRight,
- );
- }
- /// @dev Asserts the exchange state against the expected amounts transferred by from matching orders.
- /// @param signedOrderLeft First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param initialLeftOrderFilledAmount How much left order has been filled, prior to matching orders.
- /// @param initialRightOrderFilledAmount How much the right order has been filled, prior to matching orders.
- /// @return TransferAmounts A struct containing the expected transfer amounts.
- private async _assertExchangeStateAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- initialLeftOrderFilledAmount: BigNumber,
- initialRightOrderFilledAmount: BigNumber,
- expectedTransferAmounts: TransferAmounts,
- ): Promise<void> {
- // Assert state for left order: amount bought by left maker
- let amountBoughtByLeftMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderHashUtils.getOrderHashHex(signedOrderLeft),
- );
- amountBoughtByLeftMaker = amountBoughtByLeftMaker.minus(initialLeftOrderFilledAmount);
- expect(amountBoughtByLeftMaker, 'Checking exchange state for left order').to.be.bignumber.equal(
- expectedTransferAmounts.amountBoughtByLeftMaker,
- );
- // Assert state for right order: amount bought by right maker
- let amountBoughtByRightMaker = await this._exchangeWrapper.getTakerAssetFilledAmountAsync(
- orderHashUtils.getOrderHashHex(signedOrderRight),
- );
- amountBoughtByRightMaker = amountBoughtByRightMaker.minus(initialRightOrderFilledAmount);
- expect(amountBoughtByRightMaker, 'Checking exchange state for right order').to.be.bignumber.equal(
- expectedTransferAmounts.amountBoughtByRightMaker,
- );
- // Assert left order status
- const maxAmountBoughtByLeftMaker = signedOrderLeft.takerAssetAmount.minus(initialLeftOrderFilledAmount);
- const leftOrderInfo: OrderInfo = await this._exchangeWrapper.getOrderInfoAsync(signedOrderLeft);
- const leftExpectedStatus = expectedTransferAmounts.amountBoughtByLeftMaker.equals(maxAmountBoughtByLeftMaker)
- ? OrderStatus.FULLY_FILLED
- : OrderStatus.FILLABLE;
- expect(leftOrderInfo.orderStatus, 'Checking exchange status for left order').to.be.equal(leftExpectedStatus);
- // Assert right order status
- const maxAmountBoughtByRightMaker = signedOrderRight.takerAssetAmount.minus(initialRightOrderFilledAmount);
- const rightOrderInfo: OrderInfo = await this._exchangeWrapper.getOrderInfoAsync(signedOrderRight);
- const rightExpectedStatus = expectedTransferAmounts.amountBoughtByRightMaker.equals(maxAmountBoughtByRightMaker)
- ? OrderStatus.FULLY_FILLED
- : OrderStatus.FILLABLE;
- expect(rightOrderInfo.orderStatus, 'Checking exchange status for right order').to.be.equal(rightExpectedStatus);
- }
- /// @dev Asserts account balances after matching orders.
- /// @param signedOrderLeft First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param initialERC20BalancesByOwner ERC20 balances prior to order matching.
- /// @param initialERC721TokenIdsByOwner ERC721 token owners prior to order matching.
- /// @param finalERC20BalancesByOwner ERC20 balances after order matching.
- /// @param finalERC721TokenIdsByOwner ERC721 token owners after order matching.
- /// @param expectedTransferAmounts Expected amounts transferred as a result of order matching.
- /// @param takerAddress Address of taker (account that called Exchange.matchOrders).
- private async _assertBalancesAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- initialERC20BalancesByOwner: ERC20BalancesByOwner,
- initialERC721TokenIdsByOwner: ERC721TokenIdsByOwner,
- finalERC20BalancesByOwner: ERC20BalancesByOwner,
- finalERC721TokenIdsByOwner: ERC721TokenIdsByOwner,
- expectedTransferAmounts: TransferAmounts,
- takerAddress: string,
- ): Promise<void> {
- let expectedERC20BalancesByOwner: ERC20BalancesByOwner;
- let expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner;
- [expectedERC20BalancesByOwner, expectedERC721TokenIdsByOwner] = this._calculateExpectedBalances(
- signedOrderLeft,
- signedOrderRight,
- takerAddress,
- initialERC20BalancesByOwner,
- initialERC721TokenIdsByOwner,
- expectedTransferAmounts,
- );
- // Assert balances of makers, taker, and fee recipients
- await this._assertMakerTakerAndFeeRecipientBalancesAsync(
- signedOrderLeft,
- signedOrderRight,
- expectedERC20BalancesByOwner,
- finalERC20BalancesByOwner,
- expectedERC721TokenIdsByOwner,
- finalERC721TokenIdsByOwner,
- takerAddress,
- );
- // Assert balances for all known accounts
- await MatchOrderTester._assertAllKnownBalancesAsync(
- expectedERC20BalancesByOwner,
- finalERC20BalancesByOwner,
- expectedERC721TokenIdsByOwner,
- finalERC721TokenIdsByOwner,
- );
- }
- /// @dev Calculates the expected balances of order makers, fee recipients, and the taker,
- /// as a result of matching two orders.
- /// @param signedOrderRight First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param takerAddress Address of taker (the address who matched the two orders)
- /// @param erc20BalancesByOwner Current ERC20 balances.
- /// @param erc721TokenIdsByOwner Current ERC721 token owners.
- /// @param expectedTransferAmounts Expected amounts transferred as a result of order matching.
- /// @return Expected ERC20 balances & ERC721 token owners after orders have been matched.
- private _calculateExpectedBalances(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- takerAddress: string,
- erc20BalancesByOwner: ERC20BalancesByOwner,
- erc721TokenIdsByOwner: ERC721TokenIdsByOwner,
- expectedTransferAmounts: TransferAmounts,
- ): [ERC20BalancesByOwner, ERC721TokenIdsByOwner] {
- const makerAddressLeft = signedOrderLeft.makerAddress;
- const makerAddressRight = signedOrderRight.makerAddress;
- const feeRecipientAddressLeft = signedOrderLeft.feeRecipientAddress;
- const feeRecipientAddressRight = signedOrderRight.feeRecipientAddress;
- // Operations are performed on copies of the balances
- const expectedNewERC20BalancesByOwner = _.cloneDeep(erc20BalancesByOwner);
- const expectedNewERC721TokenIdsByOwner = _.cloneDeep(erc721TokenIdsByOwner);
- // Left Maker Asset (Right Taker Asset)
- const makerAssetProxyIdLeft = assetDataUtils.decodeAssetProxyId(signedOrderLeft.makerAssetData);
- if (makerAssetProxyIdLeft === AssetProxyId.ERC20) {
- // Decode asset data
- const erc20AssetData = assetDataUtils.decodeERC20AssetData(signedOrderLeft.makerAssetData);
- const makerAssetAddressLeft = erc20AssetData.tokenAddress;
- const takerAssetAddressRight = makerAssetAddressLeft;
- // Left Maker
- expectedNewERC20BalancesByOwner[makerAddressLeft][makerAssetAddressLeft] = expectedNewERC20BalancesByOwner[
- makerAddressLeft
- ][makerAssetAddressLeft].minus(expectedTransferAmounts.amountSoldByLeftMaker);
- // Right Maker
- expectedNewERC20BalancesByOwner[makerAddressRight][
- takerAssetAddressRight
- ] = expectedNewERC20BalancesByOwner[makerAddressRight][takerAssetAddressRight].add(
- expectedTransferAmounts.amountBoughtByRightMaker,
- );
- // Taker
- expectedNewERC20BalancesByOwner[takerAddress][makerAssetAddressLeft] = expectedNewERC20BalancesByOwner[
- takerAddress
- ][makerAssetAddressLeft].add(expectedTransferAmounts.amountReceivedByTaker);
- } else if (makerAssetProxyIdLeft === AssetProxyId.ERC721) {
- // Decode asset data
- const erc721AssetData = assetDataUtils.decodeERC721AssetData(signedOrderLeft.makerAssetData);
- const makerAssetAddressLeft = erc721AssetData.tokenAddress;
- const makerAssetIdLeft = erc721AssetData.tokenId;
- const takerAssetAddressRight = makerAssetAddressLeft;
- const takerAssetIdRight = makerAssetIdLeft;
- // Left Maker
- _.remove(expectedNewERC721TokenIdsByOwner[makerAddressLeft][makerAssetAddressLeft], makerAssetIdLeft);
- // Right Maker
- expectedNewERC721TokenIdsByOwner[makerAddressRight][takerAssetAddressRight].push(takerAssetIdRight);
- // Taker: Since there is only 1 asset transferred, the taker does not receive any of the left maker asset.
- }
- // Left Taker Asset (Right Maker Asset)
- // Note: This exchange is only between the order makers: the Taker does not receive any of the left taker asset.
- const takerAssetProxyIdLeft = assetDataUtils.decodeAssetProxyId(signedOrderLeft.takerAssetData);
- if (takerAssetProxyIdLeft === AssetProxyId.ERC20) {
- // Decode asset data
- const erc20AssetData = assetDataUtils.decodeERC20AssetData(signedOrderLeft.takerAssetData);
- const takerAssetAddressLeft = erc20AssetData.tokenAddress;
- const makerAssetAddressRight = takerAssetAddressLeft;
- // Left Maker
- expectedNewERC20BalancesByOwner[makerAddressLeft][takerAssetAddressLeft] = expectedNewERC20BalancesByOwner[
- makerAddressLeft
- ][takerAssetAddressLeft].add(expectedTransferAmounts.amountBoughtByLeftMaker);
- // Right Maker
- expectedNewERC20BalancesByOwner[makerAddressRight][
- makerAssetAddressRight
- ] = expectedNewERC20BalancesByOwner[makerAddressRight][makerAssetAddressRight].minus(
- expectedTransferAmounts.amountSoldByRightMaker,
- );
- } else if (takerAssetProxyIdLeft === AssetProxyId.ERC721) {
- // Decode asset data
- const erc721AssetData = assetDataUtils.decodeERC721AssetData(signedOrderRight.makerAssetData);
- const makerAssetAddressRight = erc721AssetData.tokenAddress;
- const makerAssetIdRight = erc721AssetData.tokenId;
- const takerAssetAddressLeft = makerAssetAddressRight;
- const takerAssetIdLeft = makerAssetIdRight;
- // Right Maker
- _.remove(expectedNewERC721TokenIdsByOwner[makerAddressRight][makerAssetAddressRight], makerAssetIdRight);
- // Left Maker
- expectedNewERC721TokenIdsByOwner[makerAddressLeft][takerAssetAddressLeft].push(takerAssetIdLeft);
- }
- // Left Maker Fees
- expectedNewERC20BalancesByOwner[makerAddressLeft][this._feeTokenAddress] = expectedNewERC20BalancesByOwner[
- makerAddressLeft
- ][this._feeTokenAddress].minus(expectedTransferAmounts.feePaidByLeftMaker);
- // Right Maker Fees
- expectedNewERC20BalancesByOwner[makerAddressRight][this._feeTokenAddress] = expectedNewERC20BalancesByOwner[
- makerAddressRight
- ][this._feeTokenAddress].minus(expectedTransferAmounts.feePaidByRightMaker);
- // Taker Fees
- expectedNewERC20BalancesByOwner[takerAddress][this._feeTokenAddress] = expectedNewERC20BalancesByOwner[
- takerAddress
- ][this._feeTokenAddress].minus(
- expectedTransferAmounts.feePaidByTakerLeft.add(expectedTransferAmounts.feePaidByTakerRight),
- );
- // Left Fee Recipient Fees
- expectedNewERC20BalancesByOwner[feeRecipientAddressLeft][
- this._feeTokenAddress
- ] = expectedNewERC20BalancesByOwner[feeRecipientAddressLeft][this._feeTokenAddress].add(
- expectedTransferAmounts.feePaidByLeftMaker.add(expectedTransferAmounts.feePaidByTakerLeft),
- );
- // Right Fee Recipient Fees
- expectedNewERC20BalancesByOwner[feeRecipientAddressRight][
- this._feeTokenAddress
- ] = expectedNewERC20BalancesByOwner[feeRecipientAddressRight][this._feeTokenAddress].add(
- expectedTransferAmounts.feePaidByRightMaker.add(expectedTransferAmounts.feePaidByTakerRight),
- );
-
- return [expectedNewERC20BalancesByOwner, expectedNewERC721TokenIdsByOwner];
- }
- /// @dev Asserts ERC20 account balances and ERC721 token holdings that result from order matching.
- /// Specifically checks balances of makers, taker and fee recipients.
- /// @param signedOrderLeft First matched order.
- /// @param signedOrderRight Second matched order.
- /// @param expectedERC20BalancesByOwner Expected ERC20 balances.
- /// @param realERC20BalancesByOwner Real ERC20 balances.
- /// @param expectedERC721TokenIdsByOwner Expected ERC721 token owners.
- /// @param realERC721TokenIdsByOwner Real ERC20 token owners.
- /// @param takerAddress Address of taker (account that called Exchange.matchOrders).
- private async _assertMakerTakerAndFeeRecipientBalancesAsync(
- signedOrderLeft: SignedOrder,
- signedOrderRight: SignedOrder,
- expectedERC20BalancesByOwner: ERC20BalancesByOwner,
- realERC20BalancesByOwner: ERC20BalancesByOwner,
- expectedERC721TokenIdsByOwner: ERC721TokenIdsByOwner,
- realERC721TokenIdsByOwner: ERC721TokenIdsByOwner,
- takerAddress: string,
- ): Promise<void> {
- // Individual balance comparisons
- const makerAssetProxyIdLeft = assetDataUtils.decodeAssetProxyId(signedOrderLeft.makerAssetData);
- const makerERC20AssetDataLeft =
- makerAssetProxyIdLeft === AssetProxyId.ERC20
- ? assetDataUtils.decodeERC20AssetData(signedOrderLeft.makerAssetData)
- : assetDataUtils.decodeERC721AssetData(signedOrderLeft.makerAssetData);
- const makerAssetAddressLeft = makerERC20AssetDataLeft.tokenAddress;
- const makerAssetProxyIdRight = assetDataUtils.decodeAssetProxyId(signedOrderRight.makerAssetData);
- const makerERC20AssetDataRight =
- makerAssetProxyIdRight === AssetProxyId.ERC20
- ? assetDataUtils.decodeERC20AssetData(signedOrderRight.makerAssetData)
- : assetDataUtils.decodeERC721AssetData(signedOrderRight.makerAssetData);
- const makerAssetAddressRight = makerERC20AssetDataRight.tokenAddress;
- if (makerAssetProxyIdLeft === AssetProxyId.ERC20) {
- expect(
- realERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft],
- 'Checking left maker egress ERC20 account balance',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft]);
- expect(
- realERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft],
- 'Checking right maker ingress ERC20 account balance',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft]);
- expect(
- realERC20BalancesByOwner[takerAddress][makerAssetAddressLeft],
- 'Checking taker ingress ERC20 account balance',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[takerAddress][makerAssetAddressLeft]);
- } else if (makerAssetProxyIdLeft === AssetProxyId.ERC721) {
- expect(
- realERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft].sort(),
- 'Checking left maker egress ERC721 account holdings',
- ).to.be.deep.equal(
- expectedERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressLeft].sort(),
- );
- expect(
- realERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft].sort(),
- 'Checking right maker ERC721 account holdings',
- ).to.be.deep.equal(
- expectedERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressLeft].sort(),
- );
- expect(
- realERC721TokenIdsByOwner[takerAddress][makerAssetAddressLeft].sort(),
- 'Checking taker ingress ERC721 account holdings',
- ).to.be.deep.equal(expectedERC721TokenIdsByOwner[takerAddress][makerAssetAddressLeft].sort());
- } else {
- throw new Error(`Unhandled Asset Proxy ID: ${makerAssetProxyIdLeft}`);
- }
- if (makerAssetProxyIdRight === AssetProxyId.ERC20) {
- expect(
- realERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight],
- 'Checking left maker ingress ERC20 account balance',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight]);
- expect(
- realERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressRight],
- 'Checking right maker egress ERC20 account balance',
- ).to.be.bignumber.equal(
- expectedERC20BalancesByOwner[signedOrderRight.makerAddress][makerAssetAddressRight],
- );
- } else if (makerAssetProxyIdRight === AssetProxyId.ERC721) {
- expect(
- realERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight].sort(),
- 'Checking left maker ingress ERC721 account holdings',
- ).to.be.deep.equal(
- expectedERC721TokenIdsByOwner[signedOrderLeft.makerAddress][makerAssetAddressRight].sort(),
- );
- expect(
- realERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressRight],
- 'Checking right maker agress ERC721 account holdings',
- ).to.be.deep.equal(expectedERC721TokenIdsByOwner[signedOrderRight.makerAddress][makerAssetAddressRight]);
- } else {
- throw new Error(`Unhandled Asset Proxy ID: ${makerAssetProxyIdRight}`);
- }
- // Paid fees
- expect(
- realERC20BalancesByOwner[signedOrderLeft.makerAddress][this._feeTokenAddress],
- 'Checking left maker egress ERC20 account fees',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderLeft.makerAddress][this._feeTokenAddress]);
- expect(
- realERC20BalancesByOwner[signedOrderRight.makerAddress][this._feeTokenAddress],
- 'Checking right maker egress ERC20 account fees',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[signedOrderRight.makerAddress][this._feeTokenAddress]);
- expect(
- realERC20BalancesByOwner[takerAddress][this._feeTokenAddress],
- 'Checking taker egress ERC20 account fees',
- ).to.be.bignumber.equal(expectedERC20BalancesByOwner[takerAddress][this._feeTokenAddress]);
- // Received fees
- expect(
- realERC20BalancesByOwner[signedOrderLeft.feeRecipientAddress][this._feeTokenAddress],
- 'Checking left fee recipient ingress ERC20 account fees',
- ).to.be.bignumber.equal(
- expectedERC20BalancesByOwner[signedOrderLeft.feeRecipientAddress][this._feeTokenAddress],
- );
- expect(
- realERC20BalancesByOwner[signedOrderRight.feeRecipientAddress][this._feeTokenAddress],
- 'Checking right fee receipient ingress ERC20 account fees',
- ).to.be.bignumber.equal(
- expectedERC20BalancesByOwner[signedOrderRight.feeRecipientAddress][this._feeTokenAddress],
- );
- }
-} // tslint:disable-line:max-file-line-count
diff --git a/contracts/core/test/utils/order_factory_from_scenario.ts b/contracts/core/test/utils/order_factory_from_scenario.ts
deleted file mode 100644
index ecb4b2e28..000000000
--- a/contracts/core/test/utils/order_factory_from_scenario.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-import {
- AssetDataScenario,
- constants,
- ERC721TokenIdsByOwner,
- ExpirationTimeSecondsScenario,
- FeeRecipientAddressScenario,
- OrderAssetAmountScenario,
- OrderScenario,
- TakerScenario,
-} from '@0x/contracts-test-utils';
-import { DummyERC721TokenContract } from '@0x/contracts-tokens';
-import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils';
-import { Order } from '@0x/types';
-import { BigNumber, errorUtils } from '@0x/utils';
-
-const TEN_UNITS_EIGHTEEN_DECIMALS = new BigNumber(10_000_000_000_000_000_000);
-const FIVE_UNITS_EIGHTEEN_DECIMALS = new BigNumber(5_000_000_000_000_000_000);
-const POINT_ONE_UNITS_EIGHTEEN_DECIMALS = new BigNumber(100_000_000_000_000_000);
-const POINT_ZERO_FIVE_UNITS_EIGHTEEN_DECIMALS = new BigNumber(50_000_000_000_000_000);
-const TEN_UNITS_FIVE_DECIMALS = new BigNumber(1_000_000);
-const FIVE_UNITS_FIVE_DECIMALS = new BigNumber(500_000);
-const TEN_UNITS_ZERO_DECIMALS = new BigNumber(10);
-const ONE_THOUSAND_UNITS_ZERO_DECIMALS = new BigNumber(1000);
-const ONE_NFT_UNIT = new BigNumber(1);
-
-export class OrderFactoryFromScenario {
- private readonly _userAddresses: string[];
- private readonly _zrxAddress: string;
- private readonly _nonZrxERC20EighteenDecimalTokenAddresses: string[];
- private readonly _erc20FiveDecimalTokenAddresses: string[];
- private readonly _erc20ZeroDecimalTokenAddresses: string[];
- private readonly _erc721Token: DummyERC721TokenContract;
- private readonly _erc721Balances: ERC721TokenIdsByOwner;
- private readonly _exchangeAddress: string;
- constructor(
- userAddresses: string[],
- zrxAddress: string,
- nonZrxERC20EighteenDecimalTokenAddresses: string[],
- erc20FiveDecimalTokenAddresses: string[],
- erc20ZeroDecimalTokenAddresses: string[],
- erc721Token: DummyERC721TokenContract,
- erc721Balances: ERC721TokenIdsByOwner,
- exchangeAddress: string,
- ) {
- this._userAddresses = userAddresses;
- this._zrxAddress = zrxAddress;
- this._nonZrxERC20EighteenDecimalTokenAddresses = nonZrxERC20EighteenDecimalTokenAddresses;
- this._erc20FiveDecimalTokenAddresses = erc20FiveDecimalTokenAddresses;
- this._erc20ZeroDecimalTokenAddresses = erc20ZeroDecimalTokenAddresses;
- this._erc721Token = erc721Token;
- this._erc721Balances = erc721Balances;
- this._exchangeAddress = exchangeAddress;
- }
- public generateOrder(orderScenario: OrderScenario): Order {
- const makerAddress = this._userAddresses[1];
- let takerAddress = this._userAddresses[2];
- const erc721MakerAssetIds = this._erc721Balances[makerAddress][this._erc721Token.address];
- const erc721TakerAssetIds = this._erc721Balances[takerAddress][this._erc721Token.address];
- let feeRecipientAddress;
- let makerAssetAmount;
- let takerAssetAmount;
- let makerFee;
- let takerFee;
- let expirationTimeSeconds;
- let makerAssetData;
- let takerAssetData;
-
- switch (orderScenario.feeRecipientScenario) {
- case FeeRecipientAddressScenario.BurnAddress:
- feeRecipientAddress = constants.NULL_ADDRESS;
- break;
- case FeeRecipientAddressScenario.EthUserAddress:
- feeRecipientAddress = this._userAddresses[4];
- break;
- default:
- throw errorUtils.spawnSwitchErr('FeeRecipientAddressScenario', orderScenario.feeRecipientScenario);
- }
-
- switch (orderScenario.makerAssetDataScenario) {
- case AssetDataScenario.ZRXFeeToken:
- makerAssetData = assetDataUtils.encodeERC20AssetData(this._zrxAddress);
- break;
- case AssetDataScenario.ERC20NonZRXEighteenDecimals:
- makerAssetData = assetDataUtils.encodeERC20AssetData(this._nonZrxERC20EighteenDecimalTokenAddresses[0]);
- break;
- case AssetDataScenario.ERC20FiveDecimals:
- makerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20FiveDecimalTokenAddresses[0]);
- break;
- case AssetDataScenario.ERC721:
- makerAssetData = assetDataUtils.encodeERC721AssetData(
- this._erc721Token.address,
- erc721MakerAssetIds[0],
- );
- break;
- case AssetDataScenario.ERC20ZeroDecimals:
- makerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20ZeroDecimalTokenAddresses[0]);
- break;
- default:
- throw errorUtils.spawnSwitchErr('AssetDataScenario', orderScenario.makerAssetDataScenario);
- }
-
- switch (orderScenario.takerAssetDataScenario) {
- case AssetDataScenario.ZRXFeeToken:
- takerAssetData = assetDataUtils.encodeERC20AssetData(this._zrxAddress);
- break;
- case AssetDataScenario.ERC20NonZRXEighteenDecimals:
- takerAssetData = assetDataUtils.encodeERC20AssetData(this._nonZrxERC20EighteenDecimalTokenAddresses[1]);
- break;
- case AssetDataScenario.ERC20FiveDecimals:
- takerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20FiveDecimalTokenAddresses[1]);
- break;
- case AssetDataScenario.ERC721:
- takerAssetData = assetDataUtils.encodeERC721AssetData(
- this._erc721Token.address,
- erc721TakerAssetIds[0],
- );
- break;
- case AssetDataScenario.ERC20ZeroDecimals:
- takerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20ZeroDecimalTokenAddresses[1]);
- break;
- default:
- throw errorUtils.spawnSwitchErr('AssetDataScenario', orderScenario.takerAssetDataScenario);
- }
-
- switch (orderScenario.makerAssetAmountScenario) {
- case OrderAssetAmountScenario.Large:
- switch (orderScenario.makerAssetDataScenario) {
- case AssetDataScenario.ZRXFeeToken:
- case AssetDataScenario.ERC20NonZRXEighteenDecimals:
- makerAssetAmount = TEN_UNITS_EIGHTEEN_DECIMALS;
- break;
- case AssetDataScenario.ERC20FiveDecimals:
- makerAssetAmount = TEN_UNITS_FIVE_DECIMALS;
- break;
- case AssetDataScenario.ERC721:
- makerAssetAmount = ONE_NFT_UNIT;
- break;
- case AssetDataScenario.ERC20ZeroDecimals:
- makerAssetAmount = ONE_THOUSAND_UNITS_ZERO_DECIMALS;
- break;
- default:
- throw errorUtils.spawnSwitchErr('AssetDataScenario', orderScenario.makerAssetDataScenario);
- }
- break;
- case OrderAssetAmountScenario.Small:
- switch (orderScenario.makerAssetDataScenario) {
- case AssetDataScenario.ZRXFeeToken:
- case AssetDataScenario.ERC20NonZRXEighteenDecimals:
- makerAssetAmount = FIVE_UNITS_EIGHTEEN_DECIMALS;
- break;
- case AssetDataScenario.ERC20FiveDecimals:
- makerAssetAmount = FIVE_UNITS_FIVE_DECIMALS;
- break;
- case AssetDataScenario.ERC721:
- makerAssetAmount = ONE_NFT_UNIT;
- break;
- case AssetDataScenario.ERC20ZeroDecimals:
- makerAssetAmount = TEN_UNITS_ZERO_DECIMALS;
- break;
- default:
- throw errorUtils.spawnSwitchErr('AssetDataScenario', orderScenario.makerAssetDataScenario);
- }
- break;
- case OrderAssetAmountScenario.Zero:
- makerAssetAmount = new BigNumber(0);
- break;
- default:
- throw errorUtils.spawnSwitchErr('OrderAssetAmountScenario', orderScenario.makerAssetAmountScenario);
- }
-
- switch (orderScenario.takerAssetAmountScenario) {
- case OrderAssetAmountScenario.Large:
- switch (orderScenario.takerAssetDataScenario) {
- case AssetDataScenario.ERC20NonZRXEighteenDecimals:
- case AssetDataScenario.ZRXFeeToken:
- takerAssetAmount = TEN_UNITS_EIGHTEEN_DECIMALS;
- break;
- case AssetDataScenario.ERC20FiveDecimals:
- takerAssetAmount = TEN_UNITS_FIVE_DECIMALS;
- break;
- case AssetDataScenario.ERC721:
- takerAssetAmount = ONE_NFT_UNIT;
- break;
- case AssetDataScenario.ERC20ZeroDecimals:
- takerAssetAmount = ONE_THOUSAND_UNITS_ZERO_DECIMALS;
- break;
- default:
- throw errorUtils.spawnSwitchErr('AssetDataScenario', orderScenario.takerAssetDataScenario);
- }
- break;
- case OrderAssetAmountScenario.Small:
- switch (orderScenario.takerAssetDataScenario) {
- case AssetDataScenario.ERC20NonZRXEighteenDecimals:
- case AssetDataScenario.ZRXFeeToken:
- takerAssetAmount = FIVE_UNITS_EIGHTEEN_DECIMALS;
- break;
- case AssetDataScenario.ERC20FiveDecimals:
- takerAssetAmount = FIVE_UNITS_FIVE_DECIMALS;
- break;
- case AssetDataScenario.ERC721:
- takerAssetAmount = ONE_NFT_UNIT;
- break;
- case AssetDataScenario.ERC20ZeroDecimals:
- takerAssetAmount = TEN_UNITS_ZERO_DECIMALS;
- break;
- default:
- throw errorUtils.spawnSwitchErr('AssetDataScenario', orderScenario.takerAssetDataScenario);
- }
- break;
- case OrderAssetAmountScenario.Zero:
- takerAssetAmount = new BigNumber(0);
- break;
- default:
- throw errorUtils.spawnSwitchErr('OrderAssetAmountScenario', orderScenario.takerAssetAmountScenario);
- }
-
- switch (orderScenario.makerFeeScenario) {
- case OrderAssetAmountScenario.Large:
- makerFee = POINT_ONE_UNITS_EIGHTEEN_DECIMALS;
- break;
- case OrderAssetAmountScenario.Small:
- makerFee = POINT_ZERO_FIVE_UNITS_EIGHTEEN_DECIMALS;
- break;
- case OrderAssetAmountScenario.Zero:
- makerFee = new BigNumber(0);
- break;
- default:
- throw errorUtils.spawnSwitchErr('OrderAssetAmountScenario', orderScenario.makerFeeScenario);
- }
-
- switch (orderScenario.takerFeeScenario) {
- case OrderAssetAmountScenario.Large:
- takerFee = POINT_ONE_UNITS_EIGHTEEN_DECIMALS;
- break;
- case OrderAssetAmountScenario.Small:
- takerFee = POINT_ZERO_FIVE_UNITS_EIGHTEEN_DECIMALS;
- break;
- case OrderAssetAmountScenario.Zero:
- takerFee = new BigNumber(0);
- break;
- default:
- throw errorUtils.spawnSwitchErr('OrderAssetAmountScenario', orderScenario.takerFeeScenario);
- }
-
- switch (orderScenario.expirationTimeSecondsScenario) {
- case ExpirationTimeSecondsScenario.InFuture:
- expirationTimeSeconds = new BigNumber(2524604400); // Close to infinite
- break;
- case ExpirationTimeSecondsScenario.InPast:
- expirationTimeSeconds = new BigNumber(0); // Jan 1, 1970
- break;
- default:
- throw errorUtils.spawnSwitchErr(
- 'ExpirationTimeSecondsScenario',
- orderScenario.expirationTimeSecondsScenario,
- );
- }
-
- switch (orderScenario.takerScenario) {
- case TakerScenario.CorrectlySpecified:
- break; // noop since takerAddress is already specified
-
- case TakerScenario.IncorrectlySpecified:
- const notTaker = this._userAddresses[3];
- takerAddress = notTaker;
- break;
-
- case TakerScenario.Unspecified:
- takerAddress = constants.NULL_ADDRESS;
- break;
-
- default:
- throw errorUtils.spawnSwitchErr('TakerScenario', orderScenario.takerScenario);
- }
-
- const order = {
- senderAddress: constants.NULL_ADDRESS,
- makerAddress,
- takerAddress,
- makerFee,
- takerFee,
- makerAssetAmount,
- takerAssetAmount,
- makerAssetData,
- takerAssetData,
- salt: generatePseudoRandomSalt(),
- exchangeAddress: this._exchangeAddress,
- feeRecipientAddress,
- expirationTimeSeconds,
- };
-
- return order;
- }
-}
diff --git a/contracts/core/test/utils/simple_asset_balance_and_proxy_allowance_fetcher.ts b/contracts/core/test/utils/simple_asset_balance_and_proxy_allowance_fetcher.ts
deleted file mode 100644
index 64b7dedbe..000000000
--- a/contracts/core/test/utils/simple_asset_balance_and_proxy_allowance_fetcher.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { AbstractBalanceAndProxyAllowanceFetcher } from '@0x/order-utils';
-import { BigNumber } from '@0x/utils';
-
-import { AssetWrapper } from './asset_wrapper';
-
-export class SimpleAssetBalanceAndProxyAllowanceFetcher implements AbstractBalanceAndProxyAllowanceFetcher {
- private readonly _assetWrapper: AssetWrapper;
- constructor(assetWrapper: AssetWrapper) {
- this._assetWrapper = assetWrapper;
- }
- public async getBalanceAsync(assetData: string, userAddress: string): Promise<BigNumber> {
- const balance = await this._assetWrapper.getBalanceAsync(userAddress, assetData);
- return balance;
- }
- public async getProxyAllowanceAsync(assetData: string, userAddress: string): Promise<BigNumber> {
- const proxyAllowance = await this._assetWrapper.getProxyAllowanceAsync(userAddress, assetData);
- return proxyAllowance;
- }
-}
diff --git a/contracts/core/test/utils/simple_order_filled_cancelled_fetcher.ts b/contracts/core/test/utils/simple_order_filled_cancelled_fetcher.ts
deleted file mode 100644
index af959e00e..000000000
--- a/contracts/core/test/utils/simple_order_filled_cancelled_fetcher.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { AbstractOrderFilledCancelledFetcher, orderHashUtils } from '@0x/order-utils';
-import { SignedOrder } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-
-import { ExchangeWrapper } from './exchange_wrapper';
-
-export class SimpleOrderFilledCancelledFetcher implements AbstractOrderFilledCancelledFetcher {
- private readonly _exchangeWrapper: ExchangeWrapper;
- private readonly _zrxAssetData: string;
- constructor(exchange: ExchangeWrapper, zrxAssetData: string) {
- this._exchangeWrapper = exchange;
- this._zrxAssetData = zrxAssetData;
- }
- public async getFilledTakerAmountAsync(orderHash: string): Promise<BigNumber> {
- const filledTakerAmount = new BigNumber(await this._exchangeWrapper.getTakerAssetFilledAmountAsync(orderHash));
- return filledTakerAmount;
- }
- public async isOrderCancelledAsync(signedOrder: SignedOrder): Promise<boolean> {
- const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
- const isCancelled = await this._exchangeWrapper.isCancelledAsync(orderHash);
- const orderEpoch = await this._exchangeWrapper.getOrderEpochAsync(
- signedOrder.makerAddress,
- signedOrder.senderAddress,
- );
- const isCancelledByOrderEpoch = orderEpoch > signedOrder.salt;
- return isCancelled || isCancelledByOrderEpoch;
- }
- public getZRXAssetData(): string {
- return this._zrxAssetData;
- }
-}