aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contract-wrappers/test
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contract-wrappers/test')
-rw-r--r--packages/contract-wrappers/test/artifacts_test.ts25
-rw-r--r--packages/contract-wrappers/test/erc20_proxy_wrapper_test.ts (renamed from packages/contract-wrappers/test/token_transfer_proxy_wrapper_test.ts)8
-rw-r--r--packages/contract-wrappers/test/erc20_wrapper_test.ts (renamed from packages/contract-wrappers/test/token_wrapper_test.ts)320
-rw-r--r--packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts35
-rw-r--r--packages/contract-wrappers/test/erc721_wrapper_test.ts472
-rw-r--r--packages/contract-wrappers/test/ether_token_wrapper_test.ts129
-rw-r--r--packages/contract-wrappers/test/exchange_transfer_simulator_test.ts124
-rw-r--r--packages/contract-wrappers/test/exchange_wrapper_test.ts1338
-rw-r--r--packages/contract-wrappers/test/global_hooks.ts6
-rw-r--r--packages/contract-wrappers/test/order_validation_test.ts539
-rw-r--r--packages/contract-wrappers/test/subscription_test.ts41
-rw-r--r--packages/contract-wrappers/test/token_registry_wrapper_test.ts136
-rw-r--r--packages/contract-wrappers/test/utils/constants.ts9
-rw-r--r--packages/contract-wrappers/test/utils/token_utils.ts74
-rw-r--r--packages/contract-wrappers/test/utils/web3_wrapper.ts10
15 files changed, 1184 insertions, 2082 deletions
diff --git a/packages/contract-wrappers/test/artifacts_test.ts b/packages/contract-wrappers/test/artifacts_test.ts
index 39801df35..c05d513b3 100644
--- a/packages/contract-wrappers/test/artifacts_test.ts
+++ b/packages/contract-wrappers/test/artifacts_test.ts
@@ -10,7 +10,8 @@ chaiSetup.configure();
// Those tests are slower cause they're talking to a remote node
const TIMEOUT = 10000;
-describe('Artifacts', () => {
+// TODO: Re-enable those tests after final kovan and ropsten deployments are done.
+describe.skip('Artifacts', () => {
describe('contracts are deployed on kovan', () => {
const kovanRpcUrl = constants.KOVAN_RPC_URL;
const provider = web3Factory.getRpcProvider({ rpcUrl: kovanRpcUrl });
@@ -18,14 +19,11 @@ describe('Artifacts', () => {
networkId: constants.KOVAN_NETWORK_ID,
};
const contractWrappers = new ContractWrappers(provider, config);
- it('token registry contract is deployed', async () => {
- await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync();
+ it('erc20 proxy contract is deployed', async () => {
+ await (contractWrappers.erc20Proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
- it('proxy contract is deployed', async () => {
- await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync();
- }).timeout(TIMEOUT);
- it('exchange contract is deployed', async () => {
- await (contractWrappers.exchange as any)._getExchangeContractAsync();
+ it('erc721 proxy contract is deployed', async () => {
+ await (contractWrappers.erc721Proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
});
describe('contracts are deployed on ropsten', () => {
@@ -35,14 +33,11 @@ describe('Artifacts', () => {
networkId: constants.ROPSTEN_NETWORK_ID,
};
const contractWrappers = new ContractWrappers(provider, config);
- it('token registry contract is deployed', async () => {
- await (contractWrappers.tokenRegistry as any)._getTokenRegistryContractAsync();
- }).timeout(TIMEOUT);
- it('proxy contract is deployed', async () => {
- await (contractWrappers.proxy as any)._getTokenTransferProxyContractAsync();
+ it('erc20 proxy contract is deployed', async () => {
+ await (contractWrappers.erc20Proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
- it('exchange contract is deployed', async () => {
- await (contractWrappers.exchange as any)._getExchangeContractAsync();
+ it('erc721 proxy contract is deployed', async () => {
+ await (contractWrappers.erc721Proxy as any)._getTokenTransferProxyContractAsync();
}).timeout(TIMEOUT);
});
});
diff --git a/packages/contract-wrappers/test/token_transfer_proxy_wrapper_test.ts b/packages/contract-wrappers/test/erc20_proxy_wrapper_test.ts
index 0b66985aa..6bf9f1e25 100644
--- a/packages/contract-wrappers/test/token_transfer_proxy_wrapper_test.ts
+++ b/packages/contract-wrappers/test/erc20_proxy_wrapper_test.ts
@@ -9,7 +9,7 @@ import { provider } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
-describe('TokenTransferProxyWrapper', () => {
+describe('ERC20ProxyWrapper', () => {
let contractWrappers: ContractWrappers;
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
@@ -19,15 +19,15 @@ describe('TokenTransferProxyWrapper', () => {
});
describe('#isAuthorizedAsync', () => {
it('should return false if the address is not authorized', async () => {
- const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
+ const isAuthorized = await contractWrappers.erc20Proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
expect(isAuthorized).to.be.false();
});
});
describe('#getAuthorizedAddressesAsync', () => {
it('should return the list of authorized addresses', async () => {
- const authorizedAddresses = await contractWrappers.proxy.getAuthorizedAddressesAsync();
+ const authorizedAddresses = await contractWrappers.erc20Proxy.getAuthorizedAddressesAsync();
for (const authorizedAddress of authorizedAddresses) {
- const isAuthorized = await contractWrappers.proxy.isAuthorizedAsync(authorizedAddress);
+ const isAuthorized = await contractWrappers.erc20Proxy.isAuthorizedAsync(authorizedAddress);
expect(isAuthorized).to.be.true();
}
});
diff --git a/packages/contract-wrappers/test/token_wrapper_test.ts b/packages/contract-wrappers/test/erc20_wrapper_test.ts
index 86b93b3f9..0011508e0 100644
--- a/packages/contract-wrappers/test/token_wrapper_test.ts
+++ b/packages/contract-wrappers/test/erc20_wrapper_test.ts
@@ -1,37 +1,36 @@
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
import { EmptyWalletSubprovider } from '@0xproject/subproviders';
-import { DoneCallback, Provider } from '@0xproject/types';
+import { DoneCallback } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import * as chai from 'chai';
+import { Provider } from 'ethereum-types';
import 'mocha';
import Web3ProviderEngine = require('web3-provider-engine');
import {
- ApprovalContractEventArgs,
BlockParamLiteral,
BlockRange,
ContractWrappers,
ContractWrappersError,
DecodedLogEvent,
- Token,
- TokenEvents,
- TransferContractEventArgs,
+ ERC20TokenApprovalEventArgs,
+ ERC20TokenEvents,
+ ERC20TokenTransferEventArgs,
} from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
-import { TokenUtils } from './utils/token_utils';
+import { tokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-describe('TokenWrapper', () => {
+describe('ERC20Wrapper', () => {
let contractWrappers: ContractWrappers;
let userAddresses: string[];
- let tokens: Token[];
- let tokenUtils: TokenUtils;
+ let tokens: string[];
let coinbase: string;
let addressWithoutFunds: string;
const config = {
@@ -40,8 +39,7 @@ describe('TokenWrapper', () => {
before(async () => {
contractWrappers = new ContractWrappers(provider, config);
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- tokenUtils = new TokenUtils(tokens);
+ tokens = tokenUtils.getDummyERC20TokenAddresses();
coinbase = userAddresses[0];
addressWithoutFunds = userAddresses[1];
});
@@ -52,26 +50,26 @@ describe('TokenWrapper', () => {
await blockchainLifecycle.revertAsync();
});
describe('#transferAsync', () => {
- let token: Token;
+ let tokenAddress: string;
let transferAmount: BigNumber;
before(() => {
- token = tokens[0];
+ tokenAddress = tokens[0];
transferAmount = new BigNumber(42);
});
it('should successfully transfer tokens', async () => {
const fromAddress = coinbase;
const toAddress = addressWithoutFunds;
- const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
+ const preBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
expect(preBalance).to.be.bignumber.equal(0);
- await contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount);
- const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
+ await contractWrappers.erc20Token.transferAsync(tokenAddress, fromAddress, toAddress, transferAmount);
+ const postBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
return expect(postBalance).to.be.bignumber.equal(transferAmount);
});
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
const fromAddress = addressWithoutFunds;
const toAddress = coinbase;
return expect(
- contractWrappers.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
+ contractWrappers.erc20Token.transferAsync(tokenAddress, fromAddress, toAddress, transferAmount),
).to.be.rejectedWith(ContractWrappersError.InsufficientBalanceForTransfer);
});
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
@@ -79,16 +77,21 @@ describe('TokenWrapper', () => {
const fromAddress = coinbase;
const toAddress = coinbase;
return expect(
- contractWrappers.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
- ).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
+ contractWrappers.erc20Token.transferAsync(
+ nonExistentTokenAddress,
+ fromAddress,
+ toAddress,
+ transferAmount,
+ ),
+ ).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist);
});
});
describe('#transferFromAsync', () => {
- let token: Token;
+ let tokenAddress: string;
let toAddress: string;
let senderAddress: string;
before(async () => {
- token = tokens[0];
+ tokenAddress = tokens[0];
toAddress = addressWithoutFunds;
senderAddress = userAddresses[2];
});
@@ -96,19 +99,19 @@ describe('TokenWrapper', () => {
const fromAddress = coinbase;
const transferAmount = new BigNumber(42);
- const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress);
+ const fromAddressBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, fromAddress);
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
- const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ const fromAddressAllowance = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
fromAddress,
toAddress,
);
expect(fromAddressAllowance).to.be.bignumber.equal(0);
return expect(
- contractWrappers.token.transferFromAsync(
- token.address,
+ contractWrappers.erc20Token.transferFromAsync(
+ tokenAddress,
fromAddress,
toAddress,
senderAddress,
@@ -120,11 +123,11 @@ describe('TokenWrapper', () => {
const fromAddress = coinbase;
const transferAmount = new BigNumber(42);
- await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
+ await contractWrappers.erc20Token.setAllowanceAsync(tokenAddress, fromAddress, toAddress, transferAmount);
return expect(
- contractWrappers.token.transferFromAsync(
- token.address,
+ contractWrappers.erc20Token.transferFromAsync(
+ tokenAddress,
fromAddress,
toAddress,
senderAddress,
@@ -136,20 +139,25 @@ describe('TokenWrapper', () => {
const fromAddress = addressWithoutFunds;
const transferAmount = new BigNumber(42);
- const fromAddressBalance = await contractWrappers.token.getBalanceAsync(token.address, fromAddress);
+ const fromAddressBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, fromAddress);
expect(fromAddressBalance).to.be.bignumber.equal(0);
- await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
- const fromAddressAllowance = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ await contractWrappers.erc20Token.setAllowanceAsync(
+ tokenAddress,
+ fromAddress,
+ senderAddress,
+ transferAmount,
+ );
+ const fromAddressAllowance = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
fromAddress,
senderAddress,
);
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
return expect(
- contractWrappers.token.transferFromAsync(
- token.address,
+ contractWrappers.erc20Token.transferFromAsync(
+ tokenAddress,
fromAddress,
toAddress,
senderAddress,
@@ -160,42 +168,47 @@ describe('TokenWrapper', () => {
it('should successfully transfer tokens', async () => {
const fromAddress = coinbase;
- const preBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
+ const preBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
expect(preBalance).to.be.bignumber.equal(0);
const transferAmount = new BigNumber(42);
- await contractWrappers.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
+ await contractWrappers.erc20Token.setAllowanceAsync(
+ tokenAddress,
+ fromAddress,
+ senderAddress,
+ transferAmount,
+ );
- await contractWrappers.token.transferFromAsync(
- token.address,
+ await contractWrappers.erc20Token.transferFromAsync(
+ tokenAddress,
fromAddress,
toAddress,
senderAddress,
transferAmount,
);
- const postBalance = await contractWrappers.token.getBalanceAsync(token.address, toAddress);
+ const postBalance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, toAddress);
return expect(postBalance).to.be.bignumber.equal(transferAmount);
});
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
const fromAddress = coinbase;
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
return expect(
- contractWrappers.token.transferFromAsync(
+ contractWrappers.erc20Token.transferFromAsync(
nonExistentTokenAddress,
fromAddress,
toAddress,
senderAddress,
new BigNumber(42),
),
- ).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
+ ).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist);
});
});
describe('#getBalanceAsync', () => {
describe('With provider with accounts', () => {
it('should return the balance for an existing ERC20 token', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
- const balance = await contractWrappers.token.getBalanceAsync(token.address, ownerAddress);
+ const balance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, ownerAddress);
const expectedBalance = new BigNumber('1000000000000000000000000000');
return expect(balance).to.be.bignumber.equal(expectedBalance);
});
@@ -203,13 +216,13 @@ describe('TokenWrapper', () => {
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
const ownerAddress = coinbase;
return expect(
- contractWrappers.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress),
- ).to.be.rejectedWith(ContractWrappersError.TokenContractDoesNotExist);
+ contractWrappers.erc20Token.getBalanceAsync(nonExistentTokenAddress, ownerAddress),
+ ).to.be.rejectedWith(ContractWrappersError.ERC20TokenContractDoesNotExist);
});
it('should return a balance of 0 for a non-existent owner address', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
- const balance = await contractWrappers.token.getBalanceAsync(token.address, nonExistentOwner);
+ const balance = await contractWrappers.erc20Token.getBalanceAsync(tokenAddress, nonExistentOwner);
const expectedBalance = new BigNumber(0);
return expect(balance).to.be.bignumber.equal(expectedBalance);
});
@@ -221,9 +234,12 @@ describe('TokenWrapper', () => {
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
});
it('should return balance even when called with provider instance without addresses', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
- const balance = await zeroExContractWithoutAccounts.token.getBalanceAsync(token.address, ownerAddress);
+ const balance = await zeroExContractWithoutAccounts.erc20Token.getBalanceAsync(
+ tokenAddress,
+ ownerAddress,
+ );
const expectedBalance = new BigNumber('1000000000000000000000000000');
return expect(balance).to.be.bignumber.equal(expectedBalance);
});
@@ -231,12 +247,12 @@ describe('TokenWrapper', () => {
});
describe('#setAllowanceAsync', () => {
it("should set the spender's allowance", async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
- const allowanceBeforeSet = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ const allowanceBeforeSet = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
);
@@ -244,15 +260,15 @@ describe('TokenWrapper', () => {
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
const amountInBaseUnits = new BigNumber(50);
- await contractWrappers.token.setAllowanceAsync(
- token.address,
+ await contractWrappers.erc20Token.setAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
amountInBaseUnits,
);
- const allowanceAfterSet = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ const allowanceAfterSet = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
);
@@ -262,44 +278,50 @@ describe('TokenWrapper', () => {
});
describe('#setUnlimitedAllowanceAsync', () => {
it("should set the unlimited spender's allowance", async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
- await contractWrappers.token.setUnlimitedAllowanceAsync(token.address, ownerAddress, spenderAddress);
- const allowance = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ await contractWrappers.erc20Token.setUnlimitedAllowanceAsync(tokenAddress, ownerAddress, spenderAddress);
+ const allowance = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
);
- return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+ return expect(allowance).to.be.bignumber.equal(
+ contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
+ );
});
it('should reduce the gas cost for transfers including tokens with unlimited allowance support', async () => {
const transferAmount = new BigNumber(5);
- const zrx = tokenUtils.getProtocolTokenOrThrow();
+ const zrxAddress = tokenUtils.getProtocolTokenAddress();
const [, userWithNormalAllowance, userWithUnlimitedAllowance] = userAddresses;
- await contractWrappers.token.setAllowanceAsync(
- zrx.address,
+ await contractWrappers.erc20Token.setAllowanceAsync(
+ zrxAddress,
coinbase,
userWithNormalAllowance,
transferAmount,
);
- await contractWrappers.token.setUnlimitedAllowanceAsync(zrx.address, coinbase, userWithUnlimitedAllowance);
+ await contractWrappers.erc20Token.setUnlimitedAllowanceAsync(
+ zrxAddress,
+ coinbase,
+ userWithUnlimitedAllowance,
+ );
const initBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
const initBalanceWithUnlimitedAllowance = await web3Wrapper.getBalanceInWeiAsync(
userWithUnlimitedAllowance,
);
- await contractWrappers.token.transferFromAsync(
- zrx.address,
+ await contractWrappers.erc20Token.transferFromAsync(
+ zrxAddress,
coinbase,
userWithNormalAllowance,
userWithNormalAllowance,
transferAmount,
);
- await contractWrappers.token.transferFromAsync(
- zrx.address,
+ await contractWrappers.erc20Token.transferFromAsync(
+ zrxAddress,
coinbase,
userWithUnlimitedAllowance,
userWithUnlimitedAllowance,
@@ -323,20 +345,20 @@ describe('TokenWrapper', () => {
describe('#getAllowanceAsync', () => {
describe('With provider with accounts', () => {
it('should get the proxy allowance', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
const amountInBaseUnits = new BigNumber(50);
- await contractWrappers.token.setAllowanceAsync(
- token.address,
+ await contractWrappers.erc20Token.setAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
amountInBaseUnits,
);
- const allowance = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ const allowance = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
);
@@ -344,11 +366,11 @@ describe('TokenWrapper', () => {
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
});
it('should return 0 if no allowance set yet', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
- const allowance = await contractWrappers.token.getAllowanceAsync(
- token.address,
+ const allowance = await contractWrappers.erc20Token.getAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
);
@@ -363,20 +385,20 @@ describe('TokenWrapper', () => {
zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
});
it('should get the proxy allowance', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
const spenderAddress = addressWithoutFunds;
const amountInBaseUnits = new BigNumber(50);
- await contractWrappers.token.setAllowanceAsync(
- token.address,
+ await contractWrappers.erc20Token.setAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
amountInBaseUnits,
);
- const allowance = await zeroExContractWithoutAccounts.token.getAllowanceAsync(
- token.address,
+ const allowance = await zeroExContractWithoutAccounts.erc20Token.getAllowanceAsync(
+ tokenAddress,
ownerAddress,
spenderAddress,
);
@@ -387,42 +409,50 @@ describe('TokenWrapper', () => {
});
describe('#getProxyAllowanceAsync', () => {
it('should get the proxy allowance', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
const amountInBaseUnits = new BigNumber(50);
- await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
+ await contractWrappers.erc20Token.setProxyAllowanceAsync(tokenAddress, ownerAddress, amountInBaseUnits);
- const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
+ const allowance = await contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
const expectedAllowance = amountInBaseUnits;
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
});
});
describe('#setProxyAllowanceAsync', () => {
it('should set the proxy allowance', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
- const allowanceBeforeSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
+ const allowanceBeforeSet = await contractWrappers.erc20Token.getProxyAllowanceAsync(
+ tokenAddress,
+ ownerAddress,
+ );
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
const amountInBaseUnits = new BigNumber(50);
- await contractWrappers.token.setProxyAllowanceAsync(token.address, ownerAddress, amountInBaseUnits);
+ await contractWrappers.erc20Token.setProxyAllowanceAsync(tokenAddress, ownerAddress, amountInBaseUnits);
- const allowanceAfterSet = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
+ const allowanceAfterSet = await contractWrappers.erc20Token.getProxyAllowanceAsync(
+ tokenAddress,
+ ownerAddress,
+ );
const expectedAllowanceAfterAllowanceSet = amountInBaseUnits;
return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet);
});
});
describe('#setUnlimitedProxyAllowanceAsync', () => {
it('should set the unlimited proxy allowance', async () => {
- const token = tokens[0];
+ const tokenAddress = tokens[0];
const ownerAddress = coinbase;
- await contractWrappers.token.setUnlimitedProxyAllowanceAsync(token.address, ownerAddress);
- const allowance = await contractWrappers.token.getProxyAllowanceAsync(token.address, ownerAddress);
- return expect(allowance).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+ await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, ownerAddress);
+ const allowance = await contractWrappers.erc20Token.getProxyAllowanceAsync(tokenAddress, ownerAddress);
+ return expect(allowance).to.be.bignumber.equal(
+ contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
+ );
});
});
describe('#subscribe', () => {
@@ -431,11 +461,10 @@ describe('TokenWrapper', () => {
const transferAmount = new BigNumber(42);
const allowanceAmount = new BigNumber(42);
before(() => {
- const token = tokens[0];
- tokenAddress = token.address;
+ tokenAddress = tokens[0];
});
afterEach(() => {
- contractWrappers.token.unsubscribeAll();
+ contractWrappers.erc20Token.unsubscribeAll();
});
// Hack: Mocha does not allow a test to be both async and have a `done` callback
// Since we need to await the receipt of the event in the `subscribe` callback,
@@ -445,7 +474,7 @@ describe('TokenWrapper', () => {
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<ERC20TokenTransferEventArgs>) => {
expect(logEvent.isRemoved).to.be.false();
expect(logEvent.log.logIndex).to.be.equal(0);
expect(logEvent.log.transactionIndex).to.be.equal(0);
@@ -456,14 +485,24 @@ describe('TokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(transferAmount);
},
);
- contractWrappers.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
- await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+ contractWrappers.erc20Token.subscribe(
+ tokenAddress,
+ ERC20TokenEvents.Transfer,
+ indexFilterValues,
+ callback,
+ );
+ await contractWrappers.erc20Token.transferAsync(
+ tokenAddress,
+ coinbase,
+ addressWithoutFunds,
+ transferAmount,
+ );
})().catch(done);
});
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
const args = logEvent.log.args;
@@ -472,8 +511,13 @@ describe('TokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(allowanceAmount);
},
);
- contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
- await contractWrappers.token.setAllowanceAsync(
+ contractWrappers.erc20Token.subscribe(
+ tokenAddress,
+ ERC20TokenEvents.Approval,
+ indexFilterValues,
+ callback,
+ );
+ await contractWrappers.erc20Token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
@@ -484,42 +528,52 @@ describe('TokenWrapper', () => {
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ (_logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
- contractWrappers.token.subscribe(
+ contractWrappers.erc20Token.subscribe(
tokenAddress,
- TokenEvents.Transfer,
+ ERC20TokenEvents.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)();
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
- contractWrappers.token.subscribe(
+ contractWrappers.erc20Token.subscribe(
tokenAddress,
- TokenEvents.Transfer,
+ ERC20TokenEvents.Transfer,
indexFilterValues,
callbackToBeCalled,
);
- await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+ await contractWrappers.erc20Token.transferAsync(
+ tokenAddress,
+ coinbase,
+ addressWithoutFunds,
+ transferAmount,
+ );
})().catch(done);
});
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ (_logEvent: DecodedLogEvent<ERC20TokenApprovalEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
- const subscriptionToken = contractWrappers.token.subscribe(
+ const subscriptionToken = contractWrappers.erc20Token.subscribe(
tokenAddress,
- TokenEvents.Transfer,
+ ERC20TokenEvents.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
- contractWrappers.token.unsubscribe(subscriptionToken);
- await contractWrappers.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
+ contractWrappers.erc20Token.unsubscribe(subscriptionToken);
+ await contractWrappers.erc20Token.transferAsync(
+ tokenAddress,
+ coinbase,
+ addressWithoutFunds,
+ transferAmount,
+ );
done();
})().catch(done);
});
@@ -533,16 +587,15 @@ describe('TokenWrapper', () => {
};
let txHash: string;
before(() => {
- const token = tokens[0];
- tokenAddress = token.address;
- tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress();
+ tokenAddress = tokens[0];
+ tokenTransferProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
});
it('should get logs with decoded args emitted by Approval', async () => {
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const eventName = TokenEvents.Approval;
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const eventName = ERC20TokenEvents.Approval;
const indexFilterValues = {};
- const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
+ const logs = await contractWrappers.erc20Token.getLogsAsync<ERC20TokenApprovalEventArgs>(
tokenAddress,
eventName,
blockRange,
@@ -553,14 +606,14 @@ describe('TokenWrapper', () => {
expect(logs[0].event).to.be.equal(eventName);
expect(args._owner).to.be.equal(coinbase);
expect(args._spender).to.be.equal(tokenTransferProxyAddress);
- expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+ expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should only get the logs with the correct event name', async () => {
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const differentEventName = TokenEvents.Transfer;
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const differentEventName = ERC20TokenEvents.Transfer;
const indexFilterValues = {};
- const logs = await contractWrappers.token.getLogsAsync(
+ const logs = await contractWrappers.erc20Token.getLogsAsync(
tokenAddress,
differentEventName,
blockRange,
@@ -569,15 +622,18 @@ describe('TokenWrapper', () => {
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(tokenAddress, addressWithoutFunds);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const eventName = TokenEvents.Approval;
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(tokenAddress, coinbase);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
+ tokenAddress,
+ addressWithoutFunds,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const eventName = ERC20TokenEvents.Approval;
const indexFilterValues = {
_owner: coinbase,
};
- const logs = await contractWrappers.token.getLogsAsync<ApprovalContractEventArgs>(
+ const logs = await contractWrappers.erc20Token.getLogsAsync<ERC20TokenApprovalEventArgs>(
tokenAddress,
eventName,
blockRange,
diff --git a/packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts b/packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts
new file mode 100644
index 000000000..9473d930b
--- /dev/null
+++ b/packages/contract-wrappers/test/erc721_proxy_wrapper_test.ts
@@ -0,0 +1,35 @@
+import * as chai from 'chai';
+
+import { ContractWrappers } from '../src';
+
+import { chaiSetup } from './utils/chai_setup';
+import { constants } from './utils/constants';
+import { provider } from './utils/web3_wrapper';
+
+chaiSetup.configure();
+const expect = chai.expect;
+
+describe('ERC721ProxyWrapper', () => {
+ let contractWrappers: ContractWrappers;
+ const config = {
+ networkId: constants.TESTRPC_NETWORK_ID,
+ };
+ before(async () => {
+ contractWrappers = new ContractWrappers(provider, config);
+ });
+ describe('#isAuthorizedAsync', () => {
+ it('should return false if the address is not authorized', async () => {
+ const isAuthorized = await contractWrappers.erc721Proxy.isAuthorizedAsync(constants.NULL_ADDRESS);
+ expect(isAuthorized).to.be.false();
+ });
+ });
+ describe('#getAuthorizedAddressesAsync', () => {
+ it('should return the list of authorized addresses', async () => {
+ const authorizedAddresses = await contractWrappers.erc721Proxy.getAuthorizedAddressesAsync();
+ for (const authorizedAddress of authorizedAddresses) {
+ const isAuthorized = await contractWrappers.erc721Proxy.isAuthorizedAsync(authorizedAddress);
+ expect(isAuthorized).to.be.true();
+ }
+ });
+ });
+});
diff --git a/packages/contract-wrappers/test/erc721_wrapper_test.ts b/packages/contract-wrappers/test/erc721_wrapper_test.ts
new file mode 100644
index 000000000..96b8fcf1d
--- /dev/null
+++ b/packages/contract-wrappers/test/erc721_wrapper_test.ts
@@ -0,0 +1,472 @@
+import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
+import { EmptyWalletSubprovider } from '@0xproject/subproviders';
+import { DoneCallback } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import * as chai from 'chai';
+import { Provider } from 'ethereum-types';
+import 'mocha';
+import Web3ProviderEngine = require('web3-provider-engine');
+
+import {
+ BlockParamLiteral,
+ BlockRange,
+ ContractWrappers,
+ ContractWrappersError,
+ DecodedLogEvent,
+ ERC721TokenApprovalEventArgs,
+ ERC721TokenApprovalForAllEventArgs,
+ ERC721TokenEvents,
+ ERC721TokenTransferEventArgs,
+} from '../src';
+
+import { chaiSetup } from './utils/chai_setup';
+import { constants } from './utils/constants';
+import { tokenUtils } from './utils/token_utils';
+import { provider, web3Wrapper } from './utils/web3_wrapper';
+
+chaiSetup.configure();
+const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
+describe('ERC721Wrapper', () => {
+ let contractWrappers: ContractWrappers;
+ let userAddresses: string[];
+ let tokens: string[];
+ let ownerAddress: string;
+ let tokenAddress: string;
+ let anotherOwnerAddress: string;
+ let operatorAddress: string;
+ let approvedAddress: string;
+ let receiverAddress: string;
+ const config = {
+ networkId: constants.TESTRPC_NETWORK_ID,
+ };
+ before(async () => {
+ contractWrappers = new ContractWrappers(provider, config);
+ userAddresses = await web3Wrapper.getAvailableAddressesAsync();
+ tokens = tokenUtils.getDummyERC721TokenAddresses();
+ tokenAddress = tokens[0];
+ [ownerAddress, operatorAddress, anotherOwnerAddress, approvedAddress, receiverAddress] = userAddresses;
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ describe('#transferFromAsync', () => {
+ it('should fail to transfer NFT if fromAddress has no approvals set', async () => {
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ return expect(
+ contractWrappers.erc721Token.transferFromAsync(tokenAddress, receiverAddress, approvedAddress, tokenId),
+ ).to.be.rejectedWith(ContractWrappersError.ERC721NoApproval);
+ });
+ it('should successfully transfer tokens when sender is an approved address', async () => {
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ let txHash = await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const owner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
+ expect(owner).to.be.equal(ownerAddress);
+ txHash = await contractWrappers.erc721Token.transferFromAsync(
+ tokenAddress,
+ receiverAddress,
+ approvedAddress,
+ tokenId,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const newOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
+ expect(newOwner).to.be.equal(receiverAddress);
+ });
+ it('should successfully transfer tokens when sender is an approved operator', async () => {
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ const isApprovedForAll = true;
+ let txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const owner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
+ expect(owner).to.be.equal(ownerAddress);
+ txHash = await contractWrappers.erc721Token.transferFromAsync(
+ tokenAddress,
+ receiverAddress,
+ operatorAddress,
+ tokenId,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const newOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
+ expect(newOwner).to.be.equal(receiverAddress);
+ });
+ });
+ describe('#getTokenCountAsync', () => {
+ describe('With provider with accounts', () => {
+ it('should return the count for an existing ERC721 token', async () => {
+ let tokenCount = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, ownerAddress);
+ expect(tokenCount).to.be.bignumber.equal(0);
+ await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ tokenCount = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, ownerAddress);
+ expect(tokenCount).to.be.bignumber.equal(1);
+ });
+ it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+ const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+ return expect(
+ contractWrappers.erc721Token.getTokenCountAsync(nonExistentTokenAddress, ownerAddress),
+ ).to.be.rejectedWith(ContractWrappersError.ERC721TokenContractDoesNotExist);
+ });
+ it('should return a balance of 0 for a non-existent owner address', async () => {
+ const nonExistentOwner = '0x198c6ad858f213fb31b6fe809e25040e6b964593';
+ const balance = await contractWrappers.erc721Token.getTokenCountAsync(tokenAddress, nonExistentOwner);
+ const expectedBalance = new BigNumber(0);
+ return expect(balance).to.be.bignumber.equal(expectedBalance);
+ });
+ });
+ describe('With provider without accounts', () => {
+ let zeroExContractWithoutAccounts: ContractWrappers;
+ before(async () => {
+ const emptyWalletProvider = addEmptyWalletSubprovider(provider);
+ zeroExContractWithoutAccounts = new ContractWrappers(emptyWalletProvider, config);
+ });
+ it('should return balance even when called with provider instance without addresses', async () => {
+ const balance = await zeroExContractWithoutAccounts.erc721Token.getTokenCountAsync(
+ tokenAddress,
+ ownerAddress,
+ );
+ return expect(balance).to.be.bignumber.equal(0);
+ });
+ });
+ });
+ describe('#getOwnerOfAsync', () => {
+ it('should return the owner for an existing ERC721 token', async () => {
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ const tokenOwner = await contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, tokenId);
+ expect(tokenOwner).to.be.bignumber.equal(ownerAddress);
+ });
+ it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
+ const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
+ const fakeTokenId = new BigNumber(42);
+ return expect(
+ contractWrappers.erc721Token.getOwnerOfAsync(nonExistentTokenAddress, fakeTokenId),
+ ).to.be.rejectedWith(ContractWrappersError.ERC721TokenContractDoesNotExist);
+ });
+ it('should return undefined not 0 for a non-existent ERC721', async () => {
+ const fakeTokenId = new BigNumber(42);
+ return expect(contractWrappers.erc721Token.getOwnerOfAsync(tokenAddress, fakeTokenId)).to.be.rejectedWith(
+ ContractWrappersError.ERC721OwnerNotFound,
+ );
+ });
+ });
+ describe('#setApprovalForAllAsync/isApprovedForAllAsync', () => {
+ it('should check if operator address is approved', async () => {
+ let isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ );
+ expect(isApprovedForAll).to.be.false();
+ // set
+ isApprovedForAll = true;
+ let txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ );
+ expect(isApprovedForAll).to.be.true();
+ // unset
+ txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ false,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ isApprovedForAll = await contractWrappers.erc721Token.isApprovedForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ );
+ expect(isApprovedForAll).to.be.false();
+ });
+ });
+ describe('#setProxyApprovalForAllAsync/isProxyApprovedForAllAsync', () => {
+ it('should check if proxy address is approved', async () => {
+ let isApprovedForAll = true;
+ const txHash = await contractWrappers.erc721Token.setProxyApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ isApprovedForAll = await contractWrappers.erc721Token.isProxyApprovedForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ );
+ expect(isApprovedForAll).to.be.true();
+ });
+ });
+ describe('#setApprovalAsync/getApprovedIfExistsAsync', () => {
+ it("should set the spender's approval", async () => {
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+
+ const approvalBeforeSet = await contractWrappers.erc721Token.getApprovedIfExistsAsync(
+ tokenAddress,
+ tokenId,
+ );
+ expect(approvalBeforeSet).to.be.undefined();
+ await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId);
+ const approvalAfterSet = await contractWrappers.erc721Token.getApprovedIfExistsAsync(tokenAddress, tokenId);
+ expect(approvalAfterSet).to.be.equal(approvedAddress);
+ });
+ });
+ describe('#setProxyApprovalAsync/isProxyApprovedAsync', () => {
+ it('should set the proxy approval', async () => {
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+
+ const approvalBeforeSet = await contractWrappers.erc721Token.isProxyApprovedAsync(tokenAddress, tokenId);
+ expect(approvalBeforeSet).to.be.false();
+ await contractWrappers.erc721Token.setProxyApprovalAsync(tokenAddress, tokenId);
+ const approvalAfterSet = await contractWrappers.erc721Token.isProxyApprovedAsync(tokenAddress, tokenId);
+ expect(approvalAfterSet).to.be.true();
+ });
+ });
+ describe('#subscribe', () => {
+ const indexFilterValues = {};
+ afterEach(() => {
+ contractWrappers.erc721Token.unsubscribeAll();
+ });
+ // Hack: Mocha does not allow a test to be both async and have a `done` callback
+ // Since we need to await the receipt of the event in the `subscribe` callback,
+ // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
+ // wrap the rest of the test in an async block
+ // Source: https://github.com/mochajs/mocha/issues/2407
+ it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
+ (async () => {
+ const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ERC721TokenTransferEventArgs>) => {
+ expect(logEvent.isRemoved).to.be.false();
+ expect(logEvent.log.logIndex).to.be.equal(0);
+ expect(logEvent.log.transactionIndex).to.be.equal(0);
+ expect(logEvent.log.blockNumber).to.be.a('number');
+ const args = logEvent.log.args;
+ expect(args._from).to.be.equal(ownerAddress);
+ expect(args._to).to.be.equal(receiverAddress);
+ expect(args._tokenId).to.be.bignumber.equal(tokenId);
+ },
+ );
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ const isApprovedForAll = true;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ ),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ contractWrappers.erc721Token.subscribe(
+ tokenAddress,
+ ERC721TokenEvents.Transfer,
+ indexFilterValues,
+ callback,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await contractWrappers.erc721Token.transferFromAsync(
+ tokenAddress,
+ receiverAddress,
+ operatorAddress,
+ tokenId,
+ ),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ })().catch(done);
+ });
+ it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
+ (async () => {
+ const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ERC721TokenApprovalEventArgs>) => {
+ expect(logEvent).to.not.be.undefined();
+ expect(logEvent.isRemoved).to.be.false();
+ const args = logEvent.log.args;
+ expect(args._owner).to.be.equal(ownerAddress);
+ expect(args._approved).to.be.equal(approvedAddress);
+ expect(args._tokenId).to.be.bignumber.equal(tokenId);
+ },
+ );
+ contractWrappers.erc721Token.subscribe(
+ tokenAddress,
+ ERC721TokenEvents.Approval,
+ indexFilterValues,
+ callback,
+ );
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ })().catch(done);
+ });
+ it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
+ (async () => {
+ const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ERC721TokenApprovalEventArgs>) => {
+ done(new Error('Expected this subscription to have been cancelled'));
+ },
+ );
+ contractWrappers.erc721Token.subscribe(
+ tokenAddress,
+ ERC721TokenEvents.Transfer,
+ indexFilterValues,
+ callbackNeverToBeCalled,
+ );
+ const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)();
+ contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
+ contractWrappers.erc721Token.subscribe(
+ tokenAddress,
+ ERC721TokenEvents.Approval,
+ indexFilterValues,
+ callbackToBeCalled,
+ );
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await contractWrappers.erc721Token.setApprovalAsync(tokenAddress, approvedAddress, tokenId),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ done();
+ })().catch(done);
+ });
+ it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
+ (async () => {
+ const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
+ (logEvent: DecodedLogEvent<ERC721TokenApprovalForAllEventArgs>) => {
+ done(new Error('Expected this subscription to have been cancelled'));
+ },
+ );
+ const subscriptionToken = contractWrappers.erc721Token.subscribe(
+ tokenAddress,
+ ERC721TokenEvents.ApprovalForAll,
+ indexFilterValues,
+ callbackNeverToBeCalled,
+ );
+ contractWrappers.erc721Token.unsubscribe(subscriptionToken);
+
+ const tokenId = await tokenUtils.mintDummyERC721Async(tokenAddress, ownerAddress);
+ const isApproved = true;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApproved,
+ ),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ done();
+ })().catch(done);
+ });
+ });
+ describe('#getLogsAsync', () => {
+ let tokenTransferProxyAddress: string;
+ const blockRange: BlockRange = {
+ fromBlock: 0,
+ toBlock: BlockParamLiteral.Latest,
+ };
+ let txHash: string;
+ before(() => {
+ tokenTransferProxyAddress = contractWrappers.erc721Proxy.getContractAddress();
+ });
+ it('should get logs with decoded args emitted by ApprovalForAll', async () => {
+ const isApprovedForAll = true;
+ txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const eventName = ERC721TokenEvents.ApprovalForAll;
+ const indexFilterValues = {};
+ const logs = await contractWrappers.erc721Token.getLogsAsync<ERC721TokenApprovalForAllEventArgs>(
+ tokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(1);
+ const args = logs[0].args;
+ expect(logs[0].event).to.be.equal(eventName);
+ expect(args._owner).to.be.equal(ownerAddress);
+ expect(args._operator).to.be.equal(operatorAddress);
+ expect(args._approved).to.be.equal(isApprovedForAll);
+ });
+ it('should only get the logs with the correct event name', async () => {
+ const isApprovedForAll = true;
+ txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const differentEventName = ERC721TokenEvents.Transfer;
+ const indexFilterValues = {};
+ const logs = await contractWrappers.erc721Token.getLogsAsync(
+ tokenAddress,
+ differentEventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(0);
+ });
+ it('should only get the logs with the correct indexed fields', async () => {
+ const isApprovedForAll = true;
+ txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ ownerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ txHash = await contractWrappers.erc721Token.setApprovalForAllAsync(
+ tokenAddress,
+ anotherOwnerAddress,
+ operatorAddress,
+ isApprovedForAll,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const eventName = ERC721TokenEvents.ApprovalForAll;
+ const indexFilterValues = {
+ _owner: anotherOwnerAddress,
+ };
+ const logs = await contractWrappers.erc721Token.getLogsAsync<ERC721TokenApprovalForAllEventArgs>(
+ tokenAddress,
+ eventName,
+ blockRange,
+ indexFilterValues,
+ );
+ expect(logs).to.have.length(1);
+ const args = logs[0].args;
+ expect(args._owner).to.be.equal(anotherOwnerAddress);
+ });
+ });
+});
+// tslint:disable:max-file-line-count
+
+function addEmptyWalletSubprovider(p: Provider): Provider {
+ const providerEngine = new Web3ProviderEngine();
+ providerEngine.addProvider(new EmptyWalletSubprovider());
+ const currentSubproviders = (p as any)._providers;
+ for (const subprovider of currentSubproviders) {
+ providerEngine.addProvider(subprovider);
+ }
+ providerEngine.start();
+ return providerEngine;
+}
diff --git a/packages/contract-wrappers/test/ether_token_wrapper_test.ts b/packages/contract-wrappers/test/ether_token_wrapper_test.ts
index f401ef90a..0a860884a 100644
--- a/packages/contract-wrappers/test/ether_token_wrapper_test.ts
+++ b/packages/contract-wrappers/test/ether_token_wrapper_test.ts
@@ -6,22 +6,21 @@ import * as chai from 'chai';
import 'mocha';
import {
- ApprovalContractEventArgs,
BlockParamLiteral,
BlockRange,
ContractWrappers,
ContractWrappersError,
DecodedLogEvent,
- DepositContractEventArgs,
- EtherTokenEvents,
- Token,
- TransferContractEventArgs,
- WithdrawalContractEventArgs,
+ WETH9ApprovalEventArgs,
+ WETH9DepositEventArgs,
+ WETH9Events,
+ WETH9TransferEventArgs,
+ WETH9WithdrawalEventArgs,
} from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
-import { TokenUtils } from './utils/token_utils';
+import { tokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
@@ -36,7 +35,6 @@ const MAX_REASONABLE_GAS_COST_IN_WEI = 62517;
describe('EtherTokenWrapper', () => {
let contractWrappers: ContractWrappers;
- let tokens: Token[];
let userAddresses: string[];
let addressWithETH: string;
let wethContractAddress: string;
@@ -54,7 +52,6 @@ describe('EtherTokenWrapper', () => {
const withdrawalAmount = new BigNumber(42);
before(async () => {
contractWrappers = new ContractWrappers(provider, zeroExConfig);
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
addressWithETH = userAddresses[0];
wethContractAddress = contractWrappers.etherToken.getContractAddressIfExists() as string;
@@ -85,7 +82,10 @@ describe('EtherTokenWrapper', () => {
describe('#depositAsync', () => {
it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => {
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
- const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
+ const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync(
+ wethContractAddress,
+ addressWithETH,
+ );
expect(preETHBalance).to.be.bignumber.gt(0);
expect(preWETHBalance).to.be.bignumber.equal(0);
@@ -94,10 +94,10 @@ describe('EtherTokenWrapper', () => {
depositWeiAmount,
addressWithETH,
);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
- const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
+ const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync(
wethContractAddress,
addressWithETH,
);
@@ -126,7 +126,10 @@ describe('EtherTokenWrapper', () => {
const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
- const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
+ const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync(
+ wethContractAddress,
+ addressWithETH,
+ );
let gasCost = expectedPreETHBalance.minus(preETHBalance);
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
@@ -136,10 +139,10 @@ describe('EtherTokenWrapper', () => {
depositWeiAmount,
addressWithETH,
);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH);
- const postWETHBalanceInBaseUnits = await contractWrappers.token.getBalanceAsync(
+ const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync(
wethContractAddress,
addressWithETH,
);
@@ -150,7 +153,10 @@ describe('EtherTokenWrapper', () => {
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
});
it('should throw if user has insufficient WETH balance for withdrawal', async () => {
- const preWETHBalance = await contractWrappers.token.getBalanceAsync(wethContractAddress, addressWithETH);
+ const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync(
+ wethContractAddress,
+ addressWithETH,
+ );
expect(preWETHBalance).to.be.bignumber.equal(0);
// tslint:disable-next-line:custom-no-magic-numbers
@@ -164,10 +170,8 @@ describe('EtherTokenWrapper', () => {
describe('#subscribe', () => {
const indexFilterValues = {};
let etherTokenAddress: string;
- before(() => {
- const tokenUtils = new TokenUtils(tokens);
- const etherToken = tokenUtils.getWethTokenOrThrow();
- etherTokenAddress = etherToken.address;
+ before(async () => {
+ etherTokenAddress = tokenUtils.getWethTokenAddress();
});
afterEach(() => {
contractWrappers.etherToken.unsubscribeAll();
@@ -180,7 +184,7 @@ describe('EtherTokenWrapper', () => {
it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<WETH9TransferEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
expect(logEvent.log.logIndex).to.be.equal(0);
@@ -195,11 +199,11 @@ describe('EtherTokenWrapper', () => {
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Transfer,
+ WETH9Events.Transfer,
indexFilterValues,
callback,
);
- await contractWrappers.token.transferAsync(
+ await contractWrappers.erc20Token.transferAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -210,7 +214,7 @@ describe('EtherTokenWrapper', () => {
it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
const args = logEvent.log.args;
@@ -221,11 +225,11 @@ describe('EtherTokenWrapper', () => {
);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Approval,
+ WETH9Events.Approval,
indexFilterValues,
callback,
);
- await contractWrappers.token.setAllowanceAsync(
+ await contractWrappers.erc20Token.setAllowanceAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -236,7 +240,7 @@ describe('EtherTokenWrapper', () => {
it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<DepositContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<WETH9DepositEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
const args = logEvent.log.args;
@@ -246,7 +250,7 @@ describe('EtherTokenWrapper', () => {
);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Deposit,
+ WETH9Events.Deposit,
indexFilterValues,
callback,
);
@@ -256,7 +260,7 @@ describe('EtherTokenWrapper', () => {
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<WETH9WithdrawalEventArgs>) => {
expect(logEvent).to.not.be.undefined();
expect(logEvent.isRemoved).to.be.false();
const args = logEvent.log.args;
@@ -267,7 +271,7 @@ describe('EtherTokenWrapper', () => {
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Withdrawal,
+ WETH9Events.Withdrawal,
indexFilterValues,
callback,
);
@@ -277,13 +281,13 @@ describe('EtherTokenWrapper', () => {
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ (_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Transfer,
+ WETH9Events.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
@@ -292,11 +296,11 @@ describe('EtherTokenWrapper', () => {
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Transfer,
+ WETH9Events.Transfer,
indexFilterValues,
callbackToBeCalled,
);
- await contractWrappers.token.transferAsync(
+ await contractWrappers.erc20Token.transferAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -307,19 +311,19 @@ describe('EtherTokenWrapper', () => {
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
+ (_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
const subscriptionToken = contractWrappers.etherToken.subscribe(
etherTokenAddress,
- EtherTokenEvents.Transfer,
+ WETH9Events.Transfer,
indexFilterValues,
callbackNeverToBeCalled,
);
contractWrappers.etherToken.unsubscribe(subscriptionToken);
- await contractWrappers.token.transferAsync(
+ await contractWrappers.erc20Token.transferAsync(
etherTokenAddress,
addressWithETH,
addressWithoutFunds,
@@ -331,7 +335,7 @@ describe('EtherTokenWrapper', () => {
});
describe('#getLogsAsync', () => {
let etherTokenAddress: string;
- let tokenTransferProxyAddress: string;
+ let erc20ProxyAddress: string;
const blockRange: BlockRange = {
fromBlock: 0,
toBlock: BlockParamLiteral.Latest,
@@ -339,17 +343,18 @@ describe('EtherTokenWrapper', () => {
let txHash: string;
before(() => {
addressWithETH = userAddresses[0];
- const tokenUtils = new TokenUtils(tokens);
- const etherToken = tokenUtils.getWethTokenOrThrow();
- etherTokenAddress = etherToken.address;
- tokenTransferProxyAddress = contractWrappers.proxy.getContractAddress();
+ etherTokenAddress = tokenUtils.getWethTokenAddress();
+ erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
});
it('should get logs with decoded args emitted by Approval', async () => {
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const eventName = EtherTokenEvents.Approval;
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
+ etherTokenAddress,
+ addressWithETH,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const eventName = WETH9Events.Approval;
const indexFilterValues = {};
- const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+ const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>(
etherTokenAddress,
eventName,
blockRange,
@@ -359,14 +364,14 @@ describe('EtherTokenWrapper', () => {
const args = logs[0].args;
expect(logs[0].event).to.be.equal(eventName);
expect(args._owner).to.be.equal(addressWithETH);
- expect(args._spender).to.be.equal(tokenTransferProxyAddress);
- expect(args._value).to.be.bignumber.equal(contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
+ expect(args._spender).to.be.equal(erc20ProxyAddress);
+ expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS);
});
it('should get logs with decoded args emitted by Deposit', async () => {
await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
- const eventName = EtherTokenEvents.Deposit;
+ const eventName = WETH9Events.Deposit;
const indexFilterValues = {};
- const logs = await contractWrappers.etherToken.getLogsAsync<DepositContractEventArgs>(
+ const logs = await contractWrappers.etherToken.getLogsAsync<WETH9DepositEventArgs>(
etherTokenAddress,
eventName,
blockRange,
@@ -379,9 +384,12 @@ describe('EtherTokenWrapper', () => {
expect(args._value).to.be.bignumber.equal(depositAmount);
});
it('should only get the logs with the correct event name', async () => {
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const differentEventName = EtherTokenEvents.Transfer;
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
+ etherTokenAddress,
+ addressWithETH,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const differentEventName = WETH9Events.Transfer;
const indexFilterValues = {};
const logs = await contractWrappers.etherToken.getLogsAsync(
etherTokenAddress,
@@ -392,18 +400,21 @@ describe('EtherTokenWrapper', () => {
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(etherTokenAddress, addressWithETH);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
+ etherTokenAddress,
+ addressWithETH,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync(
etherTokenAddress,
addressWithoutFunds,
);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const eventName = EtherTokenEvents.Approval;
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const eventName = WETH9Events.Approval;
const indexFilterValues = {
_owner: addressWithETH,
};
- const logs = await contractWrappers.etherToken.getLogsAsync<ApprovalContractEventArgs>(
+ const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>(
etherTokenAddress,
eventName,
blockRange,
diff --git a/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts b/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts
deleted file mode 100644
index cbc52df7f..000000000
--- a/packages/contract-wrappers/test/exchange_transfer_simulator_test.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { BlockParamLiteral, Token } from '@0xproject/types';
-import { BigNumber } from '@0xproject/utils';
-import * as chai from 'chai';
-
-import { ContractWrappers, ExchangeContractErrs } from '../src';
-import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store';
-import { TradeSide, TransferType } from '../src/types';
-import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
-
-import { chaiSetup } from './utils/chai_setup';
-import { constants } from './utils/constants';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-describe('ExchangeTransferSimulator', () => {
- const config = {
- networkId: constants.TESTRPC_NETWORK_ID,
- };
- const contractWrappers = new ContractWrappers(provider, config);
- const transferAmount = new BigNumber(5);
- let userAddresses: string[];
- let tokens: Token[];
- let coinbase: string;
- let sender: string;
- let recipient: string;
- let exampleTokenAddress: string;
- let exchangeTransferSimulator: ExchangeTransferSimulator;
- let txHash: string;
- before(async () => {
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- [coinbase, sender, recipient] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- exampleTokenAddress = tokens[0].address;
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('#transferFromAsync', () => {
- beforeEach(() => {
- const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
- contractWrappers.token,
- BlockParamLiteral.Latest,
- );
- exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
- });
- it("throws if the user doesn't have enough allowance", async () => {
- return expect(
- exchangeTransferSimulator.transferFromAsync(
- exampleTokenAddress,
- sender,
- recipient,
- transferAmount,
- TradeSide.Taker,
- TransferType.Trade,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
- });
- it("throws if the user doesn't have enough balance", async () => {
- txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- return expect(
- exchangeTransferSimulator.transferFromAsync(
- exampleTokenAddress,
- sender,
- recipient,
- transferAmount,
- TradeSide.Maker,
- TransferType.Trade,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
- });
- it('updates balances and proxyAllowance after transfer', async () => {
- txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- txHash = await contractWrappers.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- await exchangeTransferSimulator.transferFromAsync(
- exampleTokenAddress,
- sender,
- recipient,
- transferAmount,
- TradeSide.Taker,
- TransferType.Trade,
- );
- const store = (exchangeTransferSimulator as any)._store;
- const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
- const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
- const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
- expect(senderBalance).to.be.bignumber.equal(0);
- expect(recipientBalance).to.be.bignumber.equal(transferAmount);
- expect(senderProxyAllowance).to.be.bignumber.equal(0);
- });
- it("doesn't update proxyAllowance after transfer if unlimited", async () => {
- txHash = await contractWrappers.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- txHash = await contractWrappers.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- await exchangeTransferSimulator.transferFromAsync(
- exampleTokenAddress,
- sender,
- recipient,
- transferAmount,
- TradeSide.Taker,
- TransferType.Trade,
- );
- const store = (exchangeTransferSimulator as any)._store;
- const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
- const recipientBalance = await store.getBalanceAsync(exampleTokenAddress, recipient);
- const senderProxyAllowance = await store.getProxyAllowanceAsync(exampleTokenAddress, sender);
- expect(senderBalance).to.be.bignumber.equal(0);
- expect(recipientBalance).to.be.bignumber.equal(transferAmount);
- expect(senderProxyAllowance).to.be.bignumber.equal(
- contractWrappers.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
- );
- });
- });
-});
diff --git a/packages/contract-wrappers/test/exchange_wrapper_test.ts b/packages/contract-wrappers/test/exchange_wrapper_test.ts
index c945b4c70..b2c716008 100644
--- a/packages/contract-wrappers/test/exchange_wrapper_test.ts
+++ b/packages/contract-wrappers/test/exchange_wrapper_test.ts
@@ -1,57 +1,91 @@
import { BlockchainLifecycle, callbackErrorReporter } from '@0xproject/dev-utils';
import { FillScenarios } from '@0xproject/fill-scenarios';
-import { getOrderHashHex } from '@0xproject/order-utils';
-import { BlockParamLiteral, DoneCallback, OrderState } from '@0xproject/types';
+import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
+import { DoneCallback, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
-import { Web3Wrapper } from '@0xproject/web3-wrapper';
import * as chai from 'chai';
+import { BlockParamLiteral } from 'ethereum-types';
import 'mocha';
import {
- BlockRange,
ContractWrappers,
DecodedLogEvent,
- ExchangeContractErrs,
+ ExchangeCancelEventArgs,
ExchangeEvents,
- LogCancelContractEventArgs,
- LogFillContractEventArgs,
- OrderCancellationRequest,
- OrderFillRequest,
- SignedOrder,
- Token,
+ ExchangeFillEventArgs,
+ OrderStatus,
} from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
-import { TokenUtils } from './utils/token_utils';
+import { tokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
const expect = chai.expect;
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777';
-
describe('ExchangeWrapper', () => {
let contractWrappers: ContractWrappers;
- let tokenUtils: TokenUtils;
- let tokens: Token[];
let userAddresses: string[];
let zrxTokenAddress: string;
let fillScenarios: FillScenarios;
let exchangeContractAddress: string;
+ let makerTokenAddress: string;
+ let takerTokenAddress: string;
+ let coinbase: string;
+ let makerAddress: string;
+ let anotherMakerAddress: string;
+ let takerAddress: string;
+ let makerAssetData: string;
+ let takerAssetData: string;
+ let feeRecipient: string;
+ let txHash: string;
+ const fillableAmount = new BigNumber(5);
+ const takerTokenFillAmount = new BigNumber(5);
+ let signedOrder: SignedOrder;
+ let anotherSignedOrder: SignedOrder;
const config = {
networkId: constants.TESTRPC_NETWORK_ID,
+ blockPollingIntervalMs: 0,
};
before(async () => {
+ await blockchainLifecycle.startAsync();
contractWrappers = new ContractWrappers(provider, config);
exchangeContractAddress = contractWrappers.exchange.getContractAddress();
+ const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- tokenUtils = new TokenUtils(tokens);
- zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
- fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
- await fillScenarios.initTokenBalancesAsync();
+ zrxTokenAddress = tokenUtils.getProtocolTokenAddress();
+ fillScenarios = new FillScenarios(
+ provider,
+ userAddresses,
+ zrxTokenAddress,
+ exchangeContractAddress,
+ erc20ProxyAddress,
+ );
+ [coinbase, makerAddress, takerAddress, feeRecipient, anotherMakerAddress] = userAddresses;
+ [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
+ [makerAssetData, takerAssetData] = [
+ assetProxyUtils.encodeERC20AssetData(makerTokenAddress),
+ assetProxyUtils.encodeERC20AssetData(takerTokenAddress),
+ ];
+ signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerAssetData,
+ takerAssetData,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ );
+ anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerAssetData,
+ takerAssetData,
+ makerAddress,
+ takerAddress,
+ fillableAmount,
+ );
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
});
beforeEach(async () => {
await blockchainLifecycle.startAsync();
@@ -59,903 +93,279 @@ describe('ExchangeWrapper', () => {
afterEach(async () => {
await blockchainLifecycle.revertAsync();
});
- describe('fillOrKill order(s)', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- const takerTokenFillAmount = new BigNumber(5);
- before(async () => {
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- describe('#batchFillOrKillAsync', () => {
- it('successfully batch fillOrKill', async () => {
- const fillableAmount = new BigNumber(5);
- const partialFillTakerAmount = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ describe('fill order(s)', () => {
+ describe('#fillOrderAsync', () => {
+ it('should fill a valid order', async () => {
+ txHash = await contractWrappers.exchange.fillOrderAsync(
+ signedOrder,
+ takerTokenFillAmount,
takerAddress,
- fillableAmount,
);
- const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ });
+ });
+ describe('#fillOrderNoThrowAsync', () => {
+ it('should fill a valid order', async () => {
+ txHash = await contractWrappers.exchange.fillOrderNoThrowAsync(
+ signedOrder,
+ takerTokenFillAmount,
takerAddress,
- fillableAmount,
);
- const orderFillRequests = [
- {
- signedOrder,
- takerTokenFillAmount: partialFillTakerAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount: partialFillTakerAmount,
- },
- ];
- await contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress);
- });
- describe('order transaction options', () => {
- let signedOrder: SignedOrder;
- let orderFillRequests: OrderFillRequest[];
- const fillableAmount = new BigNumber(5);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- orderFillRequests = [
- {
- signedOrder,
- takerTokenFillAmount: new BigNumber(0),
- },
- ];
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
});
});
describe('#fillOrKillOrderAsync', () => {
- let signedOrder: SignedOrder;
- const fillableAmount = new BigNumber(5);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ it('should fill or kill a valid order', async () => {
+ txHash = await contractWrappers.exchange.fillOrKillOrderAsync(
+ signedOrder,
+ takerTokenFillAmount,
takerAddress,
- fillableAmount,
);
- });
- describe('successful fills', () => {
- it('should fill a valid order', async () => {
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- await contractWrappers.exchange.fillOrKillOrderAsync(
- signedOrder,
- takerTokenFillAmount,
- takerAddress,
- );
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- });
- it('should partially fill a valid order', async () => {
- const partialFillAmount = new BigNumber(3);
- await contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- });
- });
- describe('order transaction options', () => {
- const emptyFillableAmount = new BigNumber(0);
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
- });
- describe('fill order(s)', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- const fillableAmount = new BigNumber(5);
- const takerTokenFillAmount = new BigNumber(5);
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
- before(async () => {
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- describe('#fillOrderAsync', () => {
- describe('successful fills', () => {
- it('should fill a valid order', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(0);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount);
- const txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- takerTokenFillAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(takerTokenFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
- });
- it('should partially fill the valid order', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const partialFillAmount = new BigNumber(3);
- const txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- partialFillAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, makerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(makerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(partialFillAmount);
- expect(
- await contractWrappers.token.getBalanceAsync(takerTokenAddress, takerAddress),
- ).to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
- });
- it('should fill the valid orders with fees', async () => {
- const makerFee = new BigNumber(1);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- feeRecipient,
- );
- const txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- takerTokenFillAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- expect(
- await contractWrappers.token.getBalanceAsync(zrxTokenAddress, feeRecipient),
- ).to.be.bignumber.equal(makerFee.plus(takerFee));
- });
- });
- describe('order transaction options', () => {
- let signedOrder: SignedOrder;
- const emptyFillTakerAmount = new BigNumber(0);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- emptyFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- emptyFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: true,
- },
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- emptyFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: false,
- },
- ),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ describe('#batchFillOrdersAsync', () => {
+ it('should fill a batch of valid orders', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount];
+ txHash = await contractWrappers.exchange.batchFillOrdersAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
- describe('negative fill amount', async () => {
- let signedOrder: SignedOrder;
- const negativeFillTakerAmount = new BigNumber(-100);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- });
- it('should not allow the exchange wrapper to fill if amount is negative', async () => {
- return expect(
- contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- negativeFillTakerAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejected();
- });
+ });
+ describe('#marketBuyOrdersAsync', () => {
+ it('should maker buy', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const makerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketBuyOrdersAsync(
+ signedOrders,
+ makerAssetFillAmount,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
- describe('#batchFillOrdersAsync', () => {
- let signedOrder: SignedOrder;
- let signedOrderHashHex: string;
- let anotherSignedOrder: SignedOrder;
- let anotherOrderHashHex: string;
- let orderFillBatch: OrderFillRequest[];
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ describe('#marketBuyOrdersNoThrowAsync', () => {
+ it('should no throw maker buy', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const makerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketBuyOrdersNoThrowAsync(
+ signedOrders,
+ makerAssetFillAmount,
takerAddress,
- fillableAmount,
);
- signedOrderHashHex = getOrderHashHex(signedOrder);
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ });
+ });
+ describe('#marketSellOrdersAsync', () => {
+ it('should maker sell', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketSellOrdersAsync(
+ signedOrders,
+ takerAssetFillAmount,
takerAddress,
- fillableAmount,
);
- anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
- });
- describe('successful batch fills', () => {
- beforeEach(() => {
- orderFillBatch = [
- {
- signedOrder,
- takerTokenFillAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount,
- },
- ];
- });
- it('should throw if a batch is empty', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- [],
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
- });
- it('should successfully fill multiple orders', async () => {
- const txHash = await contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(filledAmount).to.be.bignumber.equal(takerTokenFillAmount);
- expect(anotherFilledAmount).to.be.bignumber.equal(takerTokenFillAmount);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
- describe('order transaction options', () => {
- beforeEach(async () => {
- const emptyFillTakerAmount = new BigNumber(0);
- orderFillBatch = [
- {
- signedOrder,
- takerTokenFillAmount: emptyFillTakerAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount: emptyFillTakerAmount,
- },
- ];
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: true,
- },
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: false,
- },
- ),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- });
- describe('negative batch fill amount', async () => {
- beforeEach(async () => {
- const negativeFillTakerAmount = new BigNumber(-100);
- orderFillBatch = [
- {
- signedOrder,
- takerTokenFillAmount,
- },
- {
- signedOrder: anotherSignedOrder,
- takerTokenFillAmount: negativeFillTakerAmount,
- },
- ];
- });
- it('should not allow the exchange wrapper to batch fill if any amount is negative', async () => {
- return expect(
- contractWrappers.exchange.batchFillOrdersAsync(
- orderFillBatch,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejected();
- });
+ });
+ describe('#marketSellOrdersNoThrowAsync', () => {
+ it('should no throw maker sell', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmount = takerTokenFillAmount;
+ txHash = await contractWrappers.exchange.marketSellOrdersNoThrowAsync(
+ signedOrders,
+ takerAssetFillAmount,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ });
+ });
+ describe('#batchFillOrdersNoThrowAsync', () => {
+ it('should fill a batch of valid orders', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount];
+ txHash = await contractWrappers.exchange.batchFillOrdersNoThrowAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ let orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ orderInfo = await contractWrappers.exchange.getOrderInfoAsync(anotherSignedOrder);
+ expect(orderInfo.orderStatus).to.be.equal(OrderStatus.FULLY_FILLED);
+ });
+ });
+ describe('#batchFillOrKillOrdersAsync', () => {
+ it('should fill or kill a batch of valid orders', async () => {
+ const signedOrders = [signedOrder, anotherSignedOrder];
+ const takerAssetFillAmounts = [takerTokenFillAmount, takerTokenFillAmount];
+ txHash = await contractWrappers.exchange.batchFillOrKillOrdersAsync(
+ signedOrders,
+ takerAssetFillAmounts,
+ takerAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
- describe('#fillOrdersUpTo', () => {
- let signedOrder: SignedOrder;
- let signedOrderHashHex: string;
- let anotherSignedOrder: SignedOrder;
- let anotherOrderHashHex: string;
- let signedOrders: SignedOrder[];
- const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
- beforeEach(async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
+ describe('#matchOrdersAsync', () => {
+ it('should match two valid ordersr', async () => {
+ const matchingSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ takerAssetData,
+ makerAssetData,
makerAddress,
takerAddress,
fillableAmount,
);
- signedOrderHashHex = getOrderHashHex(signedOrder);
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
+ txHash = await contractWrappers.exchange.matchOrdersAsync(
+ signedOrder,
+ matchingSignedOrder,
takerAddress,
- fillableAmount,
);
- anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
- signedOrders = [signedOrder, anotherSignedOrder];
- });
- describe('successful batch fills', () => {
- it('should throw if a batch is empty', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- [],
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
- });
- it('should successfully fill up to specified amount when all orders are fully funded', async () => {
- const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(filledAmount).to.be.bignumber.equal(fillableAmount);
- const remainingFillAmount = fillableAmount.minus(1);
- expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
- });
- it('should successfully fill up to specified amount and leave the rest of the orders untouched', async () => {
- const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const zeroAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
- expect(filledAmount).to.be.bignumber.equal(fillableAmount);
- expect(zeroAmount).to.be.bignumber.equal(0);
- });
- it('should successfully fill up to specified amount even if filling all orders would fail', async () => {
- const missingBalance = new BigNumber(1); // User will still have enough balance to fill up to 9,
- // but won't have 10 to fully fill all orders in a batch.
- await contractWrappers.token.transferAsync(
- makerTokenAddress,
- makerAddress,
- coinbase,
- missingBalance,
- );
- const txHash = await contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const filledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
- const anotherFilledAmount = await contractWrappers.exchange.getFilledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(filledAmount).to.be.bignumber.equal(fillableAmount);
- const remainingFillAmount = fillableAmount.minus(1);
- expect(anotherFilledAmount).to.be.bignumber.equal(remainingFillAmount);
- });
- });
- describe('failed batch fills', () => {
- it("should fail validation if user doesn't have enough balance without fill up to", async () => {
- const missingBalance = new BigNumber(2); // User will only have enough balance to fill up to 8
- await contractWrappers.token.transferAsync(
- makerTokenAddress,
- makerAddress,
- coinbase,
- missingBalance,
- );
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- fillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
- });
- });
- describe('order transaction options', () => {
- const emptyFillUpToAmount = new BigNumber(0);
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- emptyFillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- emptyFillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: true,
- },
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.fillOrdersUpToAsync(
- signedOrders,
- emptyFillUpToAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- {
- shouldValidate: false,
- },
- ),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
});
describe('cancel order(s)', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- const fillableAmount = new BigNumber(5);
- let signedOrder: SignedOrder;
- let orderHashHex: string;
- const cancelAmount = new BigNumber(3);
- beforeEach(async () => {
- [coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- orderHashHex = getOrderHashHex(signedOrder);
- });
describe('#cancelOrderAsync', () => {
- describe('successful cancels', () => {
- it('should cancel an order', async () => {
- const txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex);
- expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
- });
- });
- describe('order transaction options', () => {
- const emptyCancelTakerTokenAmount = new BigNumber(0);
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(
- contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
+ it('should cancel a valid order', async () => {
+ txHash = await contractWrappers.exchange.cancelOrderAsync(signedOrder);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
});
describe('#batchCancelOrdersAsync', () => {
- let anotherSignedOrder: SignedOrder;
- let anotherOrderHashHex: string;
- let cancelBatch: OrderCancellationRequest[];
- beforeEach(async () => {
- anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
+ it('should cancel a batch of valid orders', async () => {
+ const orders = [signedOrder, anotherSignedOrder];
+ txHash = await contractWrappers.exchange.batchCancelOrdersAsync(orders);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ });
+ });
+ describe('#cancelOrdersUpTo/getOrderEpochAsync', () => {
+ it('should cancel orders up to target order epoch', async () => {
+ const targetOrderEpoch = new BigNumber(42);
+ txHash = await contractWrappers.exchange.cancelOrdersUpToAsync(targetOrderEpoch, makerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const orderEpoch = await contractWrappers.exchange.getOrderEpochAsync(
makerAddress,
- takerAddress,
- fillableAmount,
+ constants.NULL_ADDRESS,
);
- anotherOrderHashHex = getOrderHashHex(anotherSignedOrder);
- cancelBatch = [
- {
- order: signedOrder,
- takerTokenCancelAmount: cancelAmount,
- },
- {
- order: anotherSignedOrder,
- takerTokenCancelAmount: cancelAmount,
- },
- ];
- });
- describe('failed batch cancels', () => {
- it('should throw when orders have different makers', async () => {
- const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- takerAddress,
- takerAddress,
- fillableAmount,
- );
- return expect(
- contractWrappers.exchange.batchCancelOrdersAsync([
- cancelBatch[0],
- {
- order: signedOrderWithDifferentMaker,
- takerTokenCancelAmount: cancelAmount,
- },
- ]),
- ).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
- });
- });
- describe('successful batch cancels', () => {
- it('should cancel a batch of orders', async () => {
- await contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch);
- const cancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHashHex);
- const anotherCancelledAmount = await contractWrappers.exchange.getCancelledTakerAmountAsync(
- anotherOrderHashHex,
- );
- expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
- expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
- });
- });
- describe('order transaction options', () => {
- beforeEach(async () => {
- const emptyTakerTokenCancelAmount = new BigNumber(0);
- cancelBatch = [
- {
- order: signedOrder,
- takerTokenCancelAmount: emptyTakerTokenCancelAmount,
- },
- {
- order: anotherSignedOrder,
- takerTokenCancelAmount: emptyTakerTokenCancelAmount,
- },
- ];
- });
- it('should validate when orderTransactionOptions are not present', async () => {
- return expect(contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
- ExchangeContractErrs.OrderCancelAmountZero,
- );
- });
- it('should validate when orderTransactionOptions specify to validate', async () => {
- return expect(
- contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, {
- shouldValidate: true,
- }),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should not validate when orderTransactionOptions specify not to validate', async () => {
- return expect(
- contractWrappers.exchange.batchCancelOrdersAsync(cancelBatch, {
- shouldValidate: false,
- }),
- ).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
+ expect(orderEpoch).to.be.bignumber.equal(targetOrderEpoch.plus(1));
});
});
});
- describe('tests that require partially filled order', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let takerAddress: string;
- let fillableAmount: BigNumber;
- let partialFillAmount: BigNumber;
- let signedOrder: SignedOrder;
- let orderHash: string;
- before(() => {
- takerAddress = userAddresses[1];
- tokenUtils = new TokenUtils(tokens);
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
+ describe('#getZRXAssetData', () => {
+ it('should get the asset data', async () => {
+ const ZRX_ASSET_DATA = await contractWrappers.exchange.getZRXAssetDataAsync();
+ const ASSET_DATA_HEX_LENGTH = 74;
+ expect(ZRX_ASSET_DATA).to.have.length(ASSET_DATA_HEX_LENGTH);
});
- beforeEach(async () => {
- fillableAmount = new BigNumber(5);
- partialFillAmount = new BigNumber(2);
- signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- takerAddress,
- fillableAmount,
- partialFillAmount,
+ });
+ describe('#getOrderInfoAsync', () => {
+ it('should get the order info', async () => {
+ const orderInfo = await contractWrappers.exchange.getOrderInfoAsync(signedOrder);
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ expect(orderInfo.orderHash).to.be.equal(orderHash);
+ });
+ });
+ describe('#isValidSignature', () => {
+ it('should check if the signature is valid', async () => {
+ const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ let isValid = await contractWrappers.exchange.isValidSignatureAsync(
+ orderHash,
+ signedOrder.makerAddress,
+ signedOrder.signature,
+ );
+ expect(isValid).to.be.true();
+ isValid = await contractWrappers.exchange.isValidSignatureAsync(
+ orderHash,
+ signedOrder.takerAddress,
+ signedOrder.signature,
);
- orderHash = getOrderHashHex(signedOrder);
+ expect(isValid).to.be.false();
});
- describe('#getUnavailableTakerAmountAsync', () => {
- it('should throw if passed an invalid orderHash', async () => {
- const invalidOrderHashHex = '0x123';
- return expect(
- contractWrappers.exchange.getUnavailableTakerAmountAsync(invalidOrderHashHex),
- ).to.be.rejected();
- });
- it('should return zero if passed a valid but non-existent orderHash', async () => {
- const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(
- NON_EXISTENT_ORDER_HASH,
- );
- expect(unavailableValueT).to.be.bignumber.equal(0);
- });
- it('should return the unavailableValueT for a valid and partially filled orderHash', async () => {
- const unavailableValueT = await contractWrappers.exchange.getUnavailableTakerAmountAsync(orderHash);
- expect(unavailableValueT).to.be.bignumber.equal(partialFillAmount);
- });
+ });
+ describe('#isAllowedValidatorAsync', () => {
+ it('should check if the validator is alllowed', async () => {
+ const signerAddress = makerAddress;
+ const validatorAddress = constants.NULL_ADDRESS;
+ const isAllowed = await contractWrappers.exchange.isAllowedValidatorAsync(signerAddress, validatorAddress);
+ expect(isAllowed).to.be.false();
});
- describe('#getFilledTakerAmountAsync', () => {
- it('should throw if passed an invalid orderHash', async () => {
- const invalidOrderHashHex = '0x123';
- return expect(
- contractWrappers.exchange.getFilledTakerAmountAsync(invalidOrderHashHex),
- ).to.be.rejected();
- });
- it('should return zero if passed a valid but non-existent orderHash', async () => {
- const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
- expect(filledValueT).to.be.bignumber.equal(0);
- });
- it('should return the filledValueT for a valid and partially filled orderHash', async () => {
- const filledValueT = await contractWrappers.exchange.getFilledTakerAmountAsync(orderHash);
- expect(filledValueT).to.be.bignumber.equal(partialFillAmount);
- });
+ });
+ describe('#setSignatureValidatorApproval', () => {
+ it('should set signature validator approval', async () => {
+ const validatorAddress = constants.NULL_ADDRESS;
+ const isApproved = true;
+ const senderAddress = makerAddress;
+ txHash = await contractWrappers.exchange.setSignatureValidatorApprovalAsync(
+ validatorAddress,
+ isApproved,
+ senderAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
});
- describe('#getCancelledTakerAmountAsync', () => {
- it('should throw if passed an invalid orderHash', async () => {
- const invalidOrderHashHex = '0x123';
- return expect(
- contractWrappers.exchange.getCancelledTakerAmountAsync(invalidOrderHashHex),
- ).to.be.rejected();
- });
- it('should return zero if passed a valid but non-existent orderHash', async () => {
- const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(
- NON_EXISTENT_ORDER_HASH,
- );
- expect(cancelledValueT).to.be.bignumber.equal(0);
- });
- it('should return the cancelledValueT for a valid and partially filled orderHash', async () => {
- const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash);
- expect(cancelledValueT).to.be.bignumber.equal(0);
- });
- it('should return the cancelledValueT for a valid and cancelled orderHash', async () => {
- const cancelAmount = fillableAmount.minus(partialFillAmount);
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelAmount);
- const cancelledValueT = await contractWrappers.exchange.getCancelledTakerAmountAsync(orderHash);
- expect(cancelledValueT).to.be.bignumber.equal(cancelAmount);
- });
+ });
+ describe('#isTransactionExecutedAsync', () => {
+ it('should check if the transaction is executed', async () => {
+ const transactionHash = '0x0000000000000000000000000000000000000000000000000000000000000000';
+ const isExecuted = await contractWrappers.exchange.isTransactionExecutedAsync(transactionHash);
+ expect(isExecuted).to.be.false();
+ });
+ });
+ describe('#getAssetProxyBySignatureAsync', () => {
+ it('should fill or kill a valid order', async () => {
+ const erc20ProxyId = await contractWrappers.erc20Proxy.getProxyIdAsync();
+ const erc20ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc20ProxyId);
+ const erc20ProxyAddress = contractWrappers.erc20Proxy.getContractAddress();
+ expect(erc20ProxyAddressById).to.be.equal(erc20ProxyAddress);
+ const erc721ProxyId = await contractWrappers.erc721Proxy.getProxyIdAsync();
+ const erc721ProxyAddressById = await contractWrappers.exchange.getAssetProxyBySignatureAsync(erc721ProxyId);
+ const erc721ProxyAddress = contractWrappers.erc721Proxy.getContractAddress();
+ expect(erc721ProxyAddressById).to.be.equal(erc721ProxyAddress);
+ });
+ });
+ describe('#preSignAsync/isPreSignedAsync', () => {
+ it('should preSign the hash', async () => {
+ const senderAddress = takerAddress;
+ const hash = orderHashUtils.getOrderHashHex(signedOrder);
+ const signerAddress = signedOrder.makerAddress;
+ let isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress);
+ expect(isPreSigned).to.be.false();
+ txHash = await contractWrappers.exchange.preSignAsync(
+ hash,
+ signerAddress,
+ signedOrder.signature,
+ senderAddress,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ isPreSigned = await contractWrappers.exchange.isPreSignedAsync(hash, signerAddress);
+ expect(isPreSigned).to.be.true();
+ });
+ });
+ describe('#getVersionAsync', () => {
+ it('should return version the hash', async () => {
+ const version = await contractWrappers.exchange.getVersionAsync();
+ const VERSION = '2.0.1-alpha';
+ expect(version).to.be.equal(VERSION);
});
});
describe('#subscribe', () => {
const indexFilterValues = {};
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let takerAddress: string;
- let makerAddress: string;
- let fillableAmount: BigNumber;
- let signedOrder: SignedOrder;
const takerTokenFillAmountInBaseUnits = new BigNumber(1);
- const cancelTakerAmountInBaseUnits = new BigNumber(1);
- before(() => {
- [coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
beforeEach(async () => {
- fillableAmount = new BigNumber(5);
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
+ makerAssetData,
+ takerAssetData,
makerAddress,
takerAddress,
fillableAmount,
@@ -969,18 +379,17 @@ describe('ExchangeWrapper', () => {
// we do need both. A hack is to make the top-level a sync fn w/ a done callback and then
// wrap the rest of the test in an async block
// Source: https://github.com/mochajs/mocha/issues/2407
- it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => {
+ it('Should receive the Fill event when an order is filled', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+ (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill);
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
- shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
})().catch(done);
@@ -988,35 +397,34 @@ describe('ExchangeWrapper', () => {
it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
(async () => {
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
+ (logEvent: DecodedLogEvent<ExchangeCancelEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.Cancel);
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Cancel, indexFilterValues, callback);
+ await contractWrappers.exchange.cancelOrderAsync(signedOrder);
})().catch(done);
});
it('Outstanding subscriptions are cancelled when contractWrappers.setProvider called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callbackNeverToBeCalled);
contractWrappers.setProvider(provider, constants.TESTRPC_NETWORK_ID);
const callback = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
- expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
+ (logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
+ expect(logEvent.log.event).to.be.equal(ExchangeEvents.Fill);
},
);
- contractWrappers.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
+ contractWrappers.exchange.subscribe(ExchangeEvents.Fill, indexFilterValues, callback);
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
- shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
})().catch(done);
@@ -1024,12 +432,12 @@ describe('ExchangeWrapper', () => {
it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => {
(async () => {
const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(
- (_logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
+ (_logEvent: DecodedLogEvent<ExchangeFillEventArgs>) => {
done(new Error('Expected this subscription to have been cancelled'));
},
);
const subscriptionToken = contractWrappers.exchange.subscribe(
- ExchangeEvents.LogFill,
+ ExchangeEvents.Fill,
indexFilterValues,
callbackNeverToBeCalled,
);
@@ -1037,102 +445,36 @@ describe('ExchangeWrapper', () => {
await contractWrappers.exchange.fillOrderAsync(
signedOrder,
takerTokenFillAmountInBaseUnits,
- shouldThrowOnInsufficientBalanceOrAllowance,
takerAddress,
);
done();
})().catch(done);
});
});
- describe('#getOrderHashHexUsingContractCallAsync', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let makerAddress: string;
- let takerAddress: string;
- const fillableAmount = new BigNumber(5);
- before(async () => {
- [, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- it("get's the same hash as the local function", async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const orderHash = getOrderHashHex(signedOrder);
- const orderHashFromContract = await (contractWrappers.exchange as any)._getOrderHashHexUsingContractCallAsync(
- signedOrder,
- );
- expect(orderHash).to.equal(orderHashFromContract);
- });
- });
describe('#getZRXTokenAddressAsync', () => {
it('gets the same token as is in token registry', () => {
- const zrxAddress = contractWrappers.exchange.getZRXTokenAddress();
- const zrxToken = tokenUtils.getProtocolTokenOrThrow();
- expect(zrxAddress).to.equal(zrxToken.address);
+ const zrxAddressFromExchangeWrapper = contractWrappers.exchange.getZRXTokenAddress();
+ const zrxAddress = tokenUtils.getProtocolTokenAddress();
+ expect(zrxAddressFromExchangeWrapper).to.equal(zrxAddress);
});
});
describe('#getLogsAsync', () => {
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let makerAddress: string;
- let takerAddress: string;
- const fillableAmount = new BigNumber(5);
- const shouldThrowOnInsufficientBalanceOrAllowance = true;
- const blockRange: BlockRange = {
+ const blockRange = {
fromBlock: 0,
toBlock: BlockParamLiteral.Latest,
};
- let txHash: string;
- before(async () => {
- [, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- it('should get logs with decoded args emitted by LogFill', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const eventName = ExchangeEvents.LogFill;
+ it('should get logs with decoded args emitted by Fill', async () => {
+ txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+ const eventName = ExchangeEvents.Fill;
const indexFilterValues = {};
const logs = await contractWrappers.exchange.getLogsAsync(eventName, blockRange, indexFilterValues);
expect(logs).to.have.length(1);
expect(logs[0].event).to.be.equal(eventName);
});
it('should only get the logs with the correct event name', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- const differentEventName = ExchangeEvents.LogCancel;
+ txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const differentEventName = ExchangeEvents.Cancel;
const indexFilterValues = {};
const logs = await contractWrappers.exchange.getLogsAsync(
differentEventName,
@@ -1142,86 +484,34 @@ describe('ExchangeWrapper', () => {
expect(logs).to.have.length(0);
});
it('should only get the logs with the correct indexed fields', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- txHash = await contractWrappers.exchange.fillOrderAsync(
- signedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
- takerAddress,
- );
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
-
- const differentMakerAddress = userAddresses[2];
- const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- differentMakerAddress,
+ txHash = await contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
+ const signedOrderWithAnotherMakerAddress = await fillScenarios.createFillableSignedOrderAsync(
+ makerAssetData,
+ takerAssetData,
+ anotherMakerAddress,
takerAddress,
fillableAmount,
);
txHash = await contractWrappers.exchange.fillOrderAsync(
- anotherSignedOrder,
- fillableAmount,
- shouldThrowOnInsufficientBalanceOrAllowance,
+ signedOrderWithAnotherMakerAddress,
+ takerTokenFillAmount,
takerAddress,
);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
+ await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
- const eventName = ExchangeEvents.LogFill;
+ const eventName = ExchangeEvents.Fill;
const indexFilterValues = {
- maker: differentMakerAddress,
+ makerAddress: anotherMakerAddress,
};
- const logs = await contractWrappers.exchange.getLogsAsync<LogFillContractEventArgs>(
+ const logs = await contractWrappers.exchange.getLogsAsync<ExchangeFillEventArgs>(
eventName,
blockRange,
indexFilterValues,
);
expect(logs).to.have.length(1);
const args = logs[0].args;
- expect(args.maker).to.be.equal(differentMakerAddress);
- });
- });
- describe('#getOrderStateAsync', () => {
- let maker: string;
- let taker: string;
- let makerToken: Token;
- let takerToken: Token;
- let signedOrder: SignedOrder;
- let orderState: OrderState;
- const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), constants.ZRX_DECIMALS);
- before(async () => {
- [, maker, taker] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- [makerToken, takerToken] = tokenUtils.getDummyTokens();
- });
- it('should report orderStateValid when order is fillable', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerToken.address,
- takerToken.address,
- maker,
- taker,
- fillableAmount,
- );
- orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.be.true();
- });
- it('should report orderStateInvalid when maker allowance set to 0', async () => {
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerToken.address,
- takerToken.address,
- maker,
- taker,
- fillableAmount,
- );
- await contractWrappers.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0));
- orderState = await contractWrappers.exchange.getOrderStateAsync(signedOrder);
- expect(orderState.isValid).to.be.false();
+ expect(args.makerAddress).to.be.equal(anotherMakerAddress);
});
});
}); // tslint:disable:max-file-line-count
diff --git a/packages/contract-wrappers/test/global_hooks.ts b/packages/contract-wrappers/test/global_hooks.ts
index 52a384ada..bf80e0908 100644
--- a/packages/contract-wrappers/test/global_hooks.ts
+++ b/packages/contract-wrappers/test/global_hooks.ts
@@ -1,5 +1,5 @@
import { devConstants } from '@0xproject/dev-utils';
-import { runV1MigrationsAsync } from '@0xproject/migrations';
+import { runV2MigrationsAsync } from '@0xproject/migrations';
import { provider } from './utils/web3_wrapper';
@@ -12,6 +12,6 @@ before('migrate contracts', async function(): Promise<void> {
gas: devConstants.GAS_LIMIT,
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
- const artifactsDir = `../migrations/artifacts/1.0.0`;
- await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
+ const artifactsDir = `../migrations/artifacts/2.0.0`;
+ await runV2MigrationsAsync(provider, artifactsDir, txDefaults);
});
diff --git a/packages/contract-wrappers/test/order_validation_test.ts b/packages/contract-wrappers/test/order_validation_test.ts
deleted file mode 100644
index 2afea2d5f..000000000
--- a/packages/contract-wrappers/test/order_validation_test.ts
+++ /dev/null
@@ -1,539 +0,0 @@
-import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { FillScenarios } from '@0xproject/fill-scenarios';
-import { OrderError } from '@0xproject/order-utils';
-import { BlockParamLiteral } from '@0xproject/types';
-import { BigNumber } from '@0xproject/utils';
-import * as chai from 'chai';
-import * as Sinon from 'sinon';
-
-import { ContractWrappers, ExchangeContractErrs, SignedOrder, Token } from '../src';
-import { BalanceAndProxyAllowanceLazyStore } from '../src/stores/balance_proxy_allowance_lazy_store';
-import { TradeSide, TransferType } from '../src/types';
-import { ExchangeTransferSimulator } from '../src/utils/exchange_transfer_simulator';
-import { OrderValidationUtils } from '../src/utils/order_validation_utils';
-
-import { chaiSetup } from './utils/chai_setup';
-import { constants } from './utils/constants';
-import { TokenUtils } from './utils/token_utils';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-describe('OrderValidation', () => {
- let contractWrappers: ContractWrappers;
- let userAddresses: string[];
- let tokens: Token[];
- let tokenUtils: TokenUtils;
- let exchangeContractAddress: string;
- let zrxTokenAddress: string;
- let fillScenarios: FillScenarios;
- let makerTokenAddress: string;
- let takerTokenAddress: string;
- let coinbase: string;
- let makerAddress: string;
- let takerAddress: string;
- let feeRecipient: string;
- const fillableAmount = new BigNumber(5);
- const fillTakerAmount = new BigNumber(5);
- const config = {
- networkId: constants.TESTRPC_NETWORK_ID,
- };
- before(async () => {
- contractWrappers = new ContractWrappers(provider, config);
- exchangeContractAddress = contractWrappers.exchange.getContractAddress();
- userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- tokenUtils = new TokenUtils(tokens);
- zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
- fillScenarios = new FillScenarios(provider, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('validateOrderFillableOrThrowAsync', () => {
- it('should succeed if the order is fillable', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
- });
- it('should succeed if the maker is buying ZRX and has no ZRX balance', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- zrxTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- feeRecipient,
- );
- const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress);
- await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
- await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
- });
- it('should succeed if the maker is buying ZRX and has no ZRX balance and there is no specified taker', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- zrxTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- constants.NULL_ADDRESS,
- fillableAmount,
- feeRecipient,
- );
- const zrxMakerBalance = await contractWrappers.token.getBalanceAsync(zrxTokenAddress, makerAddress);
- await contractWrappers.token.transferAsync(zrxTokenAddress, makerAddress, takerAddress, zrxMakerBalance);
- await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
- });
- it('should succeed if the order is asymmetric and fillable', async () => {
- const makerFillableAmount = fillableAmount;
- // tslint:disable-next-line:custom-no-magic-numbers
- const takerFillableAmount = fillableAmount.minus(4);
- const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- makerFillableAmount,
- takerFillableAmount,
- );
- await contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder);
- });
- it('should throw when the order is fully filled or cancelled', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
- return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
- ExchangeContractErrs.OrderRemainingFillAmountZero,
- );
- });
- it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- expirationInPast,
- );
- return expect(contractWrappers.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
- ExchangeContractErrs.OrderFillExpired,
- );
- });
- });
- describe('validateFillOrderAndThrowIfInvalidAsync', () => {
- it('should throw when the fill amount is zero', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const zeroFillAmount = new BigNumber(0);
- return expect(
- contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- zeroFillAmount,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
- });
- it('should throw when the signature is invalid', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- // 27 <--> 28
- // tslint:disable-next-line:custom-no-magic-numbers
- signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
- return expect(
- contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- fillableAmount,
- takerAddress,
- ),
- ).to.be.rejectedWith(OrderError.InvalidSignature);
- });
- it('should throw when the order is fully filled or cancelled', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
- return expect(
- contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- fillableAmount,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
- });
- it('should throw when sender is not a taker', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- // tslint:disable-next-line:custom-no-magic-numbers
- const nonTakerAddress = userAddresses[6];
- return expect(
- contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- fillTakerAmount,
- nonTakerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
- });
- it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- expirationInPast,
- );
- return expect(
- contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- fillTakerAmount,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
- });
- it('should throw when there a rounding error would have occurred', async () => {
- const makerAmount = new BigNumber(3);
- const takerAmount = new BigNumber(5);
- const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- makerAmount,
- takerAmount,
- );
- const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
- return expect(
- contractWrappers.exchange.validateFillOrderThrowIfInvalidAsync(
- signedOrder,
- fillTakerAmountThatCausesRoundingError,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
- });
- });
- describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
- it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
- const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- const tooLargeFillAmount = new BigNumber(7);
- const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
- await contractWrappers.token.transferAsync(takerTokenAddress, coinbase, takerAddress, fillAmountDifference);
- await contractWrappers.token.setProxyAllowanceAsync(takerTokenAddress, takerAddress, tooLargeFillAmount);
- await contractWrappers.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
- await contractWrappers.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
-
- return expect(
- contractWrappers.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
- signedOrder,
- tooLargeFillAmount,
- takerAddress,
- ),
- ).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
- });
- });
- describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
- let signedOrder: SignedOrder;
- const cancelAmount = new BigNumber(3);
- beforeEach(async () => {
- [coinbase, makerAddress, takerAddress] = userAddresses;
- const [makerToken, takerToken] = tokenUtils.getDummyTokens();
- makerTokenAddress = makerToken.address;
- takerTokenAddress = takerToken.address;
- signedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- );
- });
- it('should throw when cancel amount is zero', async () => {
- const zeroCancelAmount = new BigNumber(0);
- return expect(
- contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
- });
- it('should throw when order is expired', async () => {
- const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
- const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- fillableAmount,
- expirationInPast,
- );
- return expect(
- contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
- });
- it('should throw when order is already cancelled or filled', async () => {
- await contractWrappers.exchange.cancelOrderAsync(signedOrder, fillableAmount);
- return expect(
- contractWrappers.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
- ).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
- });
- });
- describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
- let exchangeTransferSimulator: ExchangeTransferSimulator;
- let transferFromAsync: Sinon.SinonSpy;
- const bigNumberMatch = (expected: BigNumber) => {
- return Sinon.match((value: BigNumber) => value.eq(expected));
- };
- beforeEach('create exchangeTransferSimulator', async () => {
- const balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
- contractWrappers.token,
- BlockParamLiteral.Latest,
- );
- exchangeTransferSimulator = new ExchangeTransferSimulator(balanceAndProxyAllowanceLazyStore);
- transferFromAsync = Sinon.spy();
- exchangeTransferSimulator.transferFromAsync = transferFromAsync as any;
- });
- it('should call exchangeTransferSimulator.transferFrom in a correct order', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- feeRecipient,
- );
- await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator,
- signedOrder,
- fillableAmount,
- takerAddress,
- zrxTokenAddress,
- );
- // tslint:disable-next-line:custom-no-magic-numbers
- expect(transferFromAsync.callCount).to.be.equal(4);
- expect(
- transferFromAsync
- .getCall(0)
- .calledWith(
- makerTokenAddress,
- makerAddress,
- takerAddress,
- bigNumberMatch(fillableAmount),
- TradeSide.Maker,
- TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync
- .getCall(1)
- .calledWith(
- takerTokenAddress,
- takerAddress,
- makerAddress,
- bigNumberMatch(fillableAmount),
- TradeSide.Taker,
- TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync
- .getCall(2)
- .calledWith(
- zrxTokenAddress,
- makerAddress,
- feeRecipient,
- bigNumberMatch(makerFee),
- TradeSide.Maker,
- TransferType.Fee,
- ),
- ).to.be.true();
- expect(
- transferFromAsync
- .getCall(3)
- .calledWith(
- zrxTokenAddress,
- takerAddress,
- feeRecipient,
- bigNumberMatch(takerFee),
- TradeSide.Taker,
- TransferType.Fee,
- ),
- ).to.be.true();
- });
- it('should call exchangeTransferSimulator.transferFrom with correct values for an open order', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(2);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- constants.NULL_ADDRESS,
- fillableAmount,
- feeRecipient,
- );
- await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator,
- signedOrder,
- fillableAmount,
- takerAddress,
- zrxTokenAddress,
- );
- // tslint:disable-next-line:custom-no-magic-numbers
- expect(transferFromAsync.callCount).to.be.equal(4);
- expect(
- transferFromAsync
- .getCall(0)
- .calledWith(
- makerTokenAddress,
- makerAddress,
- takerAddress,
- bigNumberMatch(fillableAmount),
- TradeSide.Maker,
- TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync
- .getCall(1)
- .calledWith(
- takerTokenAddress,
- takerAddress,
- makerAddress,
- bigNumberMatch(fillableAmount),
- TradeSide.Taker,
- TransferType.Trade,
- ),
- ).to.be.true();
- expect(
- transferFromAsync
- .getCall(2)
- .calledWith(
- zrxTokenAddress,
- makerAddress,
- feeRecipient,
- bigNumberMatch(makerFee),
- TradeSide.Maker,
- TransferType.Fee,
- ),
- ).to.be.true();
- expect(
- transferFromAsync
- .getCall(3)
- .calledWith(
- zrxTokenAddress,
- takerAddress,
- feeRecipient,
- bigNumberMatch(takerFee),
- TradeSide.Taker,
- TransferType.Fee,
- ),
- ).to.be.true();
- });
- it('should correctly round the fillMakerTokenAmount', async () => {
- const makerTokenAmount = new BigNumber(3);
- const takerTokenAmount = new BigNumber(1);
- const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerAddress,
- takerAddress,
- makerTokenAmount,
- takerTokenAmount,
- );
- await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator,
- signedOrder,
- takerTokenAmount,
- takerAddress,
- zrxTokenAddress,
- );
- // tslint:disable-next-line:custom-no-magic-numbers
- expect(transferFromAsync.callCount).to.be.equal(4);
- const makerFillAmount = transferFromAsync.getCall(0).args[3];
- expect(makerFillAmount).to.be.bignumber.equal(makerTokenAmount);
- });
- it('should correctly round the makerFeeAmount', async () => {
- const makerFee = new BigNumber(2);
- const takerFee = new BigNumber(4);
- const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
- makerTokenAddress,
- takerTokenAddress,
- makerFee,
- takerFee,
- makerAddress,
- takerAddress,
- fillableAmount,
- constants.NULL_ADDRESS,
- );
- const fillTakerTokenAmount = fillableAmount.div(2).round(0);
- await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
- exchangeTransferSimulator,
- signedOrder,
- fillTakerTokenAmount,
- takerAddress,
- zrxTokenAddress,
- );
- const makerPartialFee = makerFee.div(2);
- const takerPartialFee = takerFee.div(2);
- // tslint:disable-next-line:custom-no-magic-numbers
- expect(transferFromAsync.callCount).to.be.equal(4);
- const partialMakerFee = transferFromAsync.getCall(2).args[3];
- expect(partialMakerFee).to.be.bignumber.equal(makerPartialFee);
- const partialTakerFee = transferFromAsync.getCall(3).args[3];
- expect(partialTakerFee).to.be.bignumber.equal(takerPartialFee);
- });
- });
-}); // tslint:disable-line:max-file-line-count
diff --git a/packages/contract-wrappers/test/subscription_test.ts b/packages/contract-wrappers/test/subscription_test.ts
index b9417ca3d..adda4ab78 100644
--- a/packages/contract-wrappers/test/subscription_test.ts
+++ b/packages/contract-wrappers/test/subscription_test.ts
@@ -5,10 +5,11 @@ import * as _ from 'lodash';
import 'mocha';
import * as Sinon from 'sinon';
-import { ApprovalContractEventArgs, ContractWrappers, DecodedLogEvent, Token, TokenEvents } from '../src';
+import { ContractWrappers, DecodedLogEvent, ERC20TokenApprovalEventArgs, ERC20TokenEvents, Token } from '../src';
import { chaiSetup } from './utils/chai_setup';
import { constants } from './utils/constants';
+import { tokenUtils } from './utils/token_utils';
import { provider, web3Wrapper } from './utils/web3_wrapper';
chaiSetup.configure();
@@ -17,7 +18,6 @@ const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
describe('SubscriptionTest', () => {
let contractWrappers: ContractWrappers;
let userAddresses: string[];
- let tokens: Token[];
let coinbase: string;
let addressWithoutFunds: string;
const config = {
@@ -26,7 +26,6 @@ describe('SubscriptionTest', () => {
before(async () => {
contractWrappers = new ContractWrappers(provider, config);
userAddresses = await web3Wrapper.getAvailableAddressesAsync();
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
coinbase = userAddresses[0];
addressWithoutFunds = userAddresses[1];
});
@@ -42,11 +41,11 @@ describe('SubscriptionTest', () => {
const allowanceAmount = new BigNumber(42);
let stubs: Sinon.SinonStub[] = [];
before(() => {
- const token = tokens[0];
- tokenAddress = token.address;
+ const tokenAddresses = tokenUtils.getDummyERC20TokenAddresses();
+ tokenAddress = tokenAddresses[0];
});
afterEach(() => {
- contractWrappers.token.unsubscribeAll();
+ contractWrappers.erc20Token.unsubscribeAll();
_.each(stubs, s => s.restore());
stubs = [];
});
@@ -55,8 +54,13 @@ describe('SubscriptionTest', () => {
const errMsg = 'Error fetching block';
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
- contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
- await contractWrappers.token.setAllowanceAsync(
+ contractWrappers.erc20Token.subscribe(
+ tokenAddress,
+ ERC20TokenEvents.Approval,
+ indexFilterValues,
+ callback,
+ );
+ await contractWrappers.erc20Token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
@@ -69,8 +73,13 @@ describe('SubscriptionTest', () => {
const errMsg = 'Error fetching logs';
const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
- contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
- await contractWrappers.token.setAllowanceAsync(
+ contractWrappers.erc20Token.subscribe(
+ tokenAddress,
+ ERC20TokenEvents.Approval,
+ indexFilterValues,
+ callback,
+ );
+ await contractWrappers.erc20Token.setAllowanceAsync(
tokenAddress,
coinbase,
addressWithoutFunds,
@@ -80,14 +89,20 @@ describe('SubscriptionTest', () => {
});
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
(async () => {
- const callback = (_err: Error | null, _logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
- contractWrappers.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
+ const callback = (err: Error | null, _logEvent?: DecodedLogEvent<ERC20TokenApprovalEventArgs>) =>
+ _.noop;
+ contractWrappers.erc20Token.subscribe(
+ tokenAddress,
+ ERC20TokenEvents.Approval,
+ indexFilterValues,
+ callback,
+ );
stubs = [
Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(
new Error('JSON RPC error'),
),
];
- contractWrappers.token.unsubscribeAll();
+ contractWrappers.erc20Token.unsubscribeAll();
done();
})().catch(done);
});
diff --git a/packages/contract-wrappers/test/token_registry_wrapper_test.ts b/packages/contract-wrappers/test/token_registry_wrapper_test.ts
deleted file mode 100644
index 6576d789d..000000000
--- a/packages/contract-wrappers/test/token_registry_wrapper_test.ts
+++ /dev/null
@@ -1,136 +0,0 @@
-import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { schemas, SchemaValidator } from '@0xproject/json-schemas';
-import * as chai from 'chai';
-import * as _ from 'lodash';
-import 'mocha';
-
-import { ContractWrappers, Token } from '../src';
-
-import { chaiSetup } from './utils/chai_setup';
-import { constants } from './utils/constants';
-import { provider, web3Wrapper } from './utils/web3_wrapper';
-
-chaiSetup.configure();
-const expect = chai.expect;
-const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
-
-const TOKEN_REGISTRY_SIZE_AFTER_MIGRATION = 7;
-
-describe('TokenRegistryWrapper', () => {
- let contractWrappers: ContractWrappers;
- let tokens: Token[];
- const tokenAddressBySymbol: { [symbol: string]: string } = {};
- const tokenAddressByName: { [symbol: string]: string } = {};
- const tokenBySymbol: { [symbol: string]: Token } = {};
- const tokenByName: { [symbol: string]: Token } = {};
- const registeredSymbol = 'ZRX';
- const registeredName = '0x Protocol Token';
- const unregisteredSymbol = 'MAL';
- const unregisteredName = 'Malicious Token';
- const config = {
- networkId: constants.TESTRPC_NETWORK_ID,
- };
- before(async () => {
- contractWrappers = new ContractWrappers(provider, config);
- tokens = await contractWrappers.tokenRegistry.getTokensAsync();
- _.map(tokens, token => {
- tokenAddressBySymbol[token.symbol] = token.address;
- tokenAddressByName[token.name] = token.address;
- tokenBySymbol[token.symbol] = token;
- tokenByName[token.name] = token;
- });
- });
- beforeEach(async () => {
- await blockchainLifecycle.startAsync();
- });
- afterEach(async () => {
- await blockchainLifecycle.revertAsync();
- });
- describe('#getTokensAsync', () => {
- it('should return all the tokens added to the tokenRegistry during the migration', async () => {
- expect(tokens).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
-
- const schemaValidator = new SchemaValidator();
- _.each(tokens, token => {
- const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
- expect(validationResult.errors).to.have.lengthOf(0);
- });
- });
- });
- describe('#getTokenAddressesAsync', () => {
- it('should return all the token addresses added to the tokenRegistry during the migration', async () => {
- const tokenAddresses = await contractWrappers.tokenRegistry.getTokenAddressesAsync();
- expect(tokenAddresses).to.have.lengthOf(TOKEN_REGISTRY_SIZE_AFTER_MIGRATION);
-
- const schemaValidator = new SchemaValidator();
- _.each(tokenAddresses, tokenAddress => {
- const validationResult = schemaValidator.validate(tokenAddress, schemas.addressSchema);
- expect(validationResult.errors).to.have.lengthOf(0);
- expect(tokenAddress).to.not.be.equal(constants.NULL_ADDRESS);
- });
- });
- });
- describe('#getTokenAddressBySymbol', () => {
- it('should return correct address for a token in the registry', async () => {
- const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(
- registeredSymbol,
- );
- expect(tokenAddress).to.be.equal(tokenAddressBySymbol[registeredSymbol]);
- });
- it('should return undefined for a token out of registry', async () => {
- const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressBySymbolIfExistsAsync(
- unregisteredSymbol,
- );
- expect(tokenAddress).to.be.undefined();
- });
- });
- describe('#getTokenAddressByName', () => {
- it('should return correct address for a token in the registry', async () => {
- const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync(
- registeredName,
- );
- expect(tokenAddress).to.be.equal(tokenAddressByName[registeredName]);
- });
- it('should return undefined for a token out of registry', async () => {
- const tokenAddress = await contractWrappers.tokenRegistry.getTokenAddressByNameIfExistsAsync(
- unregisteredName,
- );
- expect(tokenAddress).to.be.undefined();
- });
- });
- describe('#getTokenBySymbol', () => {
- it('should return correct token for a token in the registry', async () => {
- const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(registeredSymbol);
- expect(token).to.be.deep.equal(tokenBySymbol[registeredSymbol]);
- });
- it('should return undefined for a token out of registry', async () => {
- const token = await contractWrappers.tokenRegistry.getTokenBySymbolIfExistsAsync(unregisteredSymbol);
- expect(token).to.be.undefined();
- });
- });
- describe('#getTokenByName', () => {
- it('should return correct token for a token in the registry', async () => {
- const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(registeredName);
- expect(token).to.be.deep.equal(tokenByName[registeredName]);
- });
- it('should return undefined for a token out of registry', async () => {
- const token = await contractWrappers.tokenRegistry.getTokenByNameIfExistsAsync(unregisteredName);
- expect(token).to.be.undefined();
- });
- });
- describe('#getTokenIfExistsAsync', () => {
- it('should return the token added to the tokenRegistry during the migration', async () => {
- const aToken = tokens[0];
-
- const token = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(aToken.address);
- const schemaValidator = new SchemaValidator();
- const validationResult = schemaValidator.validate(token, schemas.tokenSchema);
- expect(validationResult.errors).to.have.lengthOf(0);
- });
- it('should return return undefined when passed a token address not in the tokenRegistry', async () => {
- const unregisteredTokenAddress = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
- const tokenIfExists = await contractWrappers.tokenRegistry.getTokenIfExistsAsync(unregisteredTokenAddress);
- expect(tokenIfExists).to.be.undefined();
- });
- });
-});
diff --git a/packages/contract-wrappers/test/utils/constants.ts b/packages/contract-wrappers/test/utils/constants.ts
index cf030259c..60c3370a2 100644
--- a/packages/contract-wrappers/test/utils/constants.ts
+++ b/packages/contract-wrappers/test/utils/constants.ts
@@ -1,9 +1,18 @@
+import { BigNumber } from '@0xproject/utils';
+
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
ROPSTEN_NETWORK_ID: 3,
KOVAN_NETWORK_ID: 42,
TESTRPC_NETWORK_ID: 50,
+ AWAIT_TRANSACTION_MINED_MS: 0,
KOVAN_RPC_URL: 'https://kovan.infura.io/',
ROPSTEN_RPC_URL: 'https://ropsten.infura.io/',
ZRX_DECIMALS: 18,
+ DUMMY_TOKEN_NAME: '',
+ DUMMY_TOKEN_SYMBOL: '',
+ DUMMY_TOKEN_DECIMALS: 18,
+ DUMMY_TOKEN_TOTAL_SUPPLY: new BigNumber(10 ** 27), // tslint:disable-line:custom-no-magic-numbers
+ NUM_DUMMY_ERC20_TO_DEPLOY: 3,
+ NUM_DUMMY_ERC721_TO_DEPLOY: 1,
};
diff --git a/packages/contract-wrappers/test/utils/token_utils.ts b/packages/contract-wrappers/test/utils/token_utils.ts
index fe85de085..06a82ff6e 100644
--- a/packages/contract-wrappers/test/utils/token_utils.ts
+++ b/packages/contract-wrappers/test/utils/token_utils.ts
@@ -1,33 +1,47 @@
-import * as _ from 'lodash';
+import { generatePseudoRandomSalt } from '@0xproject/order-utils';
+import { BigNumber } from '@0xproject/utils';
-import { InternalContractWrappersError, Token } from '../../src/types';
+import { artifacts } from '../../src/artifacts';
+import { DummyERC721TokenContract } from '../../src/contract_wrappers/generated/dummy_erc721_token';
-const PROTOCOL_TOKEN_SYMBOL = 'ZRX';
-const WETH_TOKEN_SYMBOL = 'WETH';
+import { constants } from './constants';
+import { provider, txDefaults, web3Wrapper } from './web3_wrapper';
-export class TokenUtils {
- private _tokens: Token[];
- constructor(tokens: Token[]) {
- this._tokens = tokens;
- }
- public getProtocolTokenOrThrow(): Token {
- const zrxToken = _.find(this._tokens, { symbol: PROTOCOL_TOKEN_SYMBOL });
- if (_.isUndefined(zrxToken)) {
- throw new Error(InternalContractWrappersError.ZrxNotInTokenRegistry);
- }
- return zrxToken;
- }
- public getWethTokenOrThrow(): Token {
- const wethToken = _.find(this._tokens, { symbol: WETH_TOKEN_SYMBOL });
- if (_.isUndefined(wethToken)) {
- throw new Error(InternalContractWrappersError.WethNotInTokenRegistry);
- }
- return wethToken;
- }
- public getDummyTokens(): Token[] {
- const dummyTokens = _.filter(this._tokens, token => {
- return !_.includes([PROTOCOL_TOKEN_SYMBOL, WETH_TOKEN_SYMBOL], token.symbol);
- });
- return dummyTokens;
- }
-}
+// Those addresses come from migrations. They're deterministic so it's relatively safe to hard-code them here.
+// Before we were fetching them from the TokenRegistry but now we can't as it's deprecated and removed.
+const DUMMY_ERC_20_ADRESSES = [
+ '0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f',
+ '0xcfc18cec799fbd1793b5c43e773c98d4d61cc2db',
+ '0xf22469f31527adc53284441bae1665a7b9214dba',
+ '0x10add991de718a69dec2117cb6aa28098836511b',
+ '0x8d61158a366019ac78db4149d75fff9dda51160d',
+];
+
+const DUMMY_ERC_721_ADRESSES = ['0x131855dda0aaff096f6854854c55a4debf61077a'];
+
+export const tokenUtils = {
+ getProtocolTokenAddress(): string {
+ return artifacts.ZRXToken.networks[constants.TESTRPC_NETWORK_ID].address;
+ },
+ getWethTokenAddress(): string {
+ return artifacts.EtherToken.networks[constants.TESTRPC_NETWORK_ID].address;
+ },
+ getDummyERC20TokenAddresses(): string[] {
+ return DUMMY_ERC_20_ADRESSES;
+ },
+ getDummyERC721TokenAddresses(): string[] {
+ return DUMMY_ERC_721_ADRESSES;
+ },
+ async mintDummyERC721Async(address: string, tokenOwner: string): Promise<BigNumber> {
+ const erc721 = new DummyERC721TokenContract(
+ artifacts.DummyERC721Token.compilerOutput.abi,
+ address,
+ provider,
+ txDefaults,
+ );
+ const tokenId = generatePseudoRandomSalt();
+ const txHash = await erc721.mint.sendTransactionAsync(tokenOwner, tokenId);
+ web3Wrapper.awaitTransactionSuccessAsync(txHash);
+ return tokenId;
+ },
+};
diff --git a/packages/contract-wrappers/test/utils/web3_wrapper.ts b/packages/contract-wrappers/test/utils/web3_wrapper.ts
index f7d11f138..02c8c5918 100644
--- a/packages/contract-wrappers/test/utils/web3_wrapper.ts
+++ b/packages/contract-wrappers/test/utils/web3_wrapper.ts
@@ -1,8 +1,12 @@
-import { web3Factory } from '@0xproject/dev-utils';
-import { Provider } from '@0xproject/types';
+import { devConstants, web3Factory } from '@0xproject/dev-utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import { Provider } from 'ethereum-types';
+const txDefaults = {
+ from: devConstants.TESTRPC_FIRST_ADDRESS,
+ gas: devConstants.GAS_LIMIT,
+};
const provider: Provider = web3Factory.getRpcProvider({ shouldUseInProcessGanache: true });
const web3Wrapper = new Web3Wrapper(provider);
-export { provider, web3Wrapper };
+export { provider, web3Wrapper, txDefaults };