Apply prettier config
This commit is contained in:
parent
9a96e8c704
commit
e744e4cd98
@ -26,3 +26,4 @@ jobs:
|
|||||||
background: true
|
background: true
|
||||||
- run: yarn lerna:run test:circleci
|
- run: yarn lerna:run test:circleci
|
||||||
- run: yarn lerna:run lint
|
- run: yarn lerna:run lint
|
||||||
|
- run: yarn prettier:ci
|
||||||
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
lib
|
||||||
|
generated
|
6
.prettierrc
Normal file
6
.prettierrc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"tabWidth": 4,
|
||||||
|
"printWidth": 120,
|
||||||
|
"trailingComma": all,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
10
package.json
10
package.json
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "0x.js",
|
"name": "0x.js",
|
||||||
"workspaces": [
|
"workspaces": ["packages/*"],
|
||||||
"packages/*"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
|
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
|
||||||
"prettier": "prettier --write '**/*.ts'",
|
"prettier": "prettier --write '**/*.{ts,tsx}'",
|
||||||
|
"prettier:ci": "prettier --list-different '**/*.{ts,tsx}'",
|
||||||
"lerna:run": "lerna run",
|
"lerna:run": "lerna run",
|
||||||
"lerna:rebuild": "lerna run clean; lerna run build;",
|
"lerna:rebuild": "lerna run clean; lerna run build;",
|
||||||
"lerna:publish": "yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
|
"lerna:publish":
|
||||||
|
"yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
"mnemonic": "concert load couple harbor equip island argue ramp clarify fence smart topic"
|
||||||
|
@ -188,12 +188,7 @@ export class ZeroEx {
|
|||||||
config.networkId,
|
config.networkId,
|
||||||
config.tokenTransferProxyContractAddress,
|
config.tokenTransferProxyContractAddress,
|
||||||
);
|
);
|
||||||
this.token = new TokenWrapper(
|
this.token = new TokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.proxy);
|
||||||
this._web3Wrapper,
|
|
||||||
config.networkId,
|
|
||||||
this._abiDecoder,
|
|
||||||
this.proxy,
|
|
||||||
);
|
|
||||||
this.exchange = new ExchangeWrapper(
|
this.exchange = new ExchangeWrapper(
|
||||||
this._web3Wrapper,
|
this._web3Wrapper,
|
||||||
config.networkId,
|
config.networkId,
|
||||||
@ -202,13 +197,17 @@ export class ZeroEx {
|
|||||||
config.exchangeContractAddress,
|
config.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
this.tokenRegistry = new TokenRegistryWrapper(
|
this.tokenRegistry = new TokenRegistryWrapper(
|
||||||
this._web3Wrapper, config.networkId, config.tokenRegistryContractAddress,
|
this._web3Wrapper,
|
||||||
);
|
config.networkId,
|
||||||
this.etherToken = new EtherTokenWrapper(
|
config.tokenRegistryContractAddress,
|
||||||
this._web3Wrapper, config.networkId, this._abiDecoder, this.token,
|
|
||||||
);
|
);
|
||||||
|
this.etherToken = new EtherTokenWrapper(this._web3Wrapper, config.networkId, this._abiDecoder, this.token);
|
||||||
this.orderStateWatcher = new OrderStateWatcher(
|
this.orderStateWatcher = new OrderStateWatcher(
|
||||||
this._web3Wrapper, this._abiDecoder, this.token, this.exchange, config.orderWatcherConfig,
|
this._web3Wrapper,
|
||||||
|
this._abiDecoder,
|
||||||
|
this.token,
|
||||||
|
this.exchange,
|
||||||
|
config.orderWatcherConfig,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -291,10 +290,13 @@ export class ZeroEx {
|
|||||||
* @return Transaction receipt with decoded log args.
|
* @return Transaction receipt with decoded log args.
|
||||||
*/
|
*/
|
||||||
public async awaitTransactionMinedAsync(
|
public async awaitTransactionMinedAsync(
|
||||||
txHash: string, pollingIntervalMs = 1000, timeoutMs?: number): Promise<TransactionReceiptWithDecodedLogs> {
|
txHash: string,
|
||||||
|
pollingIntervalMs = 1000,
|
||||||
|
timeoutMs?: number,
|
||||||
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
let timeoutExceeded = false;
|
let timeoutExceeded = false;
|
||||||
if (timeoutMs) {
|
if (timeoutMs) {
|
||||||
setTimeout(() => timeoutExceeded = true, timeoutMs);
|
setTimeout(() => (timeoutExceeded = true), timeoutMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txReceiptPromise = new Promise(
|
const txReceiptPromise = new Promise(
|
||||||
@ -319,7 +321,8 @@ export class ZeroEx {
|
|||||||
resolve(transactionReceiptWithDecodedLogArgs);
|
resolve(transactionReceiptWithDecodedLogArgs);
|
||||||
}
|
}
|
||||||
}, pollingIntervalMs);
|
}, pollingIntervalMs);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return txReceiptPromise;
|
return txReceiptPromise;
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@ import * as ZRXArtifact from './artifacts/ZRX.json';
|
|||||||
import { Artifact } from './types';
|
import { Artifact } from './types';
|
||||||
|
|
||||||
export const artifacts = {
|
export const artifacts = {
|
||||||
ZRXArtifact: ZRXArtifact as any as Artifact,
|
ZRXArtifact: (ZRXArtifact as any) as Artifact,
|
||||||
DummyTokenArtifact: DummyTokenArtifact as any as Artifact,
|
DummyTokenArtifact: (DummyTokenArtifact as any) as Artifact,
|
||||||
TokenArtifact: TokenArtifact as any as Artifact,
|
TokenArtifact: (TokenArtifact as any) as Artifact,
|
||||||
ExchangeArtifact: ExchangeArtifact as any as Artifact,
|
ExchangeArtifact: (ExchangeArtifact as any) as Artifact,
|
||||||
EtherTokenArtifact: EtherTokenArtifact as any as Artifact,
|
EtherTokenArtifact: (EtherTokenArtifact as any) as Artifact,
|
||||||
TokenRegistryArtifact: TokenRegistryArtifact as any as Artifact,
|
TokenRegistryArtifact: (TokenRegistryArtifact as any) as Artifact,
|
||||||
TokenTransferProxyArtifact: TokenTransferProxyArtifact as any as Artifact,
|
TokenTransferProxyArtifact: (TokenTransferProxyArtifact as any) as Artifact,
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,9 @@ import {AbiDecoder} from '../utils/abi_decoder';
|
|||||||
import { constants } from '../utils/constants';
|
import { constants } from '../utils/constants';
|
||||||
import { filterUtils } from '../utils/filter_utils';
|
import { filterUtils } from '../utils/filter_utils';
|
||||||
|
|
||||||
const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {[contractName: string]: ZeroExError} = {
|
const CONTRACT_NAME_TO_NOT_FOUND_ERROR: {
|
||||||
|
[contractName: string]: ZeroExError;
|
||||||
|
} = {
|
||||||
ZRX: ZeroExError.ZRXContractDoesNotExist,
|
ZRX: ZeroExError.ZRXContractDoesNotExist,
|
||||||
EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
|
EtherToken: ZeroExError.EtherTokenContractDoesNotExist,
|
||||||
Token: ZeroExError.TokenContractDoesNotExist,
|
Token: ZeroExError.TokenContractDoesNotExist,
|
||||||
@ -37,7 +39,9 @@ export class ContractWrapper {
|
|||||||
private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
|
private _blockAndLogStreamerIfExists: BlockAndLogStreamer | undefined;
|
||||||
private _blockAndLogStreamInterval: NodeJS.Timer;
|
private _blockAndLogStreamInterval: NodeJS.Timer;
|
||||||
private _filters: { [filterToken: string]: Web3.FilterObject };
|
private _filters: { [filterToken: string]: Web3.FilterObject };
|
||||||
private _filterCallbacks: {[filterToken: string]: EventCallback<ContractEventArgs>};
|
private _filterCallbacks: {
|
||||||
|
[filterToken: string]: EventCallback<ContractEventArgs>;
|
||||||
|
};
|
||||||
private _onLogAddedSubscriptionToken: string | undefined;
|
private _onLogAddedSubscriptionToken: string | undefined;
|
||||||
private _onLogRemovedSubscriptionToken: string | undefined;
|
private _onLogRemovedSubscriptionToken: string | undefined;
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
|
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder?: AbiDecoder) {
|
||||||
@ -71,8 +75,12 @@ export class ContractWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected _subscribe<ArgsType extends ContractEventArgs>(
|
protected _subscribe<ArgsType extends ContractEventArgs>(
|
||||||
address: string, eventName: ContractEvents, indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi,
|
address: string,
|
||||||
callback: EventCallback<ArgsType>): string {
|
eventName: ContractEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
abi: Web3.ContractAbi,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
|
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
|
||||||
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||||
this._startBlockAndLogStream();
|
this._startBlockAndLogStream();
|
||||||
@ -83,15 +91,20 @@ export class ContractWrapper {
|
|||||||
return filterToken;
|
return filterToken;
|
||||||
}
|
}
|
||||||
protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
|
protected async _getLogsAsync<ArgsType extends ContractEventArgs>(
|
||||||
address: string, eventName: ContractEvents, blockRange: BlockRange,
|
address: string,
|
||||||
indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
eventName: ContractEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
abi: Web3.ContractAbi,
|
||||||
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
|
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi, blockRange);
|
||||||
const logs = await this._web3Wrapper.getLogsAsync(filter);
|
const logs = await this._web3Wrapper.getLogsAsync(filter);
|
||||||
const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
|
const logsWithDecodedArguments = _.map(logs, this._tryToDecodeLogOrNoop.bind(this));
|
||||||
return logsWithDecodedArguments;
|
return logsWithDecodedArguments;
|
||||||
}
|
}
|
||||||
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
protected _tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
||||||
log: Web3.LogEntry): LogWithDecodedArgs<ArgsType>|RawLog {
|
log: Web3.LogEntry,
|
||||||
|
): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||||
if (_.isUndefined(this._abiDecoder)) {
|
if (_.isUndefined(this._abiDecoder)) {
|
||||||
throw new Error(InternalZeroExError.NoAbiDecoder);
|
throw new Error(InternalZeroExError.NoAbiDecoder);
|
||||||
}
|
}
|
||||||
@ -99,7 +112,8 @@ export class ContractWrapper {
|
|||||||
return logWithDecodedArgs;
|
return logWithDecodedArgs;
|
||||||
}
|
}
|
||||||
protected async _instantiateContractIfExistsAsync(
|
protected async _instantiateContractIfExistsAsync(
|
||||||
artifact: Artifact, addressIfExists?: string,
|
artifact: Artifact,
|
||||||
|
addressIfExists?: string,
|
||||||
): Promise<Web3.ContractInstance> {
|
): Promise<Web3.ContractInstance> {
|
||||||
let contractAddress: string;
|
let contractAddress: string;
|
||||||
if (_.isUndefined(addressIfExists)) {
|
if (_.isUndefined(addressIfExists)) {
|
||||||
@ -114,9 +128,7 @@ export class ContractWrapper {
|
|||||||
if (!doesContractExist) {
|
if (!doesContractExist) {
|
||||||
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
throw new Error(CONTRACT_NAME_TO_NOT_FOUND_ERROR[artifact.contract_name]);
|
||||||
}
|
}
|
||||||
const contractInstance = this._web3Wrapper.getContractInstance(
|
const contractInstance = this._web3Wrapper.getContractInstance(artifact.abi, contractAddress);
|
||||||
artifact.abi, contractAddress,
|
|
||||||
);
|
|
||||||
return contractInstance;
|
return contractInstance;
|
||||||
}
|
}
|
||||||
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
protected _getContractAddress(artifact: Artifact, addressIfExists?: string): string {
|
||||||
@ -153,7 +165,8 @@ export class ContractWrapper {
|
|||||||
const catchAllLogFilter = {};
|
const catchAllLogFilter = {};
|
||||||
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
|
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
|
||||||
this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
|
this._blockAndLogStreamInterval = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._reconcileBlockAsync.bind(this), constants.DEFAULT_BLOCK_POLLING_INTERVAL,
|
this._reconcileBlockAsync.bind(this),
|
||||||
|
constants.DEFAULT_BLOCK_POLLING_INTERVAL,
|
||||||
);
|
);
|
||||||
let isRemoved = false;
|
let isRemoved = false;
|
||||||
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
|
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
|
||||||
@ -179,7 +192,7 @@ export class ContractWrapper {
|
|||||||
// We need to coerce to Block type cause Web3.Block includes types for mempool blocks
|
// We need to coerce to Block type cause Web3.Block includes types for mempool blocks
|
||||||
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
|
||||||
// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
|
// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
|
||||||
await this._blockAndLogStreamerIfExists.reconcileNewBlock(latestBlock as any as Block);
|
await this._blockAndLogStreamerIfExists.reconcileNewBlock((latestBlock as any) as Block);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const filterTokens = _.keys(this._filterCallbacks);
|
const filterTokens = _.keys(this._filterCallbacks);
|
||||||
|
@ -26,7 +26,9 @@ import {TokenWrapper} from './token_wrapper';
|
|||||||
* The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
|
* The caller can convert ETH into the equivalent number of wrapped ETH ERC20 tokens and back.
|
||||||
*/
|
*/
|
||||||
export class EtherTokenWrapper extends ContractWrapper {
|
export class EtherTokenWrapper extends ContractWrapper {
|
||||||
private _etherTokenContractsByAddress: {[address: string]: EtherTokenContract} = {};
|
private _etherTokenContractsByAddress: {
|
||||||
|
[address: string]: EtherTokenContract;
|
||||||
|
} = {};
|
||||||
private _tokenWrapper: TokenWrapper;
|
private _tokenWrapper: TokenWrapper;
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
|
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder, tokenWrapper: TokenWrapper) {
|
||||||
super(web3Wrapper, networkId, abiDecoder);
|
super(web3Wrapper, networkId, abiDecoder);
|
||||||
@ -43,7 +45,10 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async depositAsync(
|
public async depositAsync(
|
||||||
etherTokenAddress: string, amountInWei: BigNumber, depositor: string, txOpts: TransactionOpts = {},
|
etherTokenAddress: string,
|
||||||
|
amountInWei: BigNumber,
|
||||||
|
depositor: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
|
||||||
@ -70,7 +75,10 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async withdrawAsync(
|
public async withdrawAsync(
|
||||||
etherTokenAddress: string, amountInWei: BigNumber, withdrawer: string, txOpts: TransactionOpts = {},
|
etherTokenAddress: string,
|
||||||
|
amountInWei: BigNumber,
|
||||||
|
withdrawer: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
||||||
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
|
||||||
@ -96,14 +104,21 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Array of logs that match the parameters
|
* @return Array of logs that match the parameters
|
||||||
*/
|
*/
|
||||||
public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
|
public async getLogsAsync<ArgsType extends EtherTokenContractEventArgs>(
|
||||||
etherTokenAddress: string, eventName: EtherTokenEvents, blockRange: BlockRange,
|
etherTokenAddress: string,
|
||||||
indexFilterValues: IndexedFilterValues): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
eventName: EtherTokenEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues, artifacts.EtherTokenArtifact.abi,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.EtherTokenArtifact.abi,
|
||||||
);
|
);
|
||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
@ -117,14 +132,21 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
* @return Subscription token used later to unsubscribe
|
* @return Subscription token used later to unsubscribe
|
||||||
*/
|
*/
|
||||||
public subscribe<ArgsType extends EtherTokenContractEventArgs>(
|
public subscribe<ArgsType extends EtherTokenContractEventArgs>(
|
||||||
etherTokenAddress: string, eventName: EtherTokenEvents, indexFilterValues: IndexedFilterValues,
|
etherTokenAddress: string,
|
||||||
callback: EventCallback<ArgsType>): string {
|
eventName: EtherTokenEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
etherTokenAddress, eventName, indexFilterValues, artifacts.EtherTokenArtifact.abi, callback,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.EtherTokenArtifact.abi,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
return subscriptionToken;
|
return subscriptionToken;
|
||||||
}
|
}
|
||||||
@ -151,7 +173,8 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
return etherTokenContract;
|
return etherTokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.EtherTokenArtifact, etherTokenAddress,
|
artifacts.EtherTokenArtifact,
|
||||||
|
etherTokenAddress,
|
||||||
);
|
);
|
||||||
const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
etherTokenContract = contractInstance;
|
etherTokenContract = contractInstance;
|
||||||
|
@ -81,8 +81,13 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
];
|
];
|
||||||
return [orderAddresses, orderValues];
|
return [orderAddresses, orderValues];
|
||||||
}
|
}
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder,
|
constructor(
|
||||||
tokenWrapper: TokenWrapper, contractAddressIfExists?: string) {
|
web3Wrapper: Web3Wrapper,
|
||||||
|
networkId: number,
|
||||||
|
abiDecoder: AbiDecoder,
|
||||||
|
tokenWrapper: TokenWrapper,
|
||||||
|
contractAddressIfExists?: string,
|
||||||
|
) {
|
||||||
super(web3Wrapper, networkId, abiDecoder);
|
super(web3Wrapper, networkId, abiDecoder);
|
||||||
this._tokenWrapper = tokenWrapper;
|
this._tokenWrapper = tokenWrapper;
|
||||||
this._orderValidationUtils = new OrderValidationUtils(this);
|
this._orderValidationUtils = new OrderValidationUtils(this);
|
||||||
@ -97,14 +102,14 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
* @return The amount of the order (in taker tokens) that has either been filled or cancelled.
|
* @return The amount of the order (in taker tokens) that has either been filled or cancelled.
|
||||||
*/
|
*/
|
||||||
public async getUnavailableTakerAmountAsync(orderHash: string,
|
public async getUnavailableTakerAmountAsync(orderHash: string, methodOpts?: MethodOpts): Promise<BigNumber> {
|
||||||
methodOpts?: MethodOpts): Promise<BigNumber> {
|
|
||||||
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
|
assert.doesConformToSchema('orderHash', orderHash, schemas.orderHashSchema);
|
||||||
|
|
||||||
const exchangeContract = await this._getExchangeContractAsync();
|
const exchangeContract = await this._getExchangeContractAsync();
|
||||||
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock;
|
||||||
let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
let unavailableTakerTokenAmount = await exchangeContract.getUnavailableTakerTokenAmount.callAsync(
|
||||||
orderHash, defaultBlock,
|
orderHash,
|
||||||
|
defaultBlock,
|
||||||
);
|
);
|
||||||
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
unavailableTakerTokenAmount = new BigNumber(unavailableTakerTokenAmount);
|
unavailableTakerTokenAmount = new BigNumber(unavailableTakerTokenAmount);
|
||||||
@ -163,24 +168,32 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async fillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
public async fillOrderAsync(
|
||||||
|
signedOrder: SignedOrder,
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
||||||
@ -219,30 +232,42 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async fillOrdersUpToAsync(signedOrders: SignedOrder[], fillTakerTokenAmount: BigNumber,
|
public async fillOrdersUpToAsync(
|
||||||
|
signedOrders: SignedOrder[],
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
|
assert.doesConformToSchema('signedOrders', signedOrders, schemas.signedOrdersSchema);
|
||||||
const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress);
|
const takerTokenAddresses = _.map(signedOrders, signedOrder => signedOrder.takerTokenAddress);
|
||||||
assert.hasAtMostOneUniqueValue(takerTokenAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed);
|
takerTokenAddresses,
|
||||||
|
ExchangeContractErrs.MultipleTakerTokensInFillUpToDisallowed,
|
||||||
|
);
|
||||||
const exchangeContractAddresses = _.map(signedOrders, signedOrder => signedOrder.exchangeContractAddress);
|
const exchangeContractAddresses = _.map(signedOrders, signedOrder => signedOrder.exchangeContractAddress);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
for (const signedOrder of signedOrders) {
|
for (const signedOrder of signedOrders) {
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,29 +325,36 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async batchFillOrdersAsync(orderFillRequests: OrderFillRequest[],
|
public async batchFillOrdersAsync(
|
||||||
|
orderFillRequests: OrderFillRequest[],
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderFillRequests,
|
orderFillRequests,
|
||||||
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
for (const orderFillRequest of orderFillRequests) {
|
for (const orderFillRequest of orderFillRequests) {
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount,
|
exchangeTradeEmulator,
|
||||||
takerAddress, zrxTokenAddress,
|
orderFillRequest.signedOrder,
|
||||||
|
orderFillRequest.takerTokenFillAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,23 +405,31 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async fillOrKillOrderAsync(signedOrder: SignedOrder, fillTakerTokenAmount: BigNumber,
|
public async fillOrKillOrderAsync(
|
||||||
|
signedOrder: SignedOrder,
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(signedOrder);
|
||||||
@ -418,33 +458,39 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async batchFillOrKillAsync(orderFillRequests: OrderFillRequest[],
|
public async batchFillOrKillAsync(
|
||||||
|
orderFillRequests: OrderFillRequest[],
|
||||||
takerAddress: string,
|
takerAddress: string,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
assert.doesConformToSchema('orderFillRequests', orderFillRequests,
|
): Promise<string> {
|
||||||
schemas.orderFillRequestsSchema);
|
assert.doesConformToSchema('orderFillRequests', orderFillRequests, schemas.orderFillRequestsSchema);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderFillRequests,
|
orderFillRequests,
|
||||||
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
orderFillRequest => orderFillRequest.signedOrder.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
if (_.isEmpty(orderFillRequests)) {
|
if (_.isEmpty(orderFillRequests)) {
|
||||||
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
}
|
}
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
for (const orderFillRequest of orderFillRequests) {
|
for (const orderFillRequest of orderFillRequests) {
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount,
|
exchangeTradeEmulator,
|
||||||
takerAddress, zrxTokenAddress,
|
orderFillRequest.signedOrder,
|
||||||
|
orderFillRequest.takerTokenFillAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -460,8 +506,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
||||||
const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] =
|
const [orderAddresses, orderValues, fillTakerTokenAmounts, vParams, rParams, sParams] = _.unzip<any>(
|
||||||
_.unzip<any>(orderAddressesValuesAndTakerTokenFillAmounts);
|
orderAddressesValuesAndTakerTokenFillAmounts,
|
||||||
|
);
|
||||||
const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchFillOrKillOrders.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@ -486,23 +533,28 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async cancelOrderAsync(order: Order|SignedOrder,
|
public async cancelOrderAsync(
|
||||||
|
order: Order | SignedOrder,
|
||||||
cancelTakerTokenAmount: BigNumber,
|
cancelTakerTokenAmount: BigNumber,
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
assert.isValidBaseUnitAmount('takerTokenCancelAmount', cancelTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('order.maker', order.maker, this._web3Wrapper);
|
||||||
|
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
const orderHash = utils.getOrderHashHex(order);
|
const orderHash = utils.getOrderHashHex(order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
||||||
order, cancelTakerTokenAmount, unavailableTakerTokenAmount);
|
order,
|
||||||
|
cancelTakerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
const [orderAddresses, orderValues] = ExchangeWrapper._getOrderAddressesAndValues(order);
|
||||||
@ -527,33 +579,40 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
@decorators.asyncZeroExErrorHandler
|
@decorators.asyncZeroExErrorHandler
|
||||||
public async batchCancelOrdersAsync(orderCancellationRequests: OrderCancellationRequest[],
|
public async batchCancelOrdersAsync(
|
||||||
orderTransactionOpts: OrderTransactionOpts = {}): Promise<string> {
|
orderCancellationRequests: OrderCancellationRequest[],
|
||||||
assert.doesConformToSchema('orderCancellationRequests', orderCancellationRequests,
|
orderTransactionOpts: OrderTransactionOpts = {},
|
||||||
schemas.orderCancellationRequestsSchema);
|
): Promise<string> {
|
||||||
|
assert.doesConformToSchema(
|
||||||
|
'orderCancellationRequests',
|
||||||
|
orderCancellationRequests,
|
||||||
|
schemas.orderCancellationRequestsSchema,
|
||||||
|
);
|
||||||
const exchangeContractAddresses = _.map(
|
const exchangeContractAddresses = _.map(
|
||||||
orderCancellationRequests,
|
orderCancellationRequests,
|
||||||
orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress,
|
orderCancellationRequest => orderCancellationRequest.order.exchangeContractAddress,
|
||||||
);
|
);
|
||||||
assert.hasAtMostOneUniqueValue(exchangeContractAddresses,
|
assert.hasAtMostOneUniqueValue(
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress);
|
exchangeContractAddresses,
|
||||||
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
|
);
|
||||||
const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker);
|
const makers = _.map(orderCancellationRequests, cancellationRequest => cancellationRequest.order.maker);
|
||||||
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
assert.hasAtMostOneUniqueValue(makers, ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
||||||
const maker = makers[0];
|
const maker = makers[0];
|
||||||
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
await assert.isSenderAddressAsync('maker', maker, this._web3Wrapper);
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ?
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
SHOULD_VALIDATE_BY_DEFAULT :
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
if (shouldValidate) {
|
if (shouldValidate) {
|
||||||
for (const orderCancellationRequest of orderCancellationRequests) {
|
for (const orderCancellationRequest of orderCancellationRequests) {
|
||||||
const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
|
const orderHash = utils.getOrderHashHex(orderCancellationRequest.order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
||||||
orderCancellationRequest.order, orderCancellationRequest.takerTokenCancelAmount,
|
orderCancellationRequest.order,
|
||||||
|
orderCancellationRequest.takerTokenCancelAmount,
|
||||||
unavailableTakerTokenAmount,
|
unavailableTakerTokenAmount,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if (_.isEmpty(orderCancellationRequests)) {
|
if (_.isEmpty(orderCancellationRequests)) {
|
||||||
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
@ -566,8 +625,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
// We use _.unzip<any> because _.unzip doesn't type check if values have different types :'(
|
||||||
const [orderAddresses, orderValues, cancelTakerTokenAmounts] =
|
const [orderAddresses, orderValues, cancelTakerTokenAmounts] = _.unzip<any>(
|
||||||
_.unzip<any>(orderAddressesValuesAndTakerTokenCancelAmounts);
|
orderAddressesValuesAndTakerTokenCancelAmounts,
|
||||||
|
);
|
||||||
const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
|
const txHash = await exchangeInstance.batchCancelOrders.sendTransactionAsync(
|
||||||
orderAddresses,
|
orderAddresses,
|
||||||
orderValues,
|
orderValues,
|
||||||
@ -589,14 +649,20 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Subscription token used later to unsubscribe
|
* @return Subscription token used later to unsubscribe
|
||||||
*/
|
*/
|
||||||
public subscribe<ArgsType extends ExchangeContractEventArgs>(
|
public subscribe<ArgsType extends ExchangeContractEventArgs>(
|
||||||
eventName: ExchangeEvents, indexFilterValues: IndexedFilterValues,
|
eventName: ExchangeEvents,
|
||||||
callback: EventCallback<ArgsType>): string {
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const exchangeContractAddress = this.getContractAddress();
|
const exchangeContractAddress = this.getContractAddress();
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
exchangeContractAddress, eventName, indexFilterValues, artifacts.ExchangeArtifact.abi, callback,
|
exchangeContractAddress,
|
||||||
|
eventName,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.ExchangeArtifact.abi,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
return subscriptionToken;
|
return subscriptionToken;
|
||||||
}
|
}
|
||||||
@ -622,14 +688,20 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Array of logs that match the parameters
|
* @return Array of logs that match the parameters
|
||||||
*/
|
*/
|
||||||
public async getLogsAsync<ArgsType extends ExchangeContractEventArgs>(
|
public async getLogsAsync<ArgsType extends ExchangeContractEventArgs>(
|
||||||
eventName: ExchangeEvents, blockRange: BlockRange, indexFilterValues: IndexedFilterValues,
|
eventName: ExchangeEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const exchangeContractAddress = this.getContractAddress();
|
const exchangeContractAddress = this.getContractAddress();
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
exchangeContractAddress, eventName, blockRange, indexFilterValues, artifacts.ExchangeArtifact.abi,
|
exchangeContractAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.ExchangeArtifact.abi,
|
||||||
);
|
);
|
||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
@ -652,14 +724,18 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* to validate for.
|
* to validate for.
|
||||||
*/
|
*/
|
||||||
public async validateOrderFillableOrThrowAsync(
|
public async validateOrderFillableOrThrowAsync(
|
||||||
signedOrder: SignedOrder, opts?: ValidateOrderFillableOpts,
|
signedOrder: SignedOrder,
|
||||||
|
opts?: ValidateOrderFillableOpts,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
|
const expectedFillTakerTokenAmount = !_.isUndefined(opts) ? opts.expectedFillTakerTokenAmount : undefined;
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateOrderFillableOrThrowAsync(
|
await this._orderValidationUtils.validateOrderFillableOrThrowAsync(
|
||||||
exchangeTradeEmulator, signedOrder, zrxTokenAddress, expectedFillTakerTokenAmount,
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
zrxTokenAddress,
|
||||||
|
expectedFillTakerTokenAmount,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -670,16 +746,23 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param takerAddress The user Ethereum address who would like to fill this order.
|
* @param takerAddress The user Ethereum address who would like to fill this order.
|
||||||
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
||||||
*/
|
*/
|
||||||
public async validateFillOrderThrowIfInvalidAsync(signedOrder: SignedOrder,
|
public async validateFillOrderThrowIfInvalidAsync(
|
||||||
|
signedOrder: SignedOrder,
|
||||||
fillTakerTokenAmount: BigNumber,
|
fillTakerTokenAmount: BigNumber,
|
||||||
takerAddress: string): Promise<void> {
|
takerAddress: string,
|
||||||
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if cancelling a given order will succeed and throws an informative error if it won't.
|
* Checks if cancelling a given order will succeed and throws an informative error if it won't.
|
||||||
@ -688,13 +771,18 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel.
|
* @param cancelTakerTokenAmount The amount (specified in taker tokens) that you would like to cancel.
|
||||||
*/
|
*/
|
||||||
public async validateCancelOrderThrowIfInvalidAsync(
|
public async validateCancelOrderThrowIfInvalidAsync(
|
||||||
order: Order, cancelTakerTokenAmount: BigNumber): Promise<void> {
|
order: Order,
|
||||||
|
cancelTakerTokenAmount: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
assert.doesConformToSchema('order', order, schemas.orderSchema);
|
||||||
assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
|
assert.isValidBaseUnitAmount('cancelTakerTokenAmount', cancelTakerTokenAmount);
|
||||||
const orderHash = utils.getOrderHashHex(order);
|
const orderHash = utils.getOrderHashHex(order);
|
||||||
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
OrderValidationUtils.validateCancelOrderThrowIfInvalid(
|
||||||
order, cancelTakerTokenAmount, unavailableTakerTokenAmount);
|
order,
|
||||||
|
cancelTakerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if calling fillOrKill on a given order will succeed and throws an informative error if it won't.
|
* Checks if calling fillOrKill on a given order will succeed and throws an informative error if it won't.
|
||||||
@ -704,16 +792,23 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param takerAddress The user Ethereum address who would like to fill this order.
|
* @param takerAddress The user Ethereum address who would like to fill this order.
|
||||||
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
* Must be available via the supplied Web3.Provider passed to 0x.js.
|
||||||
*/
|
*/
|
||||||
public async validateFillOrKillOrderThrowIfInvalidAsync(signedOrder: SignedOrder,
|
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
|
signedOrder: SignedOrder,
|
||||||
fillTakerTokenAmount: BigNumber,
|
fillTakerTokenAmount: BigNumber,
|
||||||
takerAddress: string): Promise<void> {
|
takerAddress: string,
|
||||||
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper);
|
||||||
const zrxTokenAddress = this.getZRXTokenAddress();
|
const zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress);
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks if rounding error will be > 0.1% when computing makerTokenAmount by doing:
|
* Checks if rounding error will be > 0.1% when computing makerTokenAmount by doing:
|
||||||
@ -724,15 +819,19 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @param takerTokenAmount The order size on the taker side
|
* @param takerTokenAmount The order size on the taker side
|
||||||
* @param makerTokenAmount The order size on the maker side
|
* @param makerTokenAmount The order size on the maker side
|
||||||
*/
|
*/
|
||||||
public async isRoundingErrorAsync(fillTakerTokenAmount: BigNumber,
|
public async isRoundingErrorAsync(
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
takerTokenAmount: BigNumber,
|
takerTokenAmount: BigNumber,
|
||||||
makerTokenAmount: BigNumber): Promise<boolean> {
|
makerTokenAmount: BigNumber,
|
||||||
|
): Promise<boolean> {
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isValidBaseUnitAmount('takerTokenAmount', takerTokenAmount);
|
assert.isValidBaseUnitAmount('takerTokenAmount', takerTokenAmount);
|
||||||
assert.isValidBaseUnitAmount('makerTokenAmount', makerTokenAmount);
|
assert.isValidBaseUnitAmount('makerTokenAmount', makerTokenAmount);
|
||||||
const exchangeInstance = await this._getExchangeContractAsync();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const isRoundingError = await exchangeInstance.isRoundingError.callAsync(
|
const isRoundingError = await exchangeInstance.isRoundingError.callAsync(
|
||||||
fillTakerTokenAmount, takerTokenAmount, makerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
|
takerTokenAmount,
|
||||||
|
makerTokenAmount,
|
||||||
);
|
);
|
||||||
return isRoundingError;
|
return isRoundingError;
|
||||||
}
|
}
|
||||||
@ -756,17 +855,18 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
* @return Address of ZRX token
|
* @return Address of ZRX token
|
||||||
*/
|
*/
|
||||||
public getZRXTokenAddress(): string {
|
public getZRXTokenAddress(): string {
|
||||||
const contractAddress = this._getContractAddress(
|
const contractAddress = this._getContractAddress(artifacts.ZRXArtifact, this._zrxContractAddressIfExists);
|
||||||
artifacts.ZRXArtifact, this._zrxContractAddressIfExists,
|
|
||||||
);
|
|
||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
private _invalidateContractInstances(): void {
|
private _invalidateContractInstances(): void {
|
||||||
this.unsubscribeAll();
|
this.unsubscribeAll();
|
||||||
delete this._exchangeContractIfExists;
|
delete this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
private async _isValidSignatureUsingContractCallAsync(dataHex: string, ecSignature: ECSignature,
|
private async _isValidSignatureUsingContractCallAsync(
|
||||||
signerAddressHex: string): Promise<boolean> {
|
dataHex: string,
|
||||||
|
ecSignature: ECSignature,
|
||||||
|
signerAddressHex: string,
|
||||||
|
): Promise<boolean> {
|
||||||
assert.isHexString('dataHex', dataHex);
|
assert.isHexString('dataHex', dataHex);
|
||||||
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
|
assert.doesConformToSchema('ecSignature', ecSignature, schemas.ecSignatureSchema);
|
||||||
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
|
assert.isETHAddressHex('signerAddressHex', signerAddressHex);
|
||||||
@ -793,7 +893,8 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
return this._exchangeContractIfExists;
|
return this._exchangeContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.ExchangeArtifact, this._contractAddressIfExists,
|
artifacts.ExchangeArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new ExchangeContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
this._exchangeContractIfExists = contractInstance;
|
this._exchangeContractIfExists = contractInstance;
|
||||||
|
@ -37,9 +37,8 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
public async getTokensAsync(): Promise<Token[]> {
|
public async getTokensAsync(): Promise<Token[]> {
|
||||||
const addresses = await this.getTokenAddressesAsync();
|
const addresses = await this.getTokenAddressesAsync();
|
||||||
const tokenPromises: Array<Promise<Token|undefined>> = _.map(
|
const tokenPromises: Array<Promise<Token | undefined>> = _.map(addresses, async (address: string) =>
|
||||||
addresses,
|
this.getTokenIfExistsAsync(address),
|
||||||
async (address: string) => this.getTokenIfExistsAsync(address),
|
|
||||||
);
|
);
|
||||||
const tokens = await Promise.all(tokenPromises);
|
const tokens = await Promise.all(tokenPromises);
|
||||||
return tokens as Token[];
|
return tokens as Token[];
|
||||||
@ -104,7 +103,8 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
public getContractAddress(): string {
|
public getContractAddress(): string {
|
||||||
const contractAddress = this._getContractAddress(
|
const contractAddress = this._getContractAddress(
|
||||||
artifacts.TokenRegistryArtifact, this._contractAddressIfExists,
|
artifacts.TokenRegistryArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
@ -116,10 +116,12 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
return this._tokenRegistryContractIfExists;
|
return this._tokenRegistryContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenRegistryArtifact, this._contractAddressIfExists,
|
artifacts.TokenRegistryArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenRegistryContract(
|
const contractInstance = new TokenRegistryContract(
|
||||||
web3ContractInstance, this._web3Wrapper.getContractDefaults(),
|
web3ContractInstance,
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
);
|
);
|
||||||
this._tokenRegistryContractIfExists = contractInstance;
|
this._tokenRegistryContractIfExists = contractInstance;
|
||||||
return this._tokenRegistryContractIfExists;
|
return this._tokenRegistryContractIfExists;
|
||||||
|
@ -42,7 +42,8 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
*/
|
*/
|
||||||
public getContractAddress(): string {
|
public getContractAddress(): string {
|
||||||
const contractAddress = this._getContractAddress(
|
const contractAddress = this._getContractAddress(
|
||||||
artifacts.TokenTransferProxyArtifact, this._contractAddressIfExists,
|
artifacts.TokenTransferProxyArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
return contractAddress;
|
return contractAddress;
|
||||||
}
|
}
|
||||||
@ -54,10 +55,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
return this._tokenTransferProxyContractIfExists;
|
return this._tokenTransferProxyContractIfExists;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenTransferProxyArtifact, this._contractAddressIfExists,
|
artifacts.TokenTransferProxyArtifact,
|
||||||
|
this._contractAddressIfExists,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenTransferProxyContract(
|
const contractInstance = new TokenTransferProxyContract(
|
||||||
web3ContractInstance, this._web3Wrapper.getContractDefaults(),
|
web3ContractInstance,
|
||||||
|
this._web3Wrapper.getContractDefaults(),
|
||||||
);
|
);
|
||||||
this._tokenTransferProxyContractIfExists = contractInstance;
|
this._tokenTransferProxyContractIfExists = contractInstance;
|
||||||
return this._tokenTransferProxyContractIfExists;
|
return this._tokenTransferProxyContractIfExists;
|
||||||
|
@ -32,8 +32,12 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
public UNLIMITED_ALLOWANCE_IN_BASE_UNITS = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
|
||||||
private _tokenContractsByAddress: { [address: string]: TokenContract };
|
private _tokenContractsByAddress: { [address: string]: TokenContract };
|
||||||
private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
|
private _tokenTransferProxyWrapper: TokenTransferProxyWrapper;
|
||||||
constructor(web3Wrapper: Web3Wrapper, networkId: number, abiDecoder: AbiDecoder,
|
constructor(
|
||||||
tokenTransferProxyWrapper: TokenTransferProxyWrapper) {
|
web3Wrapper: Web3Wrapper,
|
||||||
|
networkId: number,
|
||||||
|
abiDecoder: AbiDecoder,
|
||||||
|
tokenTransferProxyWrapper: TokenTransferProxyWrapper,
|
||||||
|
) {
|
||||||
super(web3Wrapper, networkId, abiDecoder);
|
super(web3Wrapper, networkId, abiDecoder);
|
||||||
this._tokenContractsByAddress = {};
|
this._tokenContractsByAddress = {};
|
||||||
this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
|
this._tokenTransferProxyWrapper = tokenTransferProxyWrapper;
|
||||||
@ -45,8 +49,11 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
* @return The owner's ERC20 token balance in base units.
|
* @return The owner's ERC20 token balance in base units.
|
||||||
*/
|
*/
|
||||||
public async getBalanceAsync(tokenAddress: string, ownerAddress: string,
|
public async getBalanceAsync(
|
||||||
methodOpts?: MethodOpts): Promise<BigNumber> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
methodOpts?: MethodOpts,
|
||||||
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
|
||||||
@ -68,8 +75,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string,
|
public async setAllowanceAsync(
|
||||||
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
spenderAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
||||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
@ -95,10 +107,18 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setUnlimitedAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async setUnlimitedAllowanceAsync(
|
||||||
spenderAddress: string, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
spenderAddress: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, spenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts,
|
tokenAddress,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
|
txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@ -110,8 +130,12 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param spenderAddress The hex encoded user Ethereum address who can spend the allowance you are fetching.
|
* @param spenderAddress The hex encoded user Ethereum address who can spend the allowance you are fetching.
|
||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
*/
|
*/
|
||||||
public async getAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async getAllowanceAsync(
|
||||||
spenderAddress: string, methodOpts?: MethodOpts): Promise<BigNumber> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
spenderAddress: string,
|
||||||
|
methodOpts?: MethodOpts,
|
||||||
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
|
||||||
@ -128,8 +152,11 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param ownerAddress The hex encoded user Ethereum address whose proxy contract allowance we are retrieving.
|
* @param ownerAddress The hex encoded user Ethereum address whose proxy contract allowance we are retrieving.
|
||||||
* @param methodOpts Optional arguments this method accepts.
|
* @param methodOpts Optional arguments this method accepts.
|
||||||
*/
|
*/
|
||||||
public async getProxyAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async getProxyAllowanceAsync(
|
||||||
methodOpts?: MethodOpts): Promise<BigNumber> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
methodOpts?: MethodOpts,
|
||||||
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
|
|
||||||
@ -147,15 +174,23 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setProxyAllowanceAsync(tokenAddress: string, ownerAddress: string,
|
public async setProxyAllowanceAsync(
|
||||||
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits, txOpts,
|
tokenAddress,
|
||||||
|
ownerAddress,
|
||||||
|
proxyAddress,
|
||||||
|
amountInBaseUnits,
|
||||||
|
txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@ -171,10 +206,15 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async setUnlimitedProxyAllowanceAsync(
|
public async setUnlimitedProxyAllowanceAsync(
|
||||||
tokenAddress: string, ownerAddress: string, txOpts: TransactionOpts = {},
|
tokenAddress: string,
|
||||||
|
ownerAddress: string,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const txHash = await this.setProxyAllowanceAsync(
|
const txHash = await this.setProxyAllowanceAsync(
|
||||||
tokenAddress, ownerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts,
|
tokenAddress,
|
||||||
|
ownerAddress,
|
||||||
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
|
txOpts,
|
||||||
);
|
);
|
||||||
return txHash;
|
return txHash;
|
||||||
}
|
}
|
||||||
@ -187,8 +227,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async transferAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
public async transferAsync(
|
||||||
amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}): Promise<string> {
|
tokenAddress: string,
|
||||||
|
fromAddress: string,
|
||||||
|
toAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
@ -222,9 +267,14 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @param txOpts Transaction parameters.
|
* @param txOpts Transaction parameters.
|
||||||
* @return Transaction hash.
|
* @return Transaction hash.
|
||||||
*/
|
*/
|
||||||
public async transferFromAsync(tokenAddress: string, fromAddress: string, toAddress: string,
|
public async transferFromAsync(
|
||||||
senderAddress: string, amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}):
|
tokenAddress: string,
|
||||||
Promise<string> {
|
fromAddress: string,
|
||||||
|
toAddress: string,
|
||||||
|
senderAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
txOpts: TransactionOpts = {},
|
||||||
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
assert.isETHAddressHex('fromAddress', fromAddress);
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
@ -244,7 +294,9 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
||||||
fromAddress, toAddress, amountInBaseUnits,
|
fromAddress,
|
||||||
|
toAddress,
|
||||||
|
amountInBaseUnits,
|
||||||
{
|
{
|
||||||
from: senderAddress,
|
from: senderAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
@ -263,14 +315,21 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @return Subscription token used later to unsubscribe
|
* @return Subscription token used later to unsubscribe
|
||||||
*/
|
*/
|
||||||
public subscribe<ArgsType extends TokenContractEventArgs>(
|
public subscribe<ArgsType extends TokenContractEventArgs>(
|
||||||
tokenAddress: string, eventName: TokenEvents, indexFilterValues: IndexedFilterValues,
|
tokenAddress: string,
|
||||||
callback: EventCallback<ArgsType>): string {
|
eventName: TokenEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
callback: EventCallback<ArgsType>,
|
||||||
|
): string {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
tokenAddress, eventName, indexFilterValues, artifacts.TokenArtifact.abi, callback,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.TokenArtifact.abi,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
return subscriptionToken;
|
return subscriptionToken;
|
||||||
}
|
}
|
||||||
@ -297,14 +356,21 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
* @return Array of logs that match the parameters
|
* @return Array of logs that match the parameters
|
||||||
*/
|
*/
|
||||||
public async getLogsAsync<ArgsType extends TokenContractEventArgs>(
|
public async getLogsAsync<ArgsType extends TokenContractEventArgs>(
|
||||||
tokenAddress: string, eventName: TokenEvents, blockRange: BlockRange,
|
tokenAddress: string,
|
||||||
indexFilterValues: IndexedFilterValues): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
eventName: TokenEvents,
|
||||||
|
blockRange: BlockRange,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
tokenAddress, eventName, blockRange, indexFilterValues, artifacts.TokenArtifact.abi,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
|
artifacts.TokenArtifact.abi,
|
||||||
);
|
);
|
||||||
return logs;
|
return logs;
|
||||||
}
|
}
|
||||||
@ -318,11 +384,10 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
return tokenContract;
|
return tokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenArtifact, tokenAddress,
|
artifacts.TokenArtifact,
|
||||||
);
|
tokenAddress,
|
||||||
const contractInstance = new TokenContract(
|
|
||||||
web3ContractInstance, this._web3Wrapper.getContractDefaults(),
|
|
||||||
);
|
);
|
||||||
|
const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
tokenContract = contractInstance;
|
tokenContract = contractInstance;
|
||||||
this._tokenContractsByAddress[tokenAddress] = tokenContract;
|
this._tokenContractsByAddress[tokenAddress] = tokenContract;
|
||||||
return tokenContract;
|
return tokenContract;
|
||||||
|
3
packages/0x.js/src/globals.d.ts
vendored
3
packages/0x.js/src/globals.d.ts
vendored
@ -57,8 +57,7 @@ declare module 'truffle-hdwallet-provider' {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// abi-decoder declarations
|
// abi-decoder declarations
|
||||||
interface DecodedLogArg {
|
interface DecodedLogArg {}
|
||||||
}
|
|
||||||
interface DecodedLog {
|
interface DecodedLog {
|
||||||
name: string;
|
name: string;
|
||||||
events: DecodedLogArg[];
|
events: DecodedLogArg[];
|
||||||
|
@ -47,6 +47,4 @@ export {
|
|||||||
OrderState,
|
OrderState,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
export {
|
export { TransactionReceipt } from '@0xproject/types';
|
||||||
TransactionReceipt,
|
|
||||||
} from '@0xproject/types';
|
|
||||||
|
@ -3,11 +3,7 @@ import {Web3Wrapper} from '@0xproject/web3-wrapper';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {
|
import { BlockParamLiteral, EventWatcherCallback, ZeroExError } from '../types';
|
||||||
BlockParamLiteral,
|
|
||||||
EventWatcherCallback,
|
|
||||||
ZeroExError,
|
|
||||||
} from '../types';
|
|
||||||
import { assert } from '../utils/assert';
|
import { assert } from '../utils/assert';
|
||||||
|
|
||||||
const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
|
const DEFAULT_EVENT_POLLING_INTERVAL_MS = 200;
|
||||||
@ -28,9 +24,9 @@ export class EventWatcher {
|
|||||||
private _lastEvents: Web3.LogEntry[] = [];
|
private _lastEvents: Web3.LogEntry[] = [];
|
||||||
constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
|
constructor(web3Wrapper: Web3Wrapper, pollingIntervalIfExistsMs: undefined | number) {
|
||||||
this._web3Wrapper = web3Wrapper;
|
this._web3Wrapper = web3Wrapper;
|
||||||
this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs) ?
|
this._pollingIntervalMs = _.isUndefined(pollingIntervalIfExistsMs)
|
||||||
DEFAULT_EVENT_POLLING_INTERVAL_MS :
|
? DEFAULT_EVENT_POLLING_INTERVAL_MS
|
||||||
pollingIntervalIfExistsMs;
|
: pollingIntervalIfExistsMs;
|
||||||
}
|
}
|
||||||
public subscribe(callback: EventWatcherCallback): void {
|
public subscribe(callback: EventWatcherCallback): void {
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
@ -38,7 +34,8 @@ export class EventWatcher {
|
|||||||
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
||||||
}
|
}
|
||||||
this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
this._intervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._pollForBlockchainEventsAsync.bind(this, callback), this._pollingIntervalMs,
|
this._pollForBlockchainEventsAsync.bind(this, callback),
|
||||||
|
this._pollingIntervalMs,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public unsubscribe(): void {
|
public unsubscribe(): void {
|
||||||
@ -71,7 +68,9 @@ export class EventWatcher {
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
private async _emitDifferencesAsync(
|
private async _emitDifferencesAsync(
|
||||||
logs: Web3.LogEntry[], logEventState: LogEventState, callback: EventWatcherCallback,
|
logs: Web3.LogEntry[],
|
||||||
|
logEventState: LogEventState,
|
||||||
|
callback: EventWatcherCallback,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
for (const log of logs) {
|
for (const log of logs) {
|
||||||
const logEvent = {
|
const logEvent = {
|
||||||
|
@ -19,12 +19,10 @@ export class ExpirationWatcher {
|
|||||||
private _orderExpirationCheckingIntervalMs: number;
|
private _orderExpirationCheckingIntervalMs: number;
|
||||||
private _expirationMarginMs: number;
|
private _expirationMarginMs: number;
|
||||||
private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
|
private _orderExpirationCheckingIntervalIdIfExists?: NodeJS.Timer;
|
||||||
constructor(expirationMarginIfExistsMs?: number,
|
constructor(expirationMarginIfExistsMs?: number, orderExpirationCheckingIntervalIfExistsMs?: number) {
|
||||||
orderExpirationCheckingIntervalIfExistsMs?: number) {
|
this._expirationMarginMs = expirationMarginIfExistsMs || DEFAULT_EXPIRATION_MARGIN_MS;
|
||||||
this._expirationMarginMs = expirationMarginIfExistsMs ||
|
this._orderExpirationCheckingIntervalMs =
|
||||||
DEFAULT_EXPIRATION_MARGIN_MS;
|
expirationMarginIfExistsMs || DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
|
||||||
this._orderExpirationCheckingIntervalMs = expirationMarginIfExistsMs ||
|
|
||||||
DEFAULT_ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
|
|
||||||
const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
|
const scoreFunction = (orderHash: string) => this._expiration[orderHash].toNumber();
|
||||||
const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
|
const comparator = (lhs: string, rhs: string) => scoreFunction(lhs) - scoreFunction(rhs);
|
||||||
this._orderHashByExpirationRBTree = new RBTree(comparator);
|
this._orderHashByExpirationRBTree = new RBTree(comparator);
|
||||||
@ -34,7 +32,8 @@ export class ExpirationWatcher {
|
|||||||
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
throw new Error(ZeroExError.SubscriptionAlreadyPresent);
|
||||||
}
|
}
|
||||||
this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
this._orderExpirationCheckingIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._pruneExpiredOrders.bind(this, callback), this._orderExpirationCheckingIntervalMs,
|
this._pruneExpiredOrders.bind(this, callback),
|
||||||
|
this._orderExpirationCheckingIntervalMs,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public unsubscribe(): void {
|
public unsubscribe(): void {
|
||||||
|
@ -74,7 +74,10 @@ export class OrderStateWatcher {
|
|||||||
private _cleanupJobInterval: number;
|
private _cleanupJobInterval: number;
|
||||||
private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
|
private _cleanupJobIntervalIdIfExists?: NodeJS.Timer;
|
||||||
constructor(
|
constructor(
|
||||||
web3Wrapper: Web3Wrapper, abiDecoder: AbiDecoder, token: TokenWrapper, exchange: ExchangeWrapper,
|
web3Wrapper: Web3Wrapper,
|
||||||
|
abiDecoder: AbiDecoder,
|
||||||
|
token: TokenWrapper,
|
||||||
|
exchange: ExchangeWrapper,
|
||||||
config?: OrderStateWatcherConfig,
|
config?: OrderStateWatcherConfig,
|
||||||
) {
|
) {
|
||||||
this._abiDecoder = abiDecoder;
|
this._abiDecoder = abiDecoder;
|
||||||
@ -82,24 +85,26 @@ export class OrderStateWatcher {
|
|||||||
const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
|
const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
|
||||||
this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
|
this._eventWatcher = new EventWatcher(web3Wrapper, pollingIntervalIfExistsMs);
|
||||||
this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
|
||||||
token, BlockParamLiteral.Pending,
|
token,
|
||||||
|
BlockParamLiteral.Pending,
|
||||||
);
|
);
|
||||||
this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
|
this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(exchange);
|
||||||
this._orderStateUtils = new OrderStateUtils(
|
this._orderStateUtils = new OrderStateUtils(
|
||||||
this._balanceAndProxyAllowanceLazyStore, this._orderFilledCancelledLazyStore,
|
this._balanceAndProxyAllowanceLazyStore,
|
||||||
|
this._orderFilledCancelledLazyStore,
|
||||||
);
|
);
|
||||||
const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config) ?
|
const orderExpirationCheckingIntervalMsIfExists = _.isUndefined(config)
|
||||||
undefined :
|
? undefined
|
||||||
config.orderExpirationCheckingIntervalMs;
|
: config.orderExpirationCheckingIntervalMs;
|
||||||
const expirationMarginIfExistsMs = _.isUndefined(config) ?
|
const expirationMarginIfExistsMs = _.isUndefined(config) ? undefined : config.expirationMarginMs;
|
||||||
undefined :
|
|
||||||
config.expirationMarginMs;
|
|
||||||
this._expirationWatcher = new ExpirationWatcher(
|
this._expirationWatcher = new ExpirationWatcher(
|
||||||
expirationMarginIfExistsMs, orderExpirationCheckingIntervalMsIfExists,
|
expirationMarginIfExistsMs,
|
||||||
|
orderExpirationCheckingIntervalMsIfExists,
|
||||||
);
|
);
|
||||||
this._cleanupJobInterval = _.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs) ?
|
this._cleanupJobInterval =
|
||||||
DEFAULT_CLEANUP_JOB_INTERVAL_MS :
|
_.isUndefined(config) || _.isUndefined(config.cleanupJobIntervalMs)
|
||||||
config.cleanupJobIntervalMs;
|
? DEFAULT_CLEANUP_JOB_INTERVAL_MS
|
||||||
|
: config.cleanupJobIntervalMs;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Add an order to the orderStateWatcher. Before the order is added, it's
|
* Add an order to the orderStateWatcher. Before the order is added, it's
|
||||||
@ -148,7 +153,8 @@ export class OrderStateWatcher {
|
|||||||
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
this._eventWatcher.subscribe(this._onEventWatcherCallbackAsync.bind(this));
|
||||||
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
this._expirationWatcher.subscribe(this._onOrderExpired.bind(this));
|
||||||
this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
this._cleanupJobIntervalIdIfExists = intervalUtils.setAsyncExcludingInterval(
|
||||||
this._cleanupAsync.bind(this), this._cleanupJobInterval,
|
this._cleanupAsync.bind(this),
|
||||||
|
this._cleanupJobInterval,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -215,23 +221,23 @@ export class OrderStateWatcher {
|
|||||||
let makerToken: string;
|
let makerToken: string;
|
||||||
let makerAddress: string;
|
let makerAddress: string;
|
||||||
switch (decodedLog.event) {
|
switch (decodedLog.event) {
|
||||||
case TokenEvents.Approval:
|
case TokenEvents.Approval: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as ApprovalContractEventArgs;
|
const args = decodedLog.args as ApprovalContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteProxyAllowance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._owner;
|
makerAddress = args._owner;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TokenEvents.Transfer:
|
case TokenEvents.Transfer: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as TransferContractEventArgs;
|
const args = decodedLog.args as TransferContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._from);
|
||||||
@ -239,45 +245,48 @@ export class OrderStateWatcher {
|
|||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._from;
|
makerAddress = args._from;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EtherTokenEvents.Deposit:
|
case EtherTokenEvents.Deposit: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as DepositContractEventArgs;
|
const args = decodedLog.args as DepositContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._owner;
|
makerAddress = args._owner;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EtherTokenEvents.Withdrawal:
|
case EtherTokenEvents.Withdrawal: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as WithdrawalContractEventArgs;
|
const args = decodedLog.args as WithdrawalContractEventArgs;
|
||||||
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
this._balanceAndProxyAllowanceLazyStore.deleteBalance(decodedLog.address, args._owner);
|
||||||
// Revalidate orders
|
// Revalidate orders
|
||||||
makerToken = decodedLog.address;
|
makerToken = decodedLog.address;
|
||||||
makerAddress = args._owner;
|
makerAddress = args._owner;
|
||||||
if (!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
if (
|
||||||
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])) {
|
!_.isUndefined(this._dependentOrderHashes[makerAddress]) &&
|
||||||
|
!_.isUndefined(this._dependentOrderHashes[makerAddress][makerToken])
|
||||||
|
) {
|
||||||
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
const orderHashes = Array.from(this._dependentOrderHashes[makerAddress][makerToken]);
|
||||||
await this._emitRevalidateOrdersAsync(orderHashes);
|
await this._emitRevalidateOrdersAsync(orderHashes);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ExchangeEvents.LogFill:
|
case ExchangeEvents.LogFill: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as LogFillContractEventArgs;
|
const args = decodedLog.args as LogFillContractEventArgs;
|
||||||
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash);
|
this._orderFilledCancelledLazyStore.deleteFilledTakerAmount(args.orderHash);
|
||||||
@ -289,8 +298,7 @@ export class OrderStateWatcher {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ExchangeEvents.LogCancel:
|
case ExchangeEvents.LogCancel: {
|
||||||
{
|
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
const args = decodedLog.args as LogCancelContractEventArgs;
|
const args = decodedLog.args as LogCancelContractEventArgs;
|
||||||
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash);
|
this._orderFilledCancelledLazyStore.deleteCancelledTakerAmount(args.orderHash);
|
||||||
|
@ -10,17 +10,20 @@ export class RemainingFillableCalculator {
|
|||||||
private _transferrableMakerFeeTokenAmount: BigNumber;
|
private _transferrableMakerFeeTokenAmount: BigNumber;
|
||||||
private _remainingMakerTokenAmount: BigNumber;
|
private _remainingMakerTokenAmount: BigNumber;
|
||||||
private _remainingMakerFeeAmount: BigNumber;
|
private _remainingMakerFeeAmount: BigNumber;
|
||||||
constructor(signedOrder: SignedOrder,
|
constructor(
|
||||||
|
signedOrder: SignedOrder,
|
||||||
isMakerTokenZRX: boolean,
|
isMakerTokenZRX: boolean,
|
||||||
transferrableMakerTokenAmount: BigNumber,
|
transferrableMakerTokenAmount: BigNumber,
|
||||||
transferrableMakerFeeTokenAmount: BigNumber,
|
transferrableMakerFeeTokenAmount: BigNumber,
|
||||||
remainingMakerTokenAmount: BigNumber) {
|
remainingMakerTokenAmount: BigNumber,
|
||||||
|
) {
|
||||||
this._signedOrder = signedOrder;
|
this._signedOrder = signedOrder;
|
||||||
this._isMakerTokenZRX = isMakerTokenZRX;
|
this._isMakerTokenZRX = isMakerTokenZRX;
|
||||||
this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
|
this._transferrableMakerTokenAmount = transferrableMakerTokenAmount;
|
||||||
this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
|
this._transferrableMakerFeeTokenAmount = transferrableMakerFeeTokenAmount;
|
||||||
this._remainingMakerTokenAmount = remainingMakerTokenAmount;
|
this._remainingMakerTokenAmount = remainingMakerTokenAmount;
|
||||||
this._remainingMakerFeeAmount = remainingMakerTokenAmount.times(signedOrder.makerFee)
|
this._remainingMakerFeeAmount = remainingMakerTokenAmount
|
||||||
|
.times(signedOrder.makerFee)
|
||||||
.dividedToIntegerBy(signedOrder.makerTokenAmount);
|
.dividedToIntegerBy(signedOrder.makerTokenAmount);
|
||||||
}
|
}
|
||||||
public computeRemainingMakerFillable(): BigNumber {
|
public computeRemainingMakerFillable(): BigNumber {
|
||||||
@ -33,20 +36,24 @@ export class RemainingFillableCalculator {
|
|||||||
return this._calculatePartiallyFillableMakerTokenAmount();
|
return this._calculatePartiallyFillableMakerTokenAmount();
|
||||||
}
|
}
|
||||||
public computeRemainingTakerFillable(): BigNumber {
|
public computeRemainingTakerFillable(): BigNumber {
|
||||||
return this.computeRemainingMakerFillable().times(this._signedOrder.takerTokenAmount)
|
return this.computeRemainingMakerFillable()
|
||||||
|
.times(this._signedOrder.takerTokenAmount)
|
||||||
.dividedToIntegerBy(this._signedOrder.makerTokenAmount);
|
.dividedToIntegerBy(this._signedOrder.makerTokenAmount);
|
||||||
}
|
}
|
||||||
private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
|
private _hasSufficientFundsForFeeAndTransferAmount(): boolean {
|
||||||
if (this._isMakerTokenZRX) {
|
if (this._isMakerTokenZRX) {
|
||||||
const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
|
const totalZRXTransferAmountRequired = this._remainingMakerTokenAmount.plus(this._remainingMakerFeeAmount);
|
||||||
const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
const hasSufficientFunds = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
||||||
totalZRXTransferAmountRequired);
|
totalZRXTransferAmountRequired,
|
||||||
|
);
|
||||||
return hasSufficientFunds;
|
return hasSufficientFunds;
|
||||||
} else {
|
} else {
|
||||||
const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
const hasSufficientFundsForTransferAmount = this._transferrableMakerTokenAmount.greaterThanOrEqualTo(
|
||||||
this._remainingMakerTokenAmount);
|
this._remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
|
const hasSufficientFundsForFeeAmount = this._transferrableMakerFeeTokenAmount.greaterThanOrEqualTo(
|
||||||
this._remainingMakerFeeAmount);
|
this._remainingMakerFeeAmount,
|
||||||
|
);
|
||||||
const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
|
const hasSufficientFunds = hasSufficientFundsForTransferAmount && hasSufficientFundsForFeeAmount;
|
||||||
return hasSufficientFunds;
|
return hasSufficientFunds;
|
||||||
}
|
}
|
||||||
@ -57,8 +64,10 @@ export class RemainingFillableCalculator {
|
|||||||
// The number of times the maker can fill the order, if each fill only required the transfer of a single
|
// The number of times the maker can fill the order, if each fill only required the transfer of a single
|
||||||
// baseUnit of fee tokens.
|
// baseUnit of fee tokens.
|
||||||
// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
|
// Given 2 ZRXwei, the maximum amount of times Maker can fill this order, in terms of fees, is 2
|
||||||
const fillableTimesInFeeTokenBaseUnits = BigNumber.min(this._transferrableMakerFeeTokenAmount,
|
const fillableTimesInFeeTokenBaseUnits = BigNumber.min(
|
||||||
this._remainingMakerFeeAmount);
|
this._transferrableMakerFeeTokenAmount,
|
||||||
|
this._remainingMakerFeeAmount,
|
||||||
|
);
|
||||||
// The number of times the Maker can fill the order, given the Maker Token Balance
|
// The number of times the Maker can fill the order, given the Maker Token Balance
|
||||||
// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
|
// Assuming a balance of 150 wei, and an orderToFeeRatio of 100:1, maker can fill this order 1 time.
|
||||||
let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
|
let fillableTimesInMakerTokenUnits = this._transferrableMakerTokenAmount.dividedBy(orderToFeeRatio);
|
||||||
@ -68,9 +77,7 @@ export class RemainingFillableCalculator {
|
|||||||
const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
|
const totalZRXTokenPooled = this._transferrableMakerTokenAmount;
|
||||||
// The purchasing power here is less as the tokens are taken from the same Pool
|
// The purchasing power here is less as the tokens are taken from the same Pool
|
||||||
// For every one number of fills, we have to take an extra ZRX out of the pool
|
// For every one number of fills, we have to take an extra ZRX out of the pool
|
||||||
fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(
|
fillableTimesInMakerTokenUnits = totalZRXTokenPooled.dividedBy(orderToFeeRatio.plus(new BigNumber(1)));
|
||||||
orderToFeeRatio.plus(new BigNumber(1)));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
|
// When Ratio is not fully divisible there can be remainders which cannot be represented, so they are floored.
|
||||||
// This can result in a RoundingError being thrown by the Exchange Contract.
|
// This can result in a RoundingError being thrown by the Exchange Contract.
|
||||||
@ -80,8 +87,10 @@ export class RemainingFillableCalculator {
|
|||||||
const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
|
const partiallyFillableFeeTokenAmount = fillableTimesInFeeTokenBaseUnits
|
||||||
.times(this._signedOrder.makerTokenAmount)
|
.times(this._signedOrder.makerTokenAmount)
|
||||||
.dividedToIntegerBy(this._signedOrder.makerFee);
|
.dividedToIntegerBy(this._signedOrder.makerFee);
|
||||||
const partiallyFillableAmount = BigNumber.min(partiallyFillableMakerTokenAmount,
|
const partiallyFillableAmount = BigNumber.min(
|
||||||
partiallyFillableFeeTokenAmount);
|
partiallyFillableMakerTokenAmount,
|
||||||
|
partiallyFillableFeeTokenAmount,
|
||||||
|
);
|
||||||
return partiallyFillableAmount;
|
return partiallyFillableAmount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,10 @@ export class BalanceAndProxyAllowanceLazyStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
public async getProxyAllowanceAsync(tokenAddress: string, userAddress: string): Promise<BigNumber> {
|
||||||
if (_.isUndefined(this._proxyAllowance[tokenAddress]) ||
|
if (
|
||||||
_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])) {
|
_.isUndefined(this._proxyAllowance[tokenAddress]) ||
|
||||||
|
_.isUndefined(this._proxyAllowance[tokenAddress][userAddress])
|
||||||
|
) {
|
||||||
const methodOpts = {
|
const methodOpts = {
|
||||||
defaultBlock: this._defaultBlock,
|
defaultBlock: this._defaultBlock,
|
||||||
};
|
};
|
||||||
|
@ -42,8 +42,7 @@ export interface ECSignature {
|
|||||||
|
|
||||||
export type OrderAddresses = [string, string, string, string, string];
|
export type OrderAddresses = [string, string, string, string, string];
|
||||||
|
|
||||||
export type OrderValues = [BigNumber, BigNumber, BigNumber,
|
export type OrderValues = [BigNumber, BigNumber, BigNumber, BigNumber, BigNumber, BigNumber];
|
||||||
BigNumber, BigNumber, BigNumber];
|
|
||||||
|
|
||||||
export type LogEvent = Web3.LogEntryEvent;
|
export type LogEvent = Web3.LogEntryEvent;
|
||||||
export interface DecodedLogEvent<ArgsType> {
|
export interface DecodedLogEvent<ArgsType> {
|
||||||
@ -136,7 +135,10 @@ export interface LogErrorContractEventArgs {
|
|||||||
errorId: BigNumber;
|
errorId: BigNumber;
|
||||||
orderHash: string;
|
orderHash: string;
|
||||||
}
|
}
|
||||||
export type ExchangeContractEventArgs = LogFillContractEventArgs|LogCancelContractEventArgs|LogErrorContractEventArgs;
|
export type ExchangeContractEventArgs =
|
||||||
|
| LogFillContractEventArgs
|
||||||
|
| LogCancelContractEventArgs
|
||||||
|
| LogErrorContractEventArgs;
|
||||||
export interface TransferContractEventArgs {
|
export interface TransferContractEventArgs {
|
||||||
_from: string;
|
_from: string;
|
||||||
_to: string;
|
_to: string;
|
||||||
@ -156,7 +158,10 @@ export interface WithdrawalContractEventArgs {
|
|||||||
_value: BigNumber;
|
_value: BigNumber;
|
||||||
}
|
}
|
||||||
export type TokenContractEventArgs = TransferContractEventArgs | ApprovalContractEventArgs;
|
export type TokenContractEventArgs = TransferContractEventArgs | ApprovalContractEventArgs;
|
||||||
export type EtherTokenContractEventArgs = TokenContractEventArgs|DepositContractEventArgs|WithdrawalContractEventArgs;
|
export type EtherTokenContractEventArgs =
|
||||||
|
| TokenContractEventArgs
|
||||||
|
| DepositContractEventArgs
|
||||||
|
| WithdrawalContractEventArgs;
|
||||||
export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
|
export type ContractEventArgs = ExchangeContractEventArgs | TokenContractEventArgs | EtherTokenContractEventArgs;
|
||||||
export type ContractEventArg = string | BigNumber;
|
export type ContractEventArg = string | BigNumber;
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ export class AbiDecoder {
|
|||||||
}
|
}
|
||||||
// This method can only decode logs from the 0x & ERC20 smart contracts
|
// This method can only decode logs from the 0x & ERC20 smart contracts
|
||||||
public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
public tryToDecodeLogOrNoop<ArgsType extends ContractEventArgs>(
|
||||||
log: Web3.LogEntry): LogWithDecodedArgs<ArgsType>|RawLog {
|
log: Web3.LogEntry,
|
||||||
|
): LogWithDecodedArgs<ArgsType> | RawLog {
|
||||||
const methodId = log.topics[0];
|
const methodId = log.topics[0];
|
||||||
const event = this._methodIds[methodId];
|
const event = this._methodIds[methodId];
|
||||||
if (_.isUndefined(event)) {
|
if (_.isUndefined(event)) {
|
||||||
@ -42,9 +43,11 @@ export class AbiDecoder {
|
|||||||
let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++];
|
let value = param.indexed ? log.topics[topicsIndex++] : decodedData[dataIndex++];
|
||||||
if (param.type === SolidityTypes.Address) {
|
if (param.type === SolidityTypes.Address) {
|
||||||
value = AbiDecoder._padZeros(new BigNumber(value).toString(16));
|
value = AbiDecoder._padZeros(new BigNumber(value).toString(16));
|
||||||
} else if (param.type === SolidityTypes.Uint256 ||
|
} else if (
|
||||||
|
param.type === SolidityTypes.Uint256 ||
|
||||||
param.type === SolidityTypes.Uint8 ||
|
param.type === SolidityTypes.Uint8 ||
|
||||||
param.type === SolidityTypes.Uint) {
|
param.type === SolidityTypes.Uint
|
||||||
|
) {
|
||||||
value = new BigNumber(value);
|
value = new BigNumber(value);
|
||||||
}
|
}
|
||||||
decodedParams[param.name] = value;
|
decodedParams[param.name] = value;
|
||||||
|
@ -16,11 +16,15 @@ export const assert = {
|
|||||||
const isValidSignature = signatureUtils.isValidSignature(orderHash, ecSignature, signerAddress);
|
const isValidSignature = signatureUtils.isValidSignature(orderHash, ecSignature, signerAddress);
|
||||||
this.assert(isValidSignature, `Expected order with hash '${orderHash}' to have a valid signature`);
|
this.assert(isValidSignature, `Expected order with hash '${orderHash}' to have a valid signature`);
|
||||||
},
|
},
|
||||||
async isSenderAddressAsync(variableName: string, senderAddressHex: string,
|
async isSenderAddressAsync(
|
||||||
web3Wrapper: Web3Wrapper): Promise<void> {
|
variableName: string,
|
||||||
|
senderAddressHex: string,
|
||||||
|
web3Wrapper: Web3Wrapper,
|
||||||
|
): Promise<void> {
|
||||||
sharedAssert.isETHAddressHex(variableName, senderAddressHex);
|
sharedAssert.isETHAddressHex(variableName, senderAddressHex);
|
||||||
const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
|
const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
|
||||||
sharedAssert.assert(isSenderAddressAvailable,
|
sharedAssert.assert(
|
||||||
|
isSenderAddressAvailable,
|
||||||
`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
|
`Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,8 @@ const contractCallErrorTransformer = (error: Error) => {
|
|||||||
const schemaErrorTransformer = (error: Error) => {
|
const schemaErrorTransformer = (error: Error) => {
|
||||||
if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
|
if (_.includes(error.message, constants.INVALID_TAKER_FORMAT)) {
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
const errMsg = 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
const errMsg =
|
||||||
|
'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
||||||
return new Error(errMsg);
|
return new Error(errMsg);
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
@ -30,9 +31,11 @@ const schemaErrorTransformer = (error: Error) => {
|
|||||||
*/
|
*/
|
||||||
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||||
const asyncErrorHandlingDecorator = (
|
const asyncErrorHandlingDecorator = (
|
||||||
target: object, key: string|symbol, descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
target: object,
|
||||||
|
key: string | symbol,
|
||||||
|
descriptor: TypedPropertyDescriptor<AsyncMethod>,
|
||||||
) => {
|
) => {
|
||||||
const originalMethod = (descriptor.value as AsyncMethod);
|
const originalMethod = descriptor.value as AsyncMethod;
|
||||||
|
|
||||||
// Do not use arrow syntax here. Use a function expression in
|
// Do not use arrow syntax here. Use a function expression in
|
||||||
// order to use the correct value of `this` in this method
|
// order to use the correct value of `this` in this method
|
||||||
@ -55,9 +58,11 @@ const asyncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
|||||||
|
|
||||||
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
const syncErrorHandlerFactory = (errorTransformer: ErrorTransformer) => {
|
||||||
const syncErrorHandlingDecorator = (
|
const syncErrorHandlingDecorator = (
|
||||||
target: object, key: string|symbol, descriptor: TypedPropertyDescriptor<SyncMethod>,
|
target: object,
|
||||||
|
key: string | symbol,
|
||||||
|
descriptor: TypedPropertyDescriptor<SyncMethod>,
|
||||||
) => {
|
) => {
|
||||||
const originalMethod = (descriptor.value as SyncMethod);
|
const originalMethod = descriptor.value as SyncMethod;
|
||||||
|
|
||||||
// Do not use arrow syntax here. Use a function expression in
|
// Do not use arrow syntax here. Use a function expression in
|
||||||
// order to use the correct value of `this` in this method
|
// order to use the correct value of `this` in this method
|
||||||
|
@ -36,8 +36,11 @@ const ERR_MSG_MAPPING = {
|
|||||||
export class ExchangeTransferSimulator {
|
export class ExchangeTransferSimulator {
|
||||||
private _store: BalanceAndProxyAllowanceLazyStore;
|
private _store: BalanceAndProxyAllowanceLazyStore;
|
||||||
private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
|
private _UNLIMITED_ALLOWANCE_IN_BASE_UNITS: BigNumber;
|
||||||
private static _throwValidationError(failureReason: FailureReason, tradeSide: TradeSide,
|
private static _throwValidationError(
|
||||||
transferType: TransferType): never {
|
failureReason: FailureReason,
|
||||||
|
tradeSide: TradeSide,
|
||||||
|
transferType: TransferType,
|
||||||
|
): never {
|
||||||
const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
|
const errMsg = ERR_MSG_MAPPING[failureReason][tradeSide][transferType];
|
||||||
throw new Error(errMsg);
|
throw new Error(errMsg);
|
||||||
}
|
}
|
||||||
@ -54,9 +57,14 @@ export class ExchangeTransferSimulator {
|
|||||||
* @param tradeSide Is Maker/Taker transferring
|
* @param tradeSide Is Maker/Taker transferring
|
||||||
* @param transferType Is it a fee payment or a value transfer
|
* @param transferType Is it a fee payment or a value transfer
|
||||||
*/
|
*/
|
||||||
public async transferFromAsync(tokenAddress: string, from: string, to: string,
|
public async transferFromAsync(
|
||||||
amountInBaseUnits: BigNumber, tradeSide: TradeSide,
|
tokenAddress: string,
|
||||||
transferType: TransferType): Promise<void> {
|
from: string,
|
||||||
|
to: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
tradeSide: TradeSide,
|
||||||
|
transferType: TransferType,
|
||||||
|
): Promise<void> {
|
||||||
const balance = await this._store.getBalanceAsync(tokenAddress, from);
|
const balance = await this._store.getBalanceAsync(tokenAddress, from);
|
||||||
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
|
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, from);
|
||||||
if (proxyAllowance.lessThan(amountInBaseUnits)) {
|
if (proxyAllowance.lessThan(amountInBaseUnits)) {
|
||||||
@ -69,20 +77,29 @@ export class ExchangeTransferSimulator {
|
|||||||
await this._decreaseBalanceAsync(tokenAddress, from, amountInBaseUnits);
|
await this._decreaseBalanceAsync(tokenAddress, from, amountInBaseUnits);
|
||||||
await this._increaseBalanceAsync(tokenAddress, to, amountInBaseUnits);
|
await this._increaseBalanceAsync(tokenAddress, to, amountInBaseUnits);
|
||||||
}
|
}
|
||||||
private async _decreaseProxyAllowanceAsync(tokenAddress: string, userAddress: string,
|
private async _decreaseProxyAllowanceAsync(
|
||||||
amountInBaseUnits: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
userAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, userAddress);
|
const proxyAllowance = await this._store.getProxyAllowanceAsync(tokenAddress, userAddress);
|
||||||
if (!proxyAllowance.eq(this._UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
|
if (!proxyAllowance.eq(this._UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) {
|
||||||
this._store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits));
|
this._store.setProxyAllowance(tokenAddress, userAddress, proxyAllowance.minus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async _increaseBalanceAsync(tokenAddress: string, userAddress: string,
|
private async _increaseBalanceAsync(
|
||||||
amountInBaseUnits: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
userAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
||||||
this._store.setBalance(tokenAddress, userAddress, balance.plus(amountInBaseUnits));
|
this._store.setBalance(tokenAddress, userAddress, balance.plus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
private async _decreaseBalanceAsync(tokenAddress: string, userAddress: string,
|
private async _decreaseBalanceAsync(
|
||||||
amountInBaseUnits: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
userAddress: string,
|
||||||
|
amountInBaseUnits: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
const balance = await this._store.getBalanceAsync(tokenAddress, userAddress);
|
||||||
this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
|
this._store.setBalance(tokenAddress, userAddress, balance.minus(amountInBaseUnits));
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,13 @@ export const filterUtils = {
|
|||||||
generateUUID(): string {
|
generateUUID(): string {
|
||||||
return uuid();
|
return uuid();
|
||||||
},
|
},
|
||||||
getFilter(address: string, eventName: ContractEvents,
|
getFilter(
|
||||||
indexFilterValues: IndexedFilterValues, abi: Web3.ContractAbi,
|
address: string,
|
||||||
blockRange?: BlockRange): Web3.FilterObject {
|
eventName: ContractEvents,
|
||||||
|
indexFilterValues: IndexedFilterValues,
|
||||||
|
abi: Web3.ContractAbi,
|
||||||
|
blockRange?: BlockRange,
|
||||||
|
): Web3.FilterObject {
|
||||||
const eventAbi = _.find(abi, { name: eventName }) as Web3.EventAbi;
|
const eventAbi = _.find(abi, { name: eventName }) as Web3.EventAbi;
|
||||||
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName);
|
const eventSignature = filterUtils.getEventSignatureFromAbiByName(eventAbi, eventName);
|
||||||
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
const topicForEventSignature = ethUtil.addHexPrefix(jsSHA3.keccak256(eventSignature));
|
||||||
|
@ -46,13 +46,18 @@ export class OrderStateUtils {
|
|||||||
const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
|
const minFillableTakerTokenAmountWithinNoRoundingErrorRange = signedOrder.takerTokenAmount
|
||||||
.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
|
.dividedBy(ACCEPTABLE_RELATIVE_ROUNDING_ERROR)
|
||||||
.dividedBy(signedOrder.makerTokenAmount);
|
.dividedBy(signedOrder.makerTokenAmount);
|
||||||
if (orderRelevantState.remainingFillableTakerTokenAmount
|
if (
|
||||||
.lessThan(minFillableTakerTokenAmountWithinNoRoundingErrorRange)) {
|
orderRelevantState.remainingFillableTakerTokenAmount.lessThan(
|
||||||
|
minFillableTakerTokenAmountWithinNoRoundingErrorRange,
|
||||||
|
)
|
||||||
|
) {
|
||||||
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
constructor(balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
|
constructor(
|
||||||
orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore) {
|
balanceAndProxyAllowanceLazyStore: BalanceAndProxyAllowanceLazyStore,
|
||||||
|
orderFilledCancelledLazyStore: OrderFilledCancelledLazyStore,
|
||||||
|
) {
|
||||||
this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
|
this._balanceAndProxyAllowanceLazyStore = balanceAndProxyAllowanceLazyStore;
|
||||||
this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
|
this._orderFilledCancelledLazyStore = orderFilledCancelledLazyStore;
|
||||||
}
|
}
|
||||||
@ -85,16 +90,20 @@ export class OrderStateUtils {
|
|||||||
const zrxTokenAddress = exchange.getZRXTokenAddress();
|
const zrxTokenAddress = exchange.getZRXTokenAddress();
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
const makerBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
const makerBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker,
|
signedOrder.makerTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const makerProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
const makerProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker,
|
signedOrder.makerTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const makerFeeBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
const makerFeeBalance = await this._balanceAndProxyAllowanceLazyStore.getBalanceAsync(
|
||||||
zrxTokenAddress, signedOrder.maker,
|
zrxTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const makerFeeProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
const makerFeeProxyAllowance = await this._balanceAndProxyAllowanceLazyStore.getProxyAllowanceAsync(
|
||||||
zrxTokenAddress, signedOrder.maker,
|
zrxTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
);
|
);
|
||||||
const filledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getFilledTakerAmountAsync(orderHash);
|
const filledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getFilledTakerAmountAsync(orderHash);
|
||||||
const cancelledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getCancelledTakerAmountAsync(
|
const cancelledTakerTokenAmount = await this._orderFilledCancelledLazyStore.getCancelledTakerAmountAsync(
|
||||||
@ -104,17 +113,20 @@ export class OrderStateUtils {
|
|||||||
const totalMakerTokenAmount = signedOrder.makerTokenAmount;
|
const totalMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
const totalTakerTokenAmount = signedOrder.takerTokenAmount;
|
const totalTakerTokenAmount = signedOrder.takerTokenAmount;
|
||||||
const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount);
|
const remainingTakerTokenAmount = totalTakerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||||
const remainingMakerTokenAmount = remainingTakerTokenAmount.times(totalMakerTokenAmount)
|
const remainingMakerTokenAmount = remainingTakerTokenAmount
|
||||||
|
.times(totalMakerTokenAmount)
|
||||||
.dividedToIntegerBy(totalTakerTokenAmount);
|
.dividedToIntegerBy(totalTakerTokenAmount);
|
||||||
const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
|
const transferrableMakerTokenAmount = BigNumber.min([makerProxyAllowance, makerBalance]);
|
||||||
const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
|
const transferrableFeeTokenAmount = BigNumber.min([makerFeeProxyAllowance, makerFeeBalance]);
|
||||||
|
|
||||||
const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
|
const isMakerTokenZRX = signedOrder.makerTokenAddress === zrxTokenAddress;
|
||||||
const remainingFillableCalculator = new RemainingFillableCalculator(signedOrder,
|
const remainingFillableCalculator = new RemainingFillableCalculator(
|
||||||
|
signedOrder,
|
||||||
isMakerTokenZRX,
|
isMakerTokenZRX,
|
||||||
transferrableMakerTokenAmount,
|
transferrableMakerTokenAmount,
|
||||||
transferrableFeeTokenAmount,
|
transferrableFeeTokenAmount,
|
||||||
remainingMakerTokenAmount);
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
|
const remainingFillableMakerTokenAmount = remainingFillableCalculator.computeRemainingMakerFillable();
|
||||||
const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
|
const remainingFillableTakerTokenAmount = remainingFillableCalculator.computeRemainingTakerFillable();
|
||||||
const orderRelevantState = {
|
const orderRelevantState = {
|
||||||
|
@ -12,7 +12,9 @@ import {ExchangeTransferSimulator} from './exchange_transfer_simulator';
|
|||||||
export class OrderValidationUtils {
|
export class OrderValidationUtils {
|
||||||
private _exchangeWrapper: ExchangeWrapper;
|
private _exchangeWrapper: ExchangeWrapper;
|
||||||
public static validateCancelOrderThrowIfInvalid(
|
public static validateCancelOrderThrowIfInvalid(
|
||||||
order: Order, cancelTakerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber,
|
order: Order,
|
||||||
|
cancelTakerTokenAmount: BigNumber,
|
||||||
|
unavailableTakerTokenAmount: BigNumber,
|
||||||
): void {
|
): void {
|
||||||
if (cancelTakerTokenAmount.eq(0)) {
|
if (cancelTakerTokenAmount.eq(0)) {
|
||||||
throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
|
throw new Error(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
@ -26,8 +28,11 @@ export class OrderValidationUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
public static async validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
fillTakerTokenAmount: BigNumber, senderAddress: string, zrxTokenAddress: string,
|
signedOrder: SignedOrder,
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
senderAddress: string,
|
||||||
|
zrxTokenAddress: string,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
|
const fillMakerTokenAmount = OrderValidationUtils._getPartialAmount(
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
@ -35,12 +40,20 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerTokenAmount,
|
signedOrder.makerTokenAmount,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker, senderAddress, fillMakerTokenAmount,
|
signedOrder.makerTokenAddress,
|
||||||
TradeSide.Maker, TransferType.Trade,
|
signedOrder.maker,
|
||||||
|
senderAddress,
|
||||||
|
fillMakerTokenAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
signedOrder.takerTokenAddress, senderAddress, signedOrder.maker, fillTakerTokenAmount,
|
signedOrder.takerTokenAddress,
|
||||||
TradeSide.Taker, TransferType.Trade,
|
senderAddress,
|
||||||
|
signedOrder.maker,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
@ -48,7 +61,11 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerFee,
|
signedOrder.makerFee,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount, TradeSide.Maker,
|
zrxTokenAddress,
|
||||||
|
signedOrder.maker,
|
||||||
|
signedOrder.feeRecipient,
|
||||||
|
makerFeeAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
TransferType.Fee,
|
TransferType.Fee,
|
||||||
);
|
);
|
||||||
const takerFeeAmount = OrderValidationUtils._getPartialAmount(
|
const takerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||||
@ -57,12 +74,17 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.takerFee,
|
signedOrder.takerFee,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
zrxTokenAddress, senderAddress, signedOrder.feeRecipient, takerFeeAmount, TradeSide.Taker,
|
zrxTokenAddress,
|
||||||
|
senderAddress,
|
||||||
|
signedOrder.feeRecipient,
|
||||||
|
takerFeeAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
TransferType.Fee,
|
TransferType.Fee,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
private static _validateRemainingFillAmountNotZeroOrThrow(
|
private static _validateRemainingFillAmountNotZeroOrThrow(
|
||||||
takerTokenAmount: BigNumber, unavailableTakerTokenAmount: BigNumber,
|
takerTokenAmount: BigNumber,
|
||||||
|
unavailableTakerTokenAmount: BigNumber,
|
||||||
) {
|
) {
|
||||||
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
|
if (takerTokenAmount.eq(unavailableTakerTokenAmount)) {
|
||||||
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
throw new Error(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||||
@ -74,8 +96,7 @@ export class OrderValidationUtils {
|
|||||||
throw new Error(ExchangeContractErrs.OrderFillExpired);
|
throw new Error(ExchangeContractErrs.OrderFillExpired);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber,
|
private static _getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
|
||||||
target: BigNumber): BigNumber {
|
|
||||||
const fillMakerTokenAmount = numerator
|
const fillMakerTokenAmount = numerator
|
||||||
.mul(target)
|
.mul(target)
|
||||||
.div(denominator)
|
.div(denominator)
|
||||||
@ -86,12 +107,16 @@ export class OrderValidationUtils {
|
|||||||
this._exchangeWrapper = exchangeWrapper;
|
this._exchangeWrapper = exchangeWrapper;
|
||||||
}
|
}
|
||||||
public async validateOrderFillableOrThrowAsync(
|
public async validateOrderFillableOrThrowAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder, zrxTokenAddress: string,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
expectedFillTakerTokenAmount?: BigNumber): Promise<void> {
|
signedOrder: SignedOrder,
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
expectedFillTakerTokenAmount?: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
const orderHash = utils.getOrderHashHex(signedOrder);
|
const orderHash = utils.getOrderHashHex(signedOrder);
|
||||||
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
||||||
signedOrder.takerTokenAmount, unavailableTakerTokenAmount,
|
signedOrder.takerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
);
|
);
|
||||||
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
||||||
let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
let fillTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||||
@ -104,8 +129,12 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerTokenAmount,
|
signedOrder.makerTokenAmount,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
signedOrder.makerTokenAddress, signedOrder.maker, signedOrder.taker, fillMakerTokenAmount,
|
signedOrder.makerTokenAddress,
|
||||||
TradeSide.Maker, TransferType.Trade,
|
signedOrder.maker,
|
||||||
|
signedOrder.taker,
|
||||||
|
fillMakerTokenAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
const makerFeeAmount = OrderValidationUtils._getPartialAmount(
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
@ -113,14 +142,21 @@ export class OrderValidationUtils {
|
|||||||
signedOrder.makerFee,
|
signedOrder.makerFee,
|
||||||
);
|
);
|
||||||
await exchangeTradeEmulator.transferFromAsync(
|
await exchangeTradeEmulator.transferFromAsync(
|
||||||
zrxTokenAddress, signedOrder.maker, signedOrder.feeRecipient, makerFeeAmount,
|
zrxTokenAddress,
|
||||||
TradeSide.Maker, TransferType.Fee,
|
signedOrder.maker,
|
||||||
|
signedOrder.feeRecipient,
|
||||||
|
makerFeeAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Fee,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async validateFillOrderThrowIfInvalidAsync(
|
public async validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
fillTakerTokenAmount: BigNumber, takerAddress: string,
|
signedOrder: SignedOrder,
|
||||||
zrxTokenAddress: string): Promise<BigNumber> {
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
): Promise<BigNumber> {
|
||||||
if (fillTakerTokenAmount.eq(0)) {
|
if (fillTakerTokenAmount.eq(0)) {
|
||||||
throw new Error(ExchangeContractErrs.OrderFillAmountZero);
|
throw new Error(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
}
|
}
|
||||||
@ -130,22 +166,29 @@ export class OrderValidationUtils {
|
|||||||
}
|
}
|
||||||
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
const unavailableTakerTokenAmount = await this._exchangeWrapper.getUnavailableTakerAmountAsync(orderHash);
|
||||||
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
OrderValidationUtils._validateRemainingFillAmountNotZeroOrThrow(
|
||||||
signedOrder.takerTokenAmount, unavailableTakerTokenAmount,
|
signedOrder.takerTokenAmount,
|
||||||
|
unavailableTakerTokenAmount,
|
||||||
);
|
);
|
||||||
if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
|
if (signedOrder.taker !== constants.NULL_ADDRESS && signedOrder.taker !== takerAddress) {
|
||||||
throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
throw new Error(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
||||||
}
|
}
|
||||||
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
OrderValidationUtils._validateOrderNotExpiredOrThrow(signedOrder.expirationUnixTimestampSec);
|
||||||
const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
const remainingTakerTokenAmount = signedOrder.takerTokenAmount.minus(unavailableTakerTokenAmount);
|
||||||
const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount) ?
|
const filledTakerTokenAmount = remainingTakerTokenAmount.lessThan(fillTakerTokenAmount)
|
||||||
remainingTakerTokenAmount :
|
? remainingTakerTokenAmount
|
||||||
fillTakerTokenAmount;
|
: fillTakerTokenAmount;
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, filledTakerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
filledTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
|
|
||||||
const wouldRoundingErrorOccur = await this._exchangeWrapper.isRoundingErrorAsync(
|
const wouldRoundingErrorOccur = await this._exchangeWrapper.isRoundingErrorAsync(
|
||||||
filledTakerTokenAmount, signedOrder.takerTokenAmount, signedOrder.makerTokenAmount,
|
filledTakerTokenAmount,
|
||||||
|
signedOrder.takerTokenAmount,
|
||||||
|
signedOrder.makerTokenAmount,
|
||||||
);
|
);
|
||||||
if (wouldRoundingErrorOccur) {
|
if (wouldRoundingErrorOccur) {
|
||||||
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
throw new Error(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
@ -153,10 +196,18 @@ export class OrderValidationUtils {
|
|||||||
return filledTakerTokenAmount;
|
return filledTakerTokenAmount;
|
||||||
}
|
}
|
||||||
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
public async validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator: ExchangeTransferSimulator, signedOrder: SignedOrder,
|
exchangeTradeEmulator: ExchangeTransferSimulator,
|
||||||
fillTakerTokenAmount: BigNumber, takerAddress: string, zrxTokenAddress: string): Promise<void> {
|
signedOrder: SignedOrder,
|
||||||
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
takerAddress: string,
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
): Promise<void> {
|
||||||
const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
|
const filledTakerTokenAmount = await this.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTradeEmulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
if (filledTakerTokenAmount !== fillTakerTokenAmount) {
|
if (filledTakerTokenAmount !== fillTakerTokenAmount) {
|
||||||
throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
throw new Error(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
||||||
|
@ -11,7 +11,8 @@ export const signatureUtils = {
|
|||||||
msgHashBuff,
|
msgHashBuff,
|
||||||
signature.v,
|
signature.v,
|
||||||
ethUtil.toBuffer(signature.r),
|
ethUtil.toBuffer(signature.r),
|
||||||
ethUtil.toBuffer(signature.s));
|
ethUtil.toBuffer(signature.s),
|
||||||
|
);
|
||||||
const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
|
const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
|
||||||
return retrievedAddress === signerAddress;
|
return retrievedAddress === signerAddress;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -37,11 +37,26 @@ export const utils = {
|
|||||||
{ value: order.makerTokenAddress, type: SolidityTypes.Address },
|
{ value: order.makerTokenAddress, type: SolidityTypes.Address },
|
||||||
{ value: order.takerTokenAddress, type: SolidityTypes.Address },
|
{ value: order.takerTokenAddress, type: SolidityTypes.Address },
|
||||||
{ value: order.feeRecipient, type: SolidityTypes.Address },
|
{ value: order.feeRecipient, type: SolidityTypes.Address },
|
||||||
{value: utils.bigNumberToBN(order.makerTokenAmount), type: SolidityTypes.Uint256},
|
{
|
||||||
{value: utils.bigNumberToBN(order.takerTokenAmount), type: SolidityTypes.Uint256},
|
value: utils.bigNumberToBN(order.makerTokenAmount),
|
||||||
{value: utils.bigNumberToBN(order.makerFee), type: SolidityTypes.Uint256},
|
type: SolidityTypes.Uint256,
|
||||||
{value: utils.bigNumberToBN(order.takerFee), type: SolidityTypes.Uint256},
|
},
|
||||||
{value: utils.bigNumberToBN(order.expirationUnixTimestampSec), type: SolidityTypes.Uint256},
|
{
|
||||||
|
value: utils.bigNumberToBN(order.takerTokenAmount),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: utils.bigNumberToBN(order.makerFee),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: utils.bigNumberToBN(order.takerFee),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: utils.bigNumberToBN(order.expirationUnixTimestampSec),
|
||||||
|
type: SolidityTypes.Uint256,
|
||||||
|
},
|
||||||
{ value: utils.bigNumberToBN(order.salt), type: SolidityTypes.Uint256 },
|
{ value: utils.bigNumberToBN(order.salt), type: SolidityTypes.Uint256 },
|
||||||
];
|
];
|
||||||
const types = _.map(orderParts, o => o.type);
|
const types = _.map(orderParts, o => o.type);
|
||||||
|
@ -41,11 +41,11 @@ describe('ZeroEx library', () => {
|
|||||||
|
|
||||||
// Check that all nested web3 wrapper instances return the updated provider
|
// Check that all nested web3 wrapper instances return the updated provider
|
||||||
const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
|
const nestedWeb3WrapperProvider = (zeroEx as any)._web3Wrapper.getCurrentProvider();
|
||||||
expect((nestedWeb3WrapperProvider).zeroExTestId).to.be.a('number');
|
expect(nestedWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||||
const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
|
const exchangeWeb3WrapperProvider = (zeroEx.exchange as any)._web3Wrapper.getCurrentProvider();
|
||||||
expect((exchangeWeb3WrapperProvider).zeroExTestId).to.be.a('number');
|
expect(exchangeWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||||
const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
|
const tokenRegistryWeb3WrapperProvider = (zeroEx.tokenRegistry as any)._web3Wrapper.getCurrentProvider();
|
||||||
expect((tokenRegistryWeb3WrapperProvider).zeroExTestId).to.be.a('number');
|
expect(tokenRegistryWeb3WrapperProvider.zeroExTestId).to.be.a('number');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isValidSignature', () => {
|
describe('#isValidSignature', () => {
|
||||||
@ -58,21 +58,24 @@ describe('ZeroEx library', () => {
|
|||||||
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
|
s: '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254',
|
||||||
};
|
};
|
||||||
const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
|
const address = '0x5409ed021d9299bf6814279a6a1411a7e866a631';
|
||||||
it('should return false if the data doesn\'t pertain to the signature & address', async () => {
|
it("should return false if the data doesn't pertain to the signature & address", async () => {
|
||||||
expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
|
expect(ZeroEx.isValidSignature('0x0', signature, address)).to.be.false();
|
||||||
return expect(
|
return expect(
|
||||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
|
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync('0x0', signature, address),
|
||||||
).to.become(false);
|
).to.become(false);
|
||||||
});
|
});
|
||||||
it('should return false if the address doesn\'t pertain to the signature & data', async () => {
|
it("should return false if the address doesn't pertain to the signature & data", async () => {
|
||||||
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
|
const validUnrelatedAddress = '0x8b0292b11a196601ed2ce54b665cafeca0347d42';
|
||||||
expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
|
expect(ZeroEx.isValidSignature(dataHex, signature, validUnrelatedAddress)).to.be.false();
|
||||||
return expect(
|
return expect(
|
||||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature,
|
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(
|
||||||
validUnrelatedAddress),
|
dataHex,
|
||||||
|
signature,
|
||||||
|
validUnrelatedAddress,
|
||||||
|
),
|
||||||
).to.become(false);
|
).to.become(false);
|
||||||
});
|
});
|
||||||
it('should return false if the signature doesn\'t pertain to the dataHex & address', async () => {
|
it("should return false if the signature doesn't pertain to the dataHex & address", async () => {
|
||||||
const wrongSignature = _.assign({}, signature, { v: 28 });
|
const wrongSignature = _.assign({}, signature, { v: 28 });
|
||||||
expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
|
expect(ZeroEx.isValidSignature(dataHex, wrongSignature, address)).to.be.false();
|
||||||
return expect(
|
return expect(
|
||||||
@ -117,8 +120,9 @@ describe('ZeroEx library', () => {
|
|||||||
it('should throw if invalid baseUnit amount supplied as argument', () => {
|
it('should throw if invalid baseUnit amount supplied as argument', () => {
|
||||||
const invalidBaseUnitAmount = new BigNumber(1000000000.4);
|
const invalidBaseUnitAmount = new BigNumber(1000000000.4);
|
||||||
const decimals = 6;
|
const decimals = 6;
|
||||||
expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals))
|
expect(() => ZeroEx.toUnitAmount(invalidBaseUnitAmount, decimals)).to.throw(
|
||||||
.to.throw('amount should be in baseUnits (no decimals), found value: 1000000000.4');
|
'amount should be in baseUnits (no decimals), found value: 1000000000.4',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('Should return the expected unit amount for the decimals passed in', () => {
|
it('Should return the expected unit amount for the decimals passed in', () => {
|
||||||
const baseUnitAmount = new BigNumber(1000000000);
|
const baseUnitAmount = new BigNumber(1000000000);
|
||||||
@ -139,8 +143,9 @@ describe('ZeroEx library', () => {
|
|||||||
it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
|
it('should throw if unitAmount has more decimals then specified as the max decimal precision', () => {
|
||||||
const unitAmount = new BigNumber(0.823091);
|
const unitAmount = new BigNumber(0.823091);
|
||||||
const decimals = 5;
|
const decimals = 5;
|
||||||
expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals))
|
expect(() => ZeroEx.toBaseUnitAmount(unitAmount, decimals)).to.throw(
|
||||||
.to.throw('Invalid unit amount: 0.823091 - Too many decimal places');
|
'Invalid unit amount: 0.823091 - Too many decimal places',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#getOrderHashHex', () => {
|
describe('#getOrderHashHex', () => {
|
||||||
@ -167,10 +172,11 @@ describe('ZeroEx library', () => {
|
|||||||
it('throws a readable error message if taker format is invalid', async () => {
|
it('throws a readable error message if taker format is invalid', async () => {
|
||||||
const orderWithInvalidtakerFormat = {
|
const orderWithInvalidtakerFormat = {
|
||||||
...order,
|
...order,
|
||||||
taker: null as any as string,
|
taker: (null as any) as string,
|
||||||
};
|
};
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
const expectedErrorMessage = 'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
const expectedErrorMessage =
|
||||||
|
'Order taker must be of type string. If you want anyone to be able to fill an order - pass ZeroEx.NULL_ADDRESS';
|
||||||
expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
|
expect(() => ZeroEx.getOrderHashHex(orderWithInvalidtakerFormat)).to.throw(expectedErrorMessage);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -199,15 +205,15 @@ describe('ZeroEx library', () => {
|
|||||||
it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
|
it('should return the correct ECSignature for signatureHex concatenated as R + S + V', async () => {
|
||||||
const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
|
const orderHash = '0x34decbedc118904df65f379a175bb39ca18209d6ce41d5ed549d54e6e0a95004';
|
||||||
// tslint:disable-next-line: max-line-length
|
// tslint:disable-next-line: max-line-length
|
||||||
const signature = '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
|
const signature =
|
||||||
|
'0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb021b';
|
||||||
const expectedECSignature = {
|
const expectedECSignature = {
|
||||||
v: 27,
|
v: 27,
|
||||||
r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
|
r: '0x22109d11d79cb8bf96ed88625e1cd9558800c4073332a9a02857499883ee5ce3',
|
||||||
s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
|
s: '0x050aa3cc1f2c435e67e114cdce54b9527b4f50548342401bc5d2b77adbdacb02',
|
||||||
};
|
};
|
||||||
stubs = [
|
stubs = [
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync')
|
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
|
||||||
.returns(Promise.resolve(signature)),
|
|
||||||
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -217,15 +223,15 @@ describe('ZeroEx library', () => {
|
|||||||
it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
|
it('should return the correct ECSignature for signatureHex concatenated as V + R + S', async () => {
|
||||||
const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
|
const orderHash = '0xc793e33ffded933b76f2f48d9aa3339fc090399d5e7f5dec8d3660f5480793f7';
|
||||||
// tslint:disable-next-line: max-line-length
|
// tslint:disable-next-line: max-line-length
|
||||||
const signature = '0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
|
const signature =
|
||||||
|
'0x1bc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee02dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960';
|
||||||
const expectedECSignature = {
|
const expectedECSignature = {
|
||||||
v: 27,
|
v: 27,
|
||||||
r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
|
r: '0xc80bedc6756722672753413efdd749b5adbd4fd552595f59c13427407ee9aee0',
|
||||||
s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
|
s: '0x2dea66f25a608bbae457e020fb6decb763deb8b7192abab624997242da248960',
|
||||||
};
|
};
|
||||||
stubs = [
|
stubs = [
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync')
|
Sinon.stub((zeroEx as any)._web3Wrapper, 'signTransactionAsync').returns(Promise.resolve(signature)),
|
||||||
.returns(Promise.resolve(signature)),
|
|
||||||
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
Sinon.stub(ZeroEx, 'isValidSignature').returns(true),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -271,8 +277,9 @@ describe('ZeroEx library', () => {
|
|||||||
networkId: constants.TESTRPC_NETWORK_ID,
|
networkId: constants.TESTRPC_NETWORK_ID,
|
||||||
};
|
};
|
||||||
const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
|
const zeroExWithWrongTokenRegistryAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
|
||||||
expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress())
|
expect(zeroExWithWrongTokenRegistryAddress.tokenRegistry.getContractAddress()).to.be.equal(
|
||||||
.to.be.equal(ZeroEx.NULL_ADDRESS);
|
ZeroEx.NULL_ADDRESS,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,22 +19,25 @@ describe('Assertion library', () => {
|
|||||||
it('throws when address is invalid', async () => {
|
it('throws when address is invalid', async () => {
|
||||||
const address = '0xdeadbeef';
|
const address = '0xdeadbeef';
|
||||||
const varName = 'address';
|
const varName = 'address';
|
||||||
return expect(assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper))
|
return expect(
|
||||||
.to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
|
assert.isSenderAddressAsync(varName, address, (zeroEx as any)._web3Wrapper),
|
||||||
|
).to.be.rejectedWith(`Expected ${varName} to be of type ETHAddressHex, encountered: ${address}`);
|
||||||
});
|
});
|
||||||
it('throws when address is unavailable', async () => {
|
it('throws when address is unavailable', async () => {
|
||||||
const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
|
const validUnrelatedAddress = '0x8b0292b11a196601eddce54b665cafeca0347d42';
|
||||||
const varName = 'address';
|
const varName = 'address';
|
||||||
return expect(assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper))
|
return expect(
|
||||||
.to.be.rejectedWith(
|
assert.isSenderAddressAsync(varName, validUnrelatedAddress, (zeroEx as any)._web3Wrapper),
|
||||||
|
).to.be.rejectedWith(
|
||||||
`Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
|
`Specified ${varName} ${validUnrelatedAddress} isn't available through the supplied web3 provider`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('doesn\'t throw if address is available', async () => {
|
it("doesn't throw if address is available", async () => {
|
||||||
const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
|
const availableAddress = (await zeroEx.getAvailableAddressesAsync())[0];
|
||||||
const varName = 'address';
|
const varName = 'address';
|
||||||
return expect(assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper))
|
return expect(
|
||||||
.to.become(undefined);
|
assert.isSenderAddressAsync(varName, availableAddress, (zeroEx as any)._web3Wrapper),
|
||||||
|
).to.become(undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -167,10 +167,12 @@ describe('EtherTokenWrapper', () => {
|
|||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -186,10 +188,12 @@ describe('EtherTokenWrapper', () => {
|
|||||||
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
|
||||||
etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(
|
await zeroEx.token.setAllowanceAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, allowanceAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
allowanceAmount,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -204,11 +208,8 @@ describe('EtherTokenWrapper', () => {
|
|||||||
expect(args._value).to.be.bignumber.equal(depositAmount);
|
expect(args._value).to.be.bignumber.equal(depositAmount);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
|
||||||
etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
|
||||||
await zeroEx.etherToken.depositAsync(
|
|
||||||
etherTokenAddress, depositAmount, addressWithETH,
|
|
||||||
);
|
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
|
it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => {
|
||||||
@ -222,14 +223,14 @@ describe('EtherTokenWrapper', () => {
|
|||||||
expect(args._value).to.be.bignumber.equal(depositAmount);
|
expect(args._value).to.be.bignumber.equal(depositAmount);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
await zeroEx.etherToken.depositAsync(
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH);
|
||||||
etherTokenAddress, depositAmount, addressWithETH,
|
|
||||||
);
|
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Withdrawal, indexFilterValues, callback);
|
etherTokenAddress,
|
||||||
await zeroEx.etherToken.withdrawAsync(
|
EtherTokenEvents.Withdrawal,
|
||||||
etherTokenAddress, withdrawalAmount, addressWithETH,
|
indexFilterValues,
|
||||||
|
callback,
|
||||||
);
|
);
|
||||||
|
await zeroEx.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => {
|
||||||
@ -238,7 +239,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
};
|
};
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
|
etherTokenAddress,
|
||||||
|
EtherTokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
);
|
);
|
||||||
const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done();
|
done();
|
||||||
@ -247,10 +251,16 @@ describe('EtherTokenWrapper', () => {
|
|||||||
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
||||||
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||||
zeroEx.etherToken.subscribe(
|
zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackToBeCalled,
|
etherTokenAddress,
|
||||||
|
EtherTokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackToBeCalled,
|
||||||
);
|
);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -261,10 +271,17 @@ describe('EtherTokenWrapper', () => {
|
|||||||
};
|
};
|
||||||
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH);
|
||||||
const subscriptionToken = zeroEx.etherToken.subscribe(
|
const subscriptionToken = zeroEx.etherToken.subscribe(
|
||||||
etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
|
etherTokenAddress,
|
||||||
|
EtherTokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
|
);
|
||||||
zeroEx.etherToken.unsubscribe(subscriptionToken);
|
zeroEx.etherToken.unsubscribe(subscriptionToken);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
etherTokenAddress, addressWithETH, addressWithoutFunds, transferAmount,
|
etherTokenAddress,
|
||||||
|
addressWithETH,
|
||||||
|
addressWithoutFunds,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
@ -291,7 +308,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const eventName = EtherTokenEvents.Approval;
|
const eventName = EtherTokenEvents.Approval;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@ -305,7 +325,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const eventName = EtherTokenEvents.Deposit;
|
const eventName = EtherTokenEvents.Deposit;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
|
const logs = await zeroEx.etherToken.getLogsAsync<DepositContractEventArgs>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@ -319,7 +342,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
const differentEventName = EtherTokenEvents.Transfer;
|
const differentEventName = EtherTokenEvents.Transfer;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync(
|
const logs = await zeroEx.etherToken.getLogsAsync(
|
||||||
etherTokenAddress, differentEventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
differentEventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(0);
|
expect(logs).to.have.length(0);
|
||||||
});
|
});
|
||||||
@ -333,7 +359,10 @@ describe('EtherTokenWrapper', () => {
|
|||||||
_owner: addressWithETH,
|
_owner: addressWithETH,
|
||||||
};
|
};
|
||||||
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.etherToken.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
etherTokenAddress, eventName, blockRange, indexFilterValues,
|
etherTokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
|
@ -5,9 +5,7 @@ import 'mocha';
|
|||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {
|
import { LogEvent } from '../src';
|
||||||
LogEvent,
|
|
||||||
} from '../src';
|
|
||||||
import { EventWatcher } from '../src/order_watcher/event_watcher';
|
import { EventWatcher } from '../src/order_watcher/event_watcher';
|
||||||
import { DoneCallback } from '../src/types';
|
import { DoneCallback } from '../src/types';
|
||||||
|
|
||||||
|
@ -45,17 +45,31 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
|
exchangeTransferSimulator = new ExchangeTransferSimulator(zeroEx.token, BlockParamLiteral.Latest);
|
||||||
});
|
});
|
||||||
it('throws if the user doesn\'t have enough allowance', async () => {
|
it("throws if the user doesn't have enough allowance", async () => {
|
||||||
return expect(exchangeTransferSimulator.transferFromAsync(
|
return expect(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
|
exchangeTransferSimulator.transferFromAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.InsufficientTakerAllowance);
|
||||||
});
|
});
|
||||||
it('throws if the user doesn\'t have enough balance', async () => {
|
it("throws if the user doesn't have enough balance", async () => {
|
||||||
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
return expect(exchangeTransferSimulator.transferFromAsync(
|
return expect(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Maker, TransferType.Trade,
|
exchangeTransferSimulator.transferFromAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.InsufficientMakerBalance);
|
||||||
});
|
});
|
||||||
it('updates balances and proxyAllowance after transfer', async () => {
|
it('updates balances and proxyAllowance after transfer', async () => {
|
||||||
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
||||||
@ -63,7 +77,12 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
txHash = await zeroEx.token.setProxyAllowanceAsync(exampleTokenAddress, sender, transferAmount);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
await exchangeTransferSimulator.transferFromAsync(
|
await exchangeTransferSimulator.transferFromAsync(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const store = (exchangeTransferSimulator as any)._store;
|
const store = (exchangeTransferSimulator as any)._store;
|
||||||
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
||||||
@ -73,13 +92,18 @@ describe('ExchangeTransferSimulator', () => {
|
|||||||
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
|
expect(recipientBalance).to.be.bignumber.equal(transferAmount);
|
||||||
expect(senderProxyAllowance).to.be.bignumber.equal(0);
|
expect(senderProxyAllowance).to.be.bignumber.equal(0);
|
||||||
});
|
});
|
||||||
it('doesn\'t update proxyAllowance after transfer if unlimited', async () => {
|
it("doesn't update proxyAllowance after transfer if unlimited", async () => {
|
||||||
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
txHash = await zeroEx.token.transferAsync(exampleTokenAddress, coinbase, sender, transferAmount);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
|
txHash = await zeroEx.token.setUnlimitedProxyAllowanceAsync(exampleTokenAddress, sender);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
await exchangeTransferSimulator.transferFromAsync(
|
await exchangeTransferSimulator.transferFromAsync(
|
||||||
exampleTokenAddress, sender, recipient, transferAmount, TradeSide.Taker, TransferType.Trade,
|
exampleTokenAddress,
|
||||||
|
sender,
|
||||||
|
recipient,
|
||||||
|
transferAmount,
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
);
|
);
|
||||||
const store = (exchangeTransferSimulator as any)._store;
|
const store = (exchangeTransferSimulator as any)._store;
|
||||||
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
const senderBalance = await store.getBalanceAsync(exampleTokenAddress, sender);
|
||||||
|
@ -80,10 +80,18 @@ describe('ExchangeWrapper', () => {
|
|||||||
const fillableAmount = new BigNumber(5);
|
const fillableAmount = new BigNumber(5);
|
||||||
const partialFillTakerAmount = new BigNumber(2);
|
const partialFillTakerAmount = new BigNumber(2);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderFillRequests = [
|
const orderFillRequests = [
|
||||||
{
|
{
|
||||||
@ -103,7 +111,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
const fillableAmount = new BigNumber(5);
|
const fillableAmount = new BigNumber(5);
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
orderFillRequests = [
|
orderFillRequests = [
|
||||||
{
|
{
|
||||||
@ -113,18 +125,23 @@ describe('ExchangeWrapper', () => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
|
return expect(
|
||||||
|
zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
}),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
|
return expect(
|
||||||
|
zeroEx.exchange.batchFillOrKillAsync(orderFillRequests, takerAddress, {
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
}),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -133,57 +150,78 @@ describe('ExchangeWrapper', () => {
|
|||||||
const fillableAmount = new BigNumber(5);
|
const fillableAmount = new BigNumber(5);
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
describe('successful fills', () => {
|
describe('successful fills', () => {
|
||||||
it('should fill a valid order', async () => {
|
it('should fill a valid order', async () => {
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount);
|
fillableAmount,
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
);
|
||||||
.to.be.bignumber.equal(0);
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
0,
|
||||||
.to.be.bignumber.equal(0);
|
);
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount);
|
0,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount,
|
||||||
|
);
|
||||||
await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
|
await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress);
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
|
fillableAmount.minus(takerTokenFillAmount),
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
);
|
||||||
.to.be.bignumber.equal(takerTokenFillAmount);
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
takerTokenFillAmount,
|
||||||
.to.be.bignumber.equal(takerTokenFillAmount);
|
);
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
|
takerTokenFillAmount,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount.minus(takerTokenFillAmount),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should partially fill a valid order', async () => {
|
it('should partially fill a valid order', async () => {
|
||||||
const partialFillAmount = new BigNumber(3);
|
const partialFillAmount = new BigNumber(3);
|
||||||
await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
|
await zeroEx.exchange.fillOrKillOrderAsync(signedOrder, partialFillAmount, takerAddress);
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
|
fillableAmount.minus(partialFillAmount),
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
);
|
||||||
.to.be.bignumber.equal(partialFillAmount);
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
partialFillAmount,
|
||||||
.to.be.bignumber.equal(partialFillAmount);
|
);
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
|
partialFillAmount,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount.minus(partialFillAmount),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('order transaction options', () => {
|
describe('order transaction options', () => {
|
||||||
const emptyFillableAmount = new BigNumber(0);
|
const emptyFillableAmount = new BigNumber(0);
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
|
return expect(
|
||||||
|
zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
}),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
|
return expect(
|
||||||
|
zeroEx.exchange.fillOrKillOrderAsync(signedOrder, emptyFillableAmount, takerAddress, {
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
}),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -209,57 +247,96 @@ describe('ExchangeWrapper', () => {
|
|||||||
describe('successful fills', () => {
|
describe('successful fills', () => {
|
||||||
it('should fill a valid order', async () => {
|
it('should fill a valid order', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
|
||||||
.to.be.bignumber.equal(fillableAmount);
|
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
|
||||||
.to.be.bignumber.equal(0);
|
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
|
||||||
.to.be.bignumber.equal(0);
|
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
|
||||||
.to.be.bignumber.equal(fillableAmount);
|
|
||||||
const txHash = await zeroEx.exchange.fillOrderAsync(
|
const txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, takerTokenFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
|
signedOrder,
|
||||||
|
takerTokenFillAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
|
fillableAmount.minus(takerTokenFillAmount),
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
);
|
||||||
.to.be.bignumber.equal(takerTokenFillAmount);
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
takerTokenFillAmount,
|
||||||
.to.be.bignumber.equal(takerTokenFillAmount);
|
);
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(takerTokenFillAmount));
|
takerTokenFillAmount,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount.minus(takerTokenFillAmount),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should partially fill the valid order', async () => {
|
it('should partially fill the valid order', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const partialFillAmount = new BigNumber(3);
|
const partialFillAmount = new BigNumber(3);
|
||||||
const txHash = await zeroEx.exchange.fillOrderAsync(
|
const txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, partialFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
|
signedOrder,
|
||||||
|
partialFillAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
|
fillableAmount.minus(partialFillAmount),
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress))
|
);
|
||||||
.to.be.bignumber.equal(partialFillAmount);
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, makerAddress)).to.be.bignumber.equal(
|
||||||
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress))
|
partialFillAmount,
|
||||||
.to.be.bignumber.equal(partialFillAmount);
|
);
|
||||||
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress))
|
expect(await zeroEx.token.getBalanceAsync(makerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(fillableAmount.minus(partialFillAmount));
|
partialFillAmount,
|
||||||
|
);
|
||||||
|
expect(await zeroEx.token.getBalanceAsync(takerTokenAddress, takerAddress)).to.be.bignumber.equal(
|
||||||
|
fillableAmount.minus(partialFillAmount),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should fill the valid orders with fees', async () => {
|
it('should fill the valid orders with fees', async () => {
|
||||||
const makerFee = new BigNumber(1);
|
const makerFee = new BigNumber(1);
|
||||||
const takerFee = new BigNumber(2);
|
const takerFee = new BigNumber(2);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
makerTokenAddress,
|
||||||
makerAddress, takerAddress, fillableAmount, feeRecipient,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
);
|
);
|
||||||
const txHash = await zeroEx.exchange.fillOrderAsync(
|
const txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, takerTokenFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
|
signedOrder,
|
||||||
|
takerTokenFillAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient))
|
expect(await zeroEx.token.getBalanceAsync(zrxTokenAddress, feeRecipient)).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(makerFee.plus(takerFee));
|
makerFee.plus(takerFee),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('order transaction options', () => {
|
describe('order transaction options', () => {
|
||||||
@ -267,25 +344,48 @@ describe('ExchangeWrapper', () => {
|
|||||||
const emptyFillTakerAmount = new BigNumber(0);
|
const emptyFillTakerAmount = new BigNumber(0);
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrderAsync(
|
return expect(
|
||||||
signedOrder, emptyFillTakerAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
zeroEx.exchange.fillOrderAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
signedOrder,
|
||||||
|
emptyFillTakerAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrderAsync(
|
return expect(
|
||||||
signedOrder, emptyFillTakerAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
|
zeroEx.exchange.fillOrderAsync(
|
||||||
|
signedOrder,
|
||||||
|
emptyFillTakerAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
{
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
},
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrderAsync(
|
return expect(
|
||||||
signedOrder, emptyFillTakerAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
|
zeroEx.exchange.fillOrderAsync(
|
||||||
|
signedOrder,
|
||||||
|
emptyFillTakerAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
{
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
},
|
||||||
|
),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -297,11 +397,19 @@ describe('ExchangeWrapper', () => {
|
|||||||
let orderFillBatch: OrderFillRequest[];
|
let orderFillBatch: OrderFillRequest[];
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
|
signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
|
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
|
||||||
});
|
});
|
||||||
@ -319,13 +427,20 @@ describe('ExchangeWrapper', () => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
it('should throw if a batch is empty', async () => {
|
it('should throw if a batch is empty', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrdersAsync(
|
return expect(
|
||||||
[], shouldThrowOnInsufficientBalanceOrAllowance, takerAddress),
|
zeroEx.exchange.batchFillOrdersAsync(
|
||||||
|
[],
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
});
|
});
|
||||||
it('should successfully fill multiple orders', async () => {
|
it('should successfully fill multiple orders', async () => {
|
||||||
const txHash = await zeroEx.exchange.batchFillOrdersAsync(
|
const txHash = await zeroEx.exchange.batchFillOrdersAsync(
|
||||||
orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress);
|
orderFillBatch,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
|
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
|
||||||
const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
|
const anotherFilledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(anotherOrderHashHex);
|
||||||
@ -348,21 +463,37 @@ describe('ExchangeWrapper', () => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrdersAsync(
|
return expect(
|
||||||
orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress),
|
zeroEx.exchange.batchFillOrdersAsync(
|
||||||
|
orderFillBatch,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrdersAsync(
|
return expect(
|
||||||
orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
|
zeroEx.exchange.batchFillOrdersAsync(
|
||||||
|
orderFillBatch,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
{
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
},
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.batchFillOrdersAsync(
|
return expect(
|
||||||
orderFillBatch, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
|
zeroEx.exchange.batchFillOrdersAsync(
|
||||||
|
orderFillBatch,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
{
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
},
|
||||||
|
),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -375,24 +506,40 @@ describe('ExchangeWrapper', () => {
|
|||||||
const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
|
const fillUpToAmount = fillableAmount.plus(fillableAmount).minus(1);
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
|
signedOrderHashHex = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
|
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
|
||||||
signedOrders = [signedOrder, anotherSignedOrder];
|
signedOrders = [signedOrder, anotherSignedOrder];
|
||||||
});
|
});
|
||||||
describe('successful batch fills', () => {
|
describe('successful batch fills', () => {
|
||||||
it('should throw if a batch is empty', async () => {
|
it('should throw if a batch is empty', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrdersUpToAsync(
|
return expect(
|
||||||
[], fillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress),
|
zeroEx.exchange.fillOrdersUpToAsync(
|
||||||
|
[],
|
||||||
|
fillUpToAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
).to.be.rejectedWith(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
});
|
});
|
||||||
it('should successfully fill up to specified amount', async () => {
|
it('should successfully fill up to specified amount', async () => {
|
||||||
const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
|
const txHash = await zeroEx.exchange.fillOrdersUpToAsync(
|
||||||
signedOrders, fillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
signedOrders,
|
||||||
|
fillUpToAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
|
const filledAmount = await zeroEx.exchange.getFilledTakerAmountAsync(signedOrderHashHex);
|
||||||
@ -405,21 +552,40 @@ describe('ExchangeWrapper', () => {
|
|||||||
describe('order transaction options', () => {
|
describe('order transaction options', () => {
|
||||||
const emptyFillUpToAmount = new BigNumber(0);
|
const emptyFillUpToAmount = new BigNumber(0);
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrdersUpToAsync(
|
return expect(
|
||||||
signedOrders, emptyFillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
zeroEx.exchange.fillOrdersUpToAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
signedOrders,
|
||||||
|
emptyFillUpToAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrdersUpToAsync(
|
return expect(
|
||||||
signedOrders, emptyFillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
|
zeroEx.exchange.fillOrdersUpToAsync(
|
||||||
|
signedOrders,
|
||||||
|
emptyFillUpToAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
{
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
},
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.fillOrdersUpToAsync(
|
return expect(
|
||||||
signedOrders, emptyFillUpToAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress, {
|
zeroEx.exchange.fillOrdersUpToAsync(
|
||||||
|
signedOrders,
|
||||||
|
emptyFillUpToAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
|
{
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
},
|
||||||
|
),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -440,7 +606,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
makerTokenAddress = makerToken.address;
|
makerTokenAddress = makerToken.address;
|
||||||
takerTokenAddress = takerToken.address;
|
takerTokenAddress = takerToken.address;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
|
orderHashHex = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
});
|
});
|
||||||
@ -456,18 +626,23 @@ describe('ExchangeWrapper', () => {
|
|||||||
describe('order transaction options', () => {
|
describe('order transaction options', () => {
|
||||||
const emptyCancelTakerTokenAmount = new BigNumber(0);
|
const emptyCancelTakerTokenAmount = new BigNumber(0);
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
|
return expect(
|
||||||
|
zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
}),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
|
return expect(
|
||||||
|
zeroEx.exchange.cancelOrderAsync(signedOrder, emptyCancelTakerTokenAmount, {
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
}),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -477,7 +652,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
let cancelBatch: OrderCancellationRequest[];
|
let cancelBatch: OrderCancellationRequest[];
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
|
anotherOrderHashHex = ZeroEx.getOrderHashHex(anotherSignedOrder);
|
||||||
cancelBatch = [
|
cancelBatch = [
|
||||||
@ -494,15 +673,21 @@ describe('ExchangeWrapper', () => {
|
|||||||
describe('failed batch cancels', () => {
|
describe('failed batch cancels', () => {
|
||||||
it('should throw when orders have different makers', async () => {
|
it('should throw when orders have different makers', async () => {
|
||||||
const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrderWithDifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, takerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.batchCancelOrdersAsync([
|
return expect(
|
||||||
|
zeroEx.exchange.batchCancelOrdersAsync([
|
||||||
cancelBatch[0],
|
cancelBatch[0],
|
||||||
{
|
{
|
||||||
order: signedOrderWithDifferentMaker,
|
order: signedOrderWithDifferentMaker,
|
||||||
takerTokenCancelAmount: cancelAmount,
|
takerTokenCancelAmount: cancelAmount,
|
||||||
},
|
},
|
||||||
])).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
]),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.MultipleMakersInSingleCancelBatchDisallowed);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('successful batch cancels', () => {
|
describe('successful batch cancels', () => {
|
||||||
@ -531,18 +716,23 @@ describe('ExchangeWrapper', () => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions are not present', async () => {
|
it('should validate when orderTransactionOptions are not present', async () => {
|
||||||
return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch))
|
return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch)).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
ExchangeContractErrs.OrderCancelAmountZero,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should validate when orderTransactionOptions specify to validate', async () => {
|
it('should validate when orderTransactionOptions specify to validate', async () => {
|
||||||
return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
|
return expect(
|
||||||
|
zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
|
||||||
shouldValidate: true,
|
shouldValidate: true,
|
||||||
})).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
}),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
it('should not validate when orderTransactionOptions specify not to validate', async () => {
|
||||||
return expect(zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
|
return expect(
|
||||||
|
zeroEx.exchange.batchCancelOrdersAsync(cancelBatch, {
|
||||||
shouldValidate: false,
|
shouldValidate: false,
|
||||||
})).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
}),
|
||||||
|
).to.not.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -566,7 +756,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
fillableAmount = new BigNumber(5);
|
fillableAmount = new BigNumber(5);
|
||||||
partialFillAmount = new BigNumber(2);
|
partialFillAmount = new BigNumber(2);
|
||||||
signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
|
signedOrder = await fillScenarios.createPartiallyFilledSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, takerAddress, fillableAmount, partialFillAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
partialFillAmount,
|
||||||
);
|
);
|
||||||
orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
});
|
});
|
||||||
@ -590,8 +784,7 @@ describe('ExchangeWrapper', () => {
|
|||||||
return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
|
return expect(zeroEx.exchange.getFilledTakerAmountAsync(invalidOrderHashHex)).to.be.rejected();
|
||||||
});
|
});
|
||||||
it('should return zero if passed a valid but non-existent orderHash', async () => {
|
it('should return zero if passed a valid but non-existent orderHash', async () => {
|
||||||
const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH,
|
const filledValueT = await zeroEx.exchange.getFilledTakerAmountAsync(NON_EXISTENT_ORDER_HASH);
|
||||||
);
|
|
||||||
expect(filledValueT).to.be.bignumber.equal(0);
|
expect(filledValueT).to.be.bignumber.equal(0);
|
||||||
});
|
});
|
||||||
it('should return the filledValueT for a valid and partially filled orderHash', async () => {
|
it('should return the filledValueT for a valid and partially filled orderHash', async () => {
|
||||||
@ -641,7 +834,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
fillableAmount = new BigNumber(5);
|
fillableAmount = new BigNumber(5);
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@ -654,42 +851,35 @@ describe('ExchangeWrapper', () => {
|
|||||||
// Source: https://github.com/mochajs/mocha/issues/2407
|
// 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 LogFill event when an order is filled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
const callback = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
||||||
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
|
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.exchange.subscribe(
|
zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
|
||||||
ExchangeEvents.LogFill, indexFilterValues, callback,
|
|
||||||
);
|
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
|
signedOrder,
|
||||||
|
takerTokenFillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
|
it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
|
const callback = (err: Error, logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => {
|
||||||
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
|
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.exchange.subscribe(
|
zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback);
|
||||||
ExchangeEvents.LogCancel, indexFilterValues, callback,
|
|
||||||
);
|
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
|
it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
|
|
||||||
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
};
|
};
|
||||||
zeroEx.exchange.subscribe(
|
zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled);
|
||||||
ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled,
|
|
||||||
);
|
|
||||||
|
|
||||||
const newProvider = web3Factory.getRpcProvider();
|
const newProvider = web3Factory.getRpcProvider();
|
||||||
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
||||||
@ -698,11 +888,11 @@ describe('ExchangeWrapper', () => {
|
|||||||
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
|
expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.exchange.subscribe(
|
zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback);
|
||||||
ExchangeEvents.LogFill, indexFilterValues, callback,
|
|
||||||
);
|
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
|
signedOrder,
|
||||||
|
takerTokenFillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
@ -713,11 +903,15 @@ describe('ExchangeWrapper', () => {
|
|||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
};
|
};
|
||||||
const subscriptionToken = zeroEx.exchange.subscribe(
|
const subscriptionToken = zeroEx.exchange.subscribe(
|
||||||
ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled,
|
ExchangeEvents.LogFill,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
);
|
);
|
||||||
zeroEx.exchange.unsubscribe(subscriptionToken);
|
zeroEx.exchange.unsubscribe(subscriptionToken);
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, takerTokenFillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance,
|
signedOrder,
|
||||||
|
takerTokenFillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
takerAddress,
|
takerAddress,
|
||||||
);
|
);
|
||||||
done();
|
done();
|
||||||
@ -736,13 +930,18 @@ describe('ExchangeWrapper', () => {
|
|||||||
makerTokenAddress = makerToken.address;
|
makerTokenAddress = makerToken.address;
|
||||||
takerTokenAddress = takerToken.address;
|
takerTokenAddress = takerToken.address;
|
||||||
});
|
});
|
||||||
it('get\'s the same hash as the local function', async () => {
|
it("get's the same hash as the local function", async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
const orderHashFromContract = await (zeroEx.exchange as any)
|
const orderHashFromContract = await (zeroEx.exchange as any)._getOrderHashHexUsingContractCallAsync(
|
||||||
._getOrderHashHexUsingContractCallAsync(signedOrder);
|
signedOrder,
|
||||||
|
);
|
||||||
expect(orderHash).to.equal(orderHashFromContract);
|
expect(orderHash).to.equal(orderHashFromContract);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -773,10 +972,17 @@ describe('ExchangeWrapper', () => {
|
|||||||
});
|
});
|
||||||
it('should get logs with decoded args emitted by LogFill', async () => {
|
it('should get logs with decoded args emitted by LogFill', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
txHash = await zeroEx.exchange.fillOrderAsync(
|
txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
const eventName = ExchangeEvents.LogFill;
|
const eventName = ExchangeEvents.LogFill;
|
||||||
@ -787,10 +993,17 @@ describe('ExchangeWrapper', () => {
|
|||||||
});
|
});
|
||||||
it('should only get the logs with the correct event name', async () => {
|
it('should only get the logs with the correct event name', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
txHash = await zeroEx.exchange.fillOrderAsync(
|
txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
const differentEventName = ExchangeEvents.LogCancel;
|
const differentEventName = ExchangeEvents.LogCancel;
|
||||||
@ -800,19 +1013,33 @@ describe('ExchangeWrapper', () => {
|
|||||||
});
|
});
|
||||||
it('should only get the logs with the correct indexed fields', async () => {
|
it('should only get the logs with the correct indexed fields', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
txHash = await zeroEx.exchange.fillOrderAsync(
|
txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
|
|
||||||
const differentMakerAddress = userAddresses[2];
|
const differentMakerAddress = userAddresses[2];
|
||||||
const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, differentMakerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
differentMakerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
txHash = await zeroEx.exchange.fillOrderAsync(
|
txHash = await zeroEx.exchange.fillOrderAsync(
|
||||||
anotherSignedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
anotherSignedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
await zeroEx.awaitTransactionMinedAsync(txHash);
|
await zeroEx.awaitTransactionMinedAsync(txHash);
|
||||||
|
|
||||||
@ -821,7 +1048,9 @@ describe('ExchangeWrapper', () => {
|
|||||||
maker: differentMakerAddress,
|
maker: differentMakerAddress,
|
||||||
};
|
};
|
||||||
const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
|
const logs = await zeroEx.exchange.getLogsAsync<LogFillContractEventArgs>(
|
||||||
eventName, blockRange, indexFilterValues,
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
|
@ -78,7 +78,11 @@ describe('ExpirationWatcher', () => {
|
|||||||
const orderLifetimeSec = 60;
|
const orderLifetimeSec = 60;
|
||||||
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
expirationUnixTimestampSec,
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
@ -92,12 +96,16 @@ describe('ExpirationWatcher', () => {
|
|||||||
timer.tick(orderLifetimeSec * 1000);
|
timer.tick(orderLifetimeSec * 1000);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('doesn\'t emit events before order expires', (done: DoneCallback) => {
|
it("doesn't emit events before order expires", (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const orderLifetimeSec = 60;
|
const orderLifetimeSec = 60;
|
||||||
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
expirationUnixTimestampSec,
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
@ -118,11 +126,19 @@ describe('ExpirationWatcher', () => {
|
|||||||
const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
|
const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
|
||||||
const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
|
const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
|
||||||
const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
order1ExpirationUnixTimestampSec,
|
order1ExpirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
order2ExpirationUnixTimestampSec,
|
order2ExpirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
|
const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
|
||||||
|
@ -71,7 +71,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
describe('#removeOrder', async () => {
|
describe('#removeOrder', async () => {
|
||||||
it('should successfully remove existing order', async () => {
|
it('should successfully remove existing order', async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@ -89,10 +93,18 @@ describe('OrderStateWatcher', () => {
|
|||||||
});
|
});
|
||||||
it('should no-op when removing a non-existing order', async () => {
|
it('should no-op when removing a non-existing order', async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
const nonExistentOrderHash = `0x${orderHash.substr(2).split('').reverse().join('')}`;
|
const nonExistentOrderHash = `0x${orderHash
|
||||||
|
.substr(2)
|
||||||
|
.split('')
|
||||||
|
.reverse()
|
||||||
|
.join('')}`;
|
||||||
zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
|
zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -102,8 +114,7 @@ describe('OrderStateWatcher', () => {
|
|||||||
});
|
});
|
||||||
it('should fail when trying to subscribe twice', async () => {
|
it('should fail when trying to subscribe twice', async () => {
|
||||||
zeroEx.orderStateWatcher.subscribe(_.noop);
|
zeroEx.orderStateWatcher.subscribe(_.noop);
|
||||||
expect(() => zeroEx.orderStateWatcher.subscribe(_.noop))
|
expect(() => zeroEx.orderStateWatcher.subscribe(_.noop)).to.throw(ZeroExError.SubscriptionAlreadyPresent);
|
||||||
.to.throw(ZeroExError.SubscriptionAlreadyPresent);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('tests with cleanup', async () => {
|
describe('tests with cleanup', async () => {
|
||||||
@ -115,7 +126,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@ -133,7 +148,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
|
it('should not emit an orderState event when irrelevant Transfer event received', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
||||||
@ -152,7 +171,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when maker moves balance backing watched order', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@ -172,7 +195,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when watched order fully filled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@ -188,14 +215,21 @@ describe('OrderStateWatcher', () => {
|
|||||||
|
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillableAmount, shouldThrowOnInsufficientBalanceOrAllowance, taker,
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
taker,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
|
it('should emit orderStateValid when watched order partially filled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
||||||
@ -211,16 +245,21 @@ describe('OrderStateWatcher', () => {
|
|||||||
const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
|
const remainingMakerBalance = makerBalance.sub(fillAmountInBaseUnits);
|
||||||
const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
|
const remainingFillable = fillableAmount.minus(fillAmountInBaseUnits);
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingFillable);
|
remainingFillable,
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingFillable);
|
remainingFillable,
|
||||||
|
);
|
||||||
expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
|
expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker,
|
signedOrder,
|
||||||
|
fillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
taker,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -229,8 +268,15 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
|
||||||
const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
|
const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
taker);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
taker,
|
||||||
|
);
|
||||||
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@ -245,7 +291,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
|
const takerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(10), decimals);
|
||||||
const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
|
const makerFillableAmount = ZeroEx.toBaseUnitAmount(new BigNumber(20), decimals);
|
||||||
signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, makerFillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
makerFillableAmount,
|
||||||
takerFillableAmount,
|
takerFillableAmount,
|
||||||
);
|
);
|
||||||
const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
@ -257,22 +307,31 @@ describe('OrderStateWatcher', () => {
|
|||||||
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
expect(validOrderState.orderHash).to.be.equal(orderHash);
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals));
|
ZeroEx.toBaseUnitAmount(new BigNumber(16), decimals),
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals));
|
ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals),
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
await zeroEx.exchange.fillOrderAsync(
|
await zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, fillAmountInBaseUnits, shouldThrowOnInsufficientBalanceOrAllowance, taker,
|
signedOrder,
|
||||||
|
fillAmountInBaseUnits,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
taker,
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
|
it('should equal approved amount when approved amount is lowest', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
||||||
@ -282,9 +341,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
changedMakerApprovalAmount);
|
changedMakerApprovalAmount,
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
changedMakerApprovalAmount);
|
changedMakerApprovalAmount,
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
@ -294,7 +355,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
|
it('should equal balance amount when balance amount is lowest', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
|
||||||
@ -308,14 +373,15 @@ describe('OrderStateWatcher', () => {
|
|||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingAmount);
|
remainingAmount,
|
||||||
|
);
|
||||||
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingAmount);
|
remainingAmount,
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
|
||||||
makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount);
|
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
|
it('should equal remaining amount when partially cancelled and order has fees', (done: DoneCallback) => {
|
||||||
@ -324,8 +390,15 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
||||||
const feeRecipient = taker;
|
const feeRecipient = taker;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker,
|
makerToken.address,
|
||||||
taker, fillableAmount, feeRecipient);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
|
);
|
||||||
|
|
||||||
const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
|
const remainingTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(4), decimals);
|
||||||
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
|
const transferTokenAmount = makerFee.sub(remainingTokenAmount);
|
||||||
@ -336,7 +409,8 @@ describe('OrderStateWatcher', () => {
|
|||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingTokenAmount);
|
remainingTokenAmount,
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
@ -349,8 +423,15 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals);
|
||||||
const feeRecipient = taker;
|
const feeRecipient = taker;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker,
|
makerToken.address,
|
||||||
taker, fillableAmount, feeRecipient);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
|
);
|
||||||
|
|
||||||
const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
const remainingFeeAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
|
||||||
|
|
||||||
@ -362,13 +443,18 @@ describe('OrderStateWatcher', () => {
|
|||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
remainingFeeAmount);
|
remainingFeeAmount,
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
|
await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount);
|
||||||
await zeroEx.token.transferAsync(
|
await zeroEx.token.transferAsync(
|
||||||
makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferTokenAmount);
|
makerToken.address,
|
||||||
|
maker,
|
||||||
|
ZeroEx.NULL_ADDRESS,
|
||||||
|
transferTokenAmount,
|
||||||
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
|
it('should calculate full amount when all available and non-divisible', (done: DoneCallback) => {
|
||||||
@ -377,8 +463,15 @@ describe('OrderStateWatcher', () => {
|
|||||||
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
const feeRecipient = taker;
|
const feeRecipient = taker;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerToken.address, takerToken.address, makerFee, takerFee, maker,
|
makerToken.address,
|
||||||
taker, fillableAmount, feeRecipient);
|
takerToken.address,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
|
);
|
||||||
|
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
|
|
||||||
@ -386,19 +479,27 @@ describe('OrderStateWatcher', () => {
|
|||||||
const validOrderState = orderState as OrderStateValid;
|
const validOrderState = orderState as OrderStateValid;
|
||||||
const orderRelevantState = validOrderState.orderRelevantState;
|
const orderRelevantState = validOrderState.orderRelevantState;
|
||||||
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal(
|
||||||
fillableAmount);
|
fillableAmount,
|
||||||
|
);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(
|
await zeroEx.token.setProxyAllowanceAsync(
|
||||||
makerToken.address, maker, ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals));
|
makerToken.address,
|
||||||
|
maker,
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(100), decimals),
|
||||||
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
|
it('should emit orderStateInvalid when watched order cancelled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@ -419,7 +520,11 @@ describe('OrderStateWatcher', () => {
|
|||||||
(async () => {
|
(async () => {
|
||||||
const remainingFillableAmountInBaseUnits = new BigNumber(100);
|
const remainingFillableAmountInBaseUnits = new BigNumber(100);
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
|
||||||
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
zeroEx.orderStateWatcher.addOrder(signedOrder);
|
||||||
@ -433,14 +538,19 @@ describe('OrderStateWatcher', () => {
|
|||||||
});
|
});
|
||||||
zeroEx.orderStateWatcher.subscribe(callback);
|
zeroEx.orderStateWatcher.subscribe(callback);
|
||||||
await zeroEx.exchange.cancelOrderAsync(
|
await zeroEx.exchange.cancelOrderAsync(
|
||||||
signedOrder, fillableAmount.minus(remainingFillableAmountInBaseUnits),
|
signedOrder,
|
||||||
|
fillableAmount.minus(remainingFillableAmountInBaseUnits),
|
||||||
);
|
);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
|
it('should emit orderStateValid when watched order partially cancelled', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerToken.address, takerToken.address, maker, taker, fillableAmount,
|
makerToken.address,
|
||||||
|
takerToken.address,
|
||||||
|
maker,
|
||||||
|
taker,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const cancelAmountInBaseUnits = new BigNumber(2);
|
const cancelAmountInBaseUnits = new BigNumber(2);
|
||||||
|
@ -62,108 +62,152 @@ describe('OrderValidation', () => {
|
|||||||
describe('validateOrderFillableOrThrowAsync', () => {
|
describe('validateOrderFillableOrThrowAsync', () => {
|
||||||
it('should succeed if the order is fillable', async () => {
|
it('should succeed if the order is fillable', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
);
|
takerTokenAddress,
|
||||||
await zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
makerAddress,
|
||||||
signedOrder,
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
|
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||||
});
|
});
|
||||||
it('should succeed if the order is asymmetric and fillable', async () => {
|
it('should succeed if the order is asymmetric and fillable', async () => {
|
||||||
const makerFillableAmount = fillableAmount;
|
const makerFillableAmount = fillableAmount;
|
||||||
const takerFillableAmount = fillableAmount.minus(4);
|
const takerFillableAmount = fillableAmount.minus(4);
|
||||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
makerFillableAmount, takerFillableAmount,
|
takerTokenAddress,
|
||||||
);
|
makerAddress,
|
||||||
await zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
takerAddress,
|
||||||
signedOrder,
|
makerFillableAmount,
|
||||||
|
takerFillableAmount,
|
||||||
);
|
);
|
||||||
|
await zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder);
|
||||||
});
|
});
|
||||||
it('should throw when the order is fully filled or cancelled', async () => {
|
it('should throw when the order is fully filled or cancelled', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
|
||||||
signedOrder,
|
ExchangeContractErrs.OrderRemainingFillAmountZero,
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when order is expired', async () => {
|
it('should throw when order is expired', async () => {
|
||||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, expirationInPast,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
expirationInPast,
|
||||||
|
);
|
||||||
|
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(signedOrder)).to.be.rejectedWith(
|
||||||
|
ExchangeContractErrs.OrderFillExpired,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.validateOrderFillableOrThrowAsync(
|
|
||||||
signedOrder,
|
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('validateFillOrderAndThrowIfInvalidAsync', () => {
|
describe('validateFillOrderAndThrowIfInvalidAsync', () => {
|
||||||
it('should throw when the fill amount is zero', async () => {
|
it('should throw when the fill amount is zero', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const zeroFillAmount = new BigNumber(0);
|
const zeroFillAmount = new BigNumber(0);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, zeroFillAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, zeroFillAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should throw when the signature is invalid', async () => {
|
it('should throw when the signature is invalid', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
// 27 <--> 28
|
// 27 <--> 28
|
||||||
signedOrder.ecSignature.v = (28 - signedOrder.ecSignature.v) + 27;
|
signedOrder.ecSignature.v = 28 - signedOrder.ecSignature.v + 27;
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillableAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ZeroExError.InvalidSignature);
|
).to.be.rejectedWith(ZeroExError.InvalidSignature);
|
||||||
});
|
});
|
||||||
it('should throw when the order is fully filled or cancelled', async () => {
|
it('should throw when the order is fully filled or cancelled', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillableAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillableAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderRemainingFillAmountZero);
|
||||||
});
|
});
|
||||||
it('should throw when sender is not a taker', async () => {
|
it('should throw when sender is not a taker', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const nonTakerAddress = userAddresses[6];
|
const nonTakerAddress = userAddresses[6];
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillTakerAmount, nonTakerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, nonTakerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
).to.be.rejectedWith(ExchangeContractErrs.TransactionSenderIsNotFillOrderTaker);
|
||||||
});
|
});
|
||||||
it('should throw when order is expired', async () => {
|
it('should throw when order is expired', async () => {
|
||||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, expirationInPast,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
expirationInPast,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillTakerAmount, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(signedOrder, fillTakerAmount, takerAddress),
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillExpired);
|
||||||
});
|
});
|
||||||
it('should throw when there a rounding error would have occurred', async () => {
|
it('should throw when there a rounding error would have occurred', async () => {
|
||||||
const makerAmount = new BigNumber(3);
|
const makerAmount = new BigNumber(3);
|
||||||
const takerAmount = new BigNumber(5);
|
const takerAmount = new BigNumber(5);
|
||||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
makerAmount, takerAmount,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerAmount,
|
||||||
|
takerAmount,
|
||||||
);
|
);
|
||||||
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
|
const fillTakerAmountThatCausesRoundingError = new BigNumber(3);
|
||||||
return expect(zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, fillTakerAmountThatCausesRoundingError, takerAddress,
|
zeroEx.exchange.validateFillOrderThrowIfInvalidAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
|
signedOrder,
|
||||||
|
fillTakerAmountThatCausesRoundingError,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderFillRoundingError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
|
describe('#validateFillOrKillOrderAndThrowIfInvalidAsync', () => {
|
||||||
it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
|
it('should throw if remaining fillAmount is less then the desired fillAmount', async () => {
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const tooLargeFillAmount = new BigNumber(7);
|
const tooLargeFillAmount = new BigNumber(7);
|
||||||
const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
|
const fillAmountDifference = tooLargeFillAmount.minus(fillableAmount);
|
||||||
@ -172,9 +216,13 @@ describe('OrderValidation', () => {
|
|||||||
await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
|
await zeroEx.token.transferAsync(makerTokenAddress, coinbase, makerAddress, fillAmountDifference);
|
||||||
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
|
await zeroEx.token.setProxyAllowanceAsync(makerTokenAddress, makerAddress, tooLargeFillAmount);
|
||||||
|
|
||||||
return expect(zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
|
return expect(
|
||||||
signedOrder, tooLargeFillAmount, takerAddress,
|
zeroEx.exchange.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
)).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
signedOrder,
|
||||||
|
tooLargeFillAmount,
|
||||||
|
takerAddress,
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.InsufficientRemainingFillAmount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
|
describe('validateCancelOrderAndThrowIfInvalidAsync', () => {
|
||||||
@ -186,27 +234,38 @@ describe('OrderValidation', () => {
|
|||||||
makerTokenAddress = makerToken.address;
|
makerTokenAddress = makerToken.address;
|
||||||
takerTokenAddress = takerToken.address;
|
takerTokenAddress = takerToken.address;
|
||||||
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
signedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw when cancel amount is zero', async () => {
|
it('should throw when cancel amount is zero', async () => {
|
||||||
const zeroCancelAmount = new BigNumber(0);
|
const zeroCancelAmount = new BigNumber(0);
|
||||||
return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, zeroCancelAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelAmountZero);
|
||||||
});
|
});
|
||||||
it('should throw when order is expired', async () => {
|
it('should throw when order is expired', async () => {
|
||||||
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
|
||||||
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, expirationInPast,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
expirationInPast,
|
||||||
);
|
);
|
||||||
return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
|
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(expiredSignedOrder, cancelAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderCancelExpired);
|
||||||
});
|
});
|
||||||
it('should throw when order is already cancelled or filled', async () => {
|
it('should throw when order is already cancelled or filled', async () => {
|
||||||
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
|
||||||
return expect(zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount))
|
return expect(
|
||||||
.to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
|
zeroEx.exchange.validateCancelOrderThrowIfInvalidAsync(signedOrder, fillableAmount),
|
||||||
|
).to.be.rejectedWith(ExchangeContractErrs.OrderAlreadyCancelledOrFilled);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
|
describe('#validateFillOrderBalancesAllowancesThrowIfInvalidAsync', () => {
|
||||||
@ -224,35 +283,69 @@ describe('OrderValidation', () => {
|
|||||||
const makerFee = new BigNumber(2);
|
const makerFee = new BigNumber(2);
|
||||||
const takerFee = new BigNumber(2);
|
const takerFee = new BigNumber(2);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
makerTokenAddress,
|
||||||
makerAddress, takerAddress, fillableAmount, feeRecipient,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
);
|
);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(0).calledWith(
|
transferFromAsync
|
||||||
makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
|
.getCall(0)
|
||||||
TradeSide.Maker, TransferType.Trade,
|
.calledWith(
|
||||||
|
makerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(1).calledWith(
|
transferFromAsync
|
||||||
takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
|
.getCall(1)
|
||||||
TradeSide.Taker, TransferType.Trade,
|
.calledWith(
|
||||||
|
takerTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(2).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
|
.getCall(2)
|
||||||
TradeSide.Maker, TransferType.Fee,
|
.calledWith(
|
||||||
|
zrxTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(makerFee),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Fee,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(3).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
|
.getCall(3)
|
||||||
TradeSide.Taker, TransferType.Fee,
|
.calledWith(
|
||||||
|
zrxTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(takerFee),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Fee,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
});
|
});
|
||||||
@ -260,35 +353,69 @@ describe('OrderValidation', () => {
|
|||||||
const makerFee = new BigNumber(2);
|
const makerFee = new BigNumber(2);
|
||||||
const takerFee = new BigNumber(2);
|
const takerFee = new BigNumber(2);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee,
|
makerTokenAddress,
|
||||||
makerAddress, ZeroEx.NULL_ADDRESS, fillableAmount, feeRecipient,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
ZeroEx.NULL_ADDRESS,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecipient,
|
||||||
);
|
);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, fillableAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
fillableAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(0).calledWith(
|
transferFromAsync
|
||||||
makerTokenAddress, makerAddress, takerAddress, bigNumberMatch(fillableAmount),
|
.getCall(0)
|
||||||
TradeSide.Maker, TransferType.Trade,
|
.calledWith(
|
||||||
|
makerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Trade,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(1).calledWith(
|
transferFromAsync
|
||||||
takerTokenAddress, takerAddress, makerAddress, bigNumberMatch(fillableAmount),
|
.getCall(1)
|
||||||
TradeSide.Taker, TransferType.Trade,
|
.calledWith(
|
||||||
|
takerTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerAddress,
|
||||||
|
bigNumberMatch(fillableAmount),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Trade,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(2).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, makerAddress, feeRecipient, bigNumberMatch(makerFee),
|
.getCall(2)
|
||||||
TradeSide.Maker, TransferType.Fee,
|
.calledWith(
|
||||||
|
zrxTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(makerFee),
|
||||||
|
TradeSide.Maker,
|
||||||
|
TransferType.Fee,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
expect(
|
expect(
|
||||||
transferFromAsync.getCall(3).calledWith(
|
transferFromAsync
|
||||||
zrxTokenAddress, takerAddress, feeRecipient, bigNumberMatch(takerFee),
|
.getCall(3)
|
||||||
TradeSide.Taker, TransferType.Fee,
|
.calledWith(
|
||||||
|
zrxTokenAddress,
|
||||||
|
takerAddress,
|
||||||
|
feeRecipient,
|
||||||
|
bigNumberMatch(takerFee),
|
||||||
|
TradeSide.Taker,
|
||||||
|
TransferType.Fee,
|
||||||
),
|
),
|
||||||
).to.be.true();
|
).to.be.true();
|
||||||
});
|
});
|
||||||
@ -296,10 +423,19 @@ describe('OrderValidation', () => {
|
|||||||
const makerTokenAmount = new BigNumber(3);
|
const makerTokenAmount = new BigNumber(3);
|
||||||
const takerTokenAmount = new BigNumber(1);
|
const takerTokenAmount = new BigNumber(1);
|
||||||
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await fillScenarios.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, makerTokenAmount, takerTokenAmount,
|
makerTokenAddress,
|
||||||
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerTokenAmount,
|
||||||
|
takerTokenAmount,
|
||||||
);
|
);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, takerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
takerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
expect(transferFromAsync.callCount).to.be.equal(4);
|
expect(transferFromAsync.callCount).to.be.equal(4);
|
||||||
const makerFillAmount = transferFromAsync.getCall(0).args[3];
|
const makerFillAmount = transferFromAsync.getCall(0).args[3];
|
||||||
@ -309,12 +445,22 @@ describe('OrderValidation', () => {
|
|||||||
const makerFee = new BigNumber(2);
|
const makerFee = new BigNumber(2);
|
||||||
const takerFee = new BigNumber(4);
|
const takerFee = new BigNumber(4);
|
||||||
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
const signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, ZeroEx.NULL_ADDRESS,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
ZeroEx.NULL_ADDRESS,
|
||||||
);
|
);
|
||||||
const fillTakerTokenAmount = fillableAmount.div(2).round(0);
|
const fillTakerTokenAmount = fillableAmount.div(2).round(0);
|
||||||
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
await OrderValidationUtils.validateFillOrderBalancesAllowancesThrowIfInvalidAsync(
|
||||||
exchangeTransferSimulator, signedOrder, fillTakerTokenAmount, takerAddress, zrxTokenAddress,
|
exchangeTransferSimulator,
|
||||||
|
signedOrder,
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
takerAddress,
|
||||||
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
const makerPartialFee = makerFee.div(2);
|
const makerPartialFee = makerFee.div(2);
|
||||||
const takerPartialFee = takerFee.div(2);
|
const takerPartialFee = takerFee.div(2);
|
||||||
|
@ -28,15 +28,19 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
const zeroAddress = '0x0';
|
const zeroAddress = '0x0';
|
||||||
const signature: ECSignature = { v: 27, r: '', s: '' };
|
const signature: ECSignature = { v: 27, r: '', s: '' };
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
[makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals),
|
||||||
|
];
|
||||||
[transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
|
[transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount] = [
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(50), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(5), decimals),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
function buildSignedOrder(): SignedOrder {
|
function buildSignedOrder(): SignedOrder {
|
||||||
return { ecSignature: signature,
|
return {
|
||||||
|
ecSignature: signature,
|
||||||
exchangeContractAddress: zeroAddress,
|
exchangeContractAddress: zeroAddress,
|
||||||
feeRecipient: zeroAddress,
|
feeRecipient: zeroAddress,
|
||||||
maker: zeroAddress,
|
maker: zeroAddress,
|
||||||
@ -48,7 +52,8 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
makerTokenAddress: makerToken,
|
makerTokenAddress: makerToken,
|
||||||
takerTokenAddress: takerToken,
|
takerTokenAddress: takerToken,
|
||||||
salt: zero,
|
salt: zero,
|
||||||
expirationUnixTimestampSec: zero };
|
expirationUnixTimestampSec: zero,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
describe('Maker token is NOT ZRX', () => {
|
describe('Maker token is NOT ZRX', () => {
|
||||||
before(async () => {
|
before(async () => {
|
||||||
@ -57,23 +62,38 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
it('calculates the correct amount when unfilled and funds available', () => {
|
it('calculates the correct amount when unfilled and funds available', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when partially filled and funds available', () => {
|
it('calculates the correct amount when partially filled and funds available', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
transferrableMakerFeeTokenAmount = zero;
|
transferrableMakerFeeTokenAmount = zero;
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
||||||
@ -81,41 +101,58 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const partiallyFilledAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount.minus(partiallyFilledAmount);
|
||||||
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
|
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(partiallyFilledAmount);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
||||||
});
|
});
|
||||||
describe('Order to Fee Ratio is < 1', () => {
|
describe('Order to Fee Ratio is < 1', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
[makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(6), decimals),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when funds unavailable', () => {
|
it('calculates the correct amount when funds unavailable', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount,
|
signedOrder,
|
||||||
remainingMakerTokenAmount);
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(transferrableMakerTokenAmount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('Ratio is not evenly divisble', () => {
|
describe('Ratio is not evenly divisble', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
[makerAmount, takerAmount, makerFeeAmount] = [ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
[makerAmount, takerAmount, makerFeeAmount] = [
|
||||||
|
ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
|
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
|
||||||
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals)];
|
ZeroEx.toBaseUnitAmount(new BigNumber(7), decimals),
|
||||||
|
];
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when funds unavailable', () => {
|
it('calculates the correct amount when funds unavailable', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
const transferredAmount = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
|
||||||
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
transferrableMakerTokenAmount = remainingMakerTokenAmount.minus(transferredAmount);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount,
|
signedOrder,
|
||||||
remainingMakerTokenAmount);
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
||||||
expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
|
expect(calculatedFillableAmount.lessThanOrEqualTo(transferrableMakerTokenAmount)).to.be.true();
|
||||||
expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
|
expect(calculatedFillableAmount).to.be.bignumber.greaterThan(new BigNumber(0));
|
||||||
@ -134,15 +171,25 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
|
transferrableMakerTokenAmount = makerAmount.plus(makerFeeAmount);
|
||||||
transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
|
transferrableMakerFeeTokenAmount = transferrableMakerTokenAmount;
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when partially filled and funds available', () => {
|
it('calculates the correct amount when partially filled and funds available', () => {
|
||||||
signedOrder = buildSignedOrder();
|
signedOrder = buildSignedOrder();
|
||||||
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
remainingMakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(remainingMakerTokenAmount);
|
||||||
});
|
});
|
||||||
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
it('calculates the amount to be 0 when all fee funds are transferred', () => {
|
||||||
@ -150,8 +197,13 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
transferrableMakerTokenAmount = zero;
|
transferrableMakerTokenAmount = zero;
|
||||||
transferrableMakerFeeTokenAmount = zero;
|
transferrableMakerFeeTokenAmount = zero;
|
||||||
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
remainingMakerTokenAmount = signedOrder.makerTokenAmount;
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
expect(calculator.computeRemainingMakerFillable()).to.be.bignumber.equal(zero);
|
||||||
});
|
});
|
||||||
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
it('calculates the correct amount when balance is less than remaining fillable', () => {
|
||||||
@ -163,8 +215,13 @@ describe('RemainingFillableCalculator', () => {
|
|||||||
|
|
||||||
const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
|
const orderToFeeRatio = signedOrder.makerTokenAmount.dividedToIntegerBy(signedOrder.makerFee);
|
||||||
const expectedFillableAmount = new BigNumber(450980);
|
const expectedFillableAmount = new BigNumber(450980);
|
||||||
calculator = new RemainingFillableCalculator(signedOrder, isMakerTokenZRX,
|
calculator = new RemainingFillableCalculator(
|
||||||
transferrableMakerTokenAmount, transferrableMakerFeeTokenAmount, remainingMakerTokenAmount);
|
signedOrder,
|
||||||
|
isMakerTokenZRX,
|
||||||
|
transferrableMakerTokenAmount,
|
||||||
|
transferrableMakerFeeTokenAmount,
|
||||||
|
remainingMakerTokenAmount,
|
||||||
|
);
|
||||||
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
const calculatedFillableAmount = calculator.computeRemainingMakerFillable();
|
||||||
const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
|
const numberOfFillsInRatio = calculatedFillableAmount.dividedToIntegerBy(orderToFeeRatio);
|
||||||
const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
|
const calculatedFillableAmountPlusFees = calculatedFillableAmount.plus(numberOfFillsInRatio);
|
||||||
|
@ -6,13 +6,7 @@ import 'mocha';
|
|||||||
import * as Sinon from 'sinon';
|
import * as Sinon from 'sinon';
|
||||||
import * as Web3 from 'web3';
|
import * as Web3 from 'web3';
|
||||||
|
|
||||||
import {
|
import { ApprovalContractEventArgs, DecodedLogEvent, Token, TokenEvents, ZeroEx } from '../src';
|
||||||
ApprovalContractEventArgs,
|
|
||||||
DecodedLogEvent,
|
|
||||||
Token,
|
|
||||||
TokenEvents,
|
|
||||||
ZeroEx,
|
|
||||||
} from '../src';
|
|
||||||
import { DoneCallback } from '../src/types';
|
import { DoneCallback } from '../src/types';
|
||||||
|
|
||||||
import { chaiSetup } from './utils/chai_setup';
|
import { chaiSetup } from './utils/chai_setup';
|
||||||
@ -72,12 +66,8 @@ describe('SubscriptionTest', () => {
|
|||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
stubs = [
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
.throws(new Error(errMsg)),
|
|
||||||
];
|
|
||||||
zeroEx.token.subscribe(
|
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -91,24 +81,16 @@ describe('SubscriptionTest', () => {
|
|||||||
done();
|
done();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
stubs = [
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync')
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
.throws(new Error(errMsg)),
|
|
||||||
];
|
|
||||||
zeroEx.token.subscribe(
|
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
|
||||||
(async () => {
|
(async () => {
|
||||||
const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop;
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))];
|
||||||
stubs = [
|
|
||||||
Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync')
|
|
||||||
.throws(new Error('JSON RPC error')),
|
|
||||||
];
|
|
||||||
zeroEx.token.unsubscribeAll();
|
zeroEx.token.unsubscribeAll();
|
||||||
done();
|
done();
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
|
@ -74,17 +74,17 @@ describe('TokenWrapper', () => {
|
|||||||
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
|
it('should fail to transfer tokens if fromAddress has an insufficient balance', async () => {
|
||||||
const fromAddress = addressWithoutFunds;
|
const fromAddress = addressWithoutFunds;
|
||||||
const toAddress = coinbase;
|
const toAddress = coinbase;
|
||||||
return expect(zeroEx.token.transferAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, transferAmount,
|
zeroEx.token.transferAsync(token.address, fromAddress, toAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
});
|
});
|
||||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
const toAddress = coinbase;
|
const toAddress = coinbase;
|
||||||
return expect(zeroEx.token.transferAsync(
|
return expect(
|
||||||
nonExistentTokenAddress, fromAddress, toAddress, transferAmount,
|
zeroEx.token.transferAsync(nonExistentTokenAddress, fromAddress, toAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#transferFromAsync', () => {
|
describe('#transferFromAsync', () => {
|
||||||
@ -103,24 +103,22 @@ describe('TokenWrapper', () => {
|
|||||||
const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
|
const fromAddressBalance = await zeroEx.token.getBalanceAsync(token.address, fromAddress);
|
||||||
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
|
expect(fromAddressBalance).to.be.bignumber.greaterThan(transferAmount);
|
||||||
|
|
||||||
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress,
|
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress, toAddress);
|
||||||
toAddress);
|
|
||||||
expect(fromAddressAllowance).to.be.bignumber.equal(0);
|
expect(fromAddressAllowance).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, senderAddress, transferAmount,
|
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
||||||
});
|
});
|
||||||
it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress',
|
it('[regression] should fail to transfer tokens if set allowance for toAddress instead of senderAddress', async () => {
|
||||||
async () => {
|
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
const transferAmount = new BigNumber(42);
|
const transferAmount = new BigNumber(42);
|
||||||
|
|
||||||
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
|
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, toAddress, transferAmount);
|
||||||
|
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, senderAddress, transferAmount,
|
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientAllowanceForTransfer);
|
||||||
});
|
});
|
||||||
it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
|
it('should fail to transfer tokens if fromAddress has insufficient balance', async () => {
|
||||||
const fromAddress = addressWithoutFunds;
|
const fromAddress = addressWithoutFunds;
|
||||||
@ -130,13 +128,16 @@ describe('TokenWrapper', () => {
|
|||||||
expect(fromAddressBalance).to.be.bignumber.equal(0);
|
expect(fromAddressBalance).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
||||||
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(token.address, fromAddress,
|
const fromAddressAllowance = await zeroEx.token.getAllowanceAsync(
|
||||||
senderAddress);
|
token.address,
|
||||||
|
fromAddress,
|
||||||
|
senderAddress,
|
||||||
|
);
|
||||||
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
|
expect(fromAddressAllowance).to.be.bignumber.equal(transferAmount);
|
||||||
|
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
token.address, fromAddress, toAddress, senderAddress, transferAmount,
|
zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount),
|
||||||
)).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
).to.be.rejectedWith(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
});
|
});
|
||||||
it('should successfully transfer tokens', async () => {
|
it('should successfully transfer tokens', async () => {
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
@ -147,17 +148,22 @@ describe('TokenWrapper', () => {
|
|||||||
const transferAmount = new BigNumber(42);
|
const transferAmount = new BigNumber(42);
|
||||||
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
await zeroEx.token.setAllowanceAsync(token.address, fromAddress, senderAddress, transferAmount);
|
||||||
|
|
||||||
await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress,
|
await zeroEx.token.transferFromAsync(token.address, fromAddress, toAddress, senderAddress, transferAmount);
|
||||||
transferAmount);
|
|
||||||
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
|
const postBalance = await zeroEx.token.getBalanceAsync(token.address, toAddress);
|
||||||
return expect(postBalance).to.be.bignumber.equal(transferAmount);
|
return expect(postBalance).to.be.bignumber.equal(transferAmount);
|
||||||
});
|
});
|
||||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||||
const fromAddress = coinbase;
|
const fromAddress = coinbase;
|
||||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||||
return expect(zeroEx.token.transferFromAsync(
|
return expect(
|
||||||
nonExistentTokenAddress, fromAddress, toAddress, senderAddress, new BigNumber(42),
|
zeroEx.token.transferFromAsync(
|
||||||
)).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
nonExistentTokenAddress,
|
||||||
|
fromAddress,
|
||||||
|
toAddress,
|
||||||
|
senderAddress,
|
||||||
|
new BigNumber(42),
|
||||||
|
),
|
||||||
|
).to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#getBalanceAsync', () => {
|
describe('#getBalanceAsync', () => {
|
||||||
@ -172,8 +178,9 @@ describe('TokenWrapper', () => {
|
|||||||
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
it('should throw a CONTRACT_DOES_NOT_EXIST error for a non-existent token contract', async () => {
|
||||||
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
const nonExistentTokenAddress = '0x9dd402f14d67e001d8efbe6583e51bf9706aa065';
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress))
|
return expect(zeroEx.token.getBalanceAsync(nonExistentTokenAddress, ownerAddress)).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(ZeroExError.TokenContractDoesNotExist);
|
ZeroExError.TokenContractDoesNotExist,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('should return a balance of 0 for a non-existent owner address', async () => {
|
it('should return a balance of 0 for a non-existent owner address', async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
@ -200,13 +207,16 @@ describe('TokenWrapper', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#setAllowanceAsync', () => {
|
describe('#setAllowanceAsync', () => {
|
||||||
it('should set the spender\'s allowance', async () => {
|
it("should set the spender's allowance", async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
const spenderAddress = addressWithoutFunds;
|
const spenderAddress = addressWithoutFunds;
|
||||||
|
|
||||||
const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(token.address, ownerAddress,
|
const allowanceBeforeSet = await zeroEx.token.getAllowanceAsync(
|
||||||
spenderAddress);
|
token.address,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
|
);
|
||||||
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
|
const expectedAllowanceBeforeAllowanceSet = new BigNumber(0);
|
||||||
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
|
expect(allowanceBeforeSet).to.be.bignumber.equal(expectedAllowanceBeforeAllowanceSet);
|
||||||
|
|
||||||
@ -219,7 +229,7 @@ describe('TokenWrapper', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#setUnlimitedAllowanceAsync', () => {
|
describe('#setUnlimitedAllowanceAsync', () => {
|
||||||
it('should set the unlimited spender\'s allowance', async () => {
|
it("should set the unlimited spender's allowance", async () => {
|
||||||
const token = tokens[0];
|
const token = tokens[0];
|
||||||
const ownerAddress = coinbase;
|
const ownerAddress = coinbase;
|
||||||
const spenderAddress = addressWithoutFunds;
|
const spenderAddress = addressWithoutFunds;
|
||||||
@ -241,10 +251,18 @@ describe('TokenWrapper', () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await zeroEx.token.transferFromAsync(
|
await zeroEx.token.transferFromAsync(
|
||||||
zrx.address, coinbase, userWithNormalAllowance, userWithNormalAllowance, transferAmount,
|
zrx.address,
|
||||||
|
coinbase,
|
||||||
|
userWithNormalAllowance,
|
||||||
|
userWithNormalAllowance,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
await zeroEx.token.transferFromAsync(
|
await zeroEx.token.transferFromAsync(
|
||||||
zrx.address, coinbase, userWithUnlimitedAllowance, userWithUnlimitedAllowance, transferAmount,
|
zrx.address,
|
||||||
|
coinbase,
|
||||||
|
userWithUnlimitedAllowance,
|
||||||
|
userWithUnlimitedAllowance,
|
||||||
|
transferAmount,
|
||||||
);
|
);
|
||||||
|
|
||||||
const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
|
const finalBalanceWithNormalAllowance = await web3Wrapper.getBalanceInWeiAsync(userWithNormalAllowance);
|
||||||
@ -300,7 +318,9 @@ describe('TokenWrapper', () => {
|
|||||||
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
|
await zeroEx.token.setAllowanceAsync(token.address, ownerAddress, spenderAddress, amountInBaseUnits);
|
||||||
|
|
||||||
const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
|
const allowance = await zeroExWithoutAccounts.token.getAllowanceAsync(
|
||||||
token.address, ownerAddress, spenderAddress,
|
token.address,
|
||||||
|
ownerAddress,
|
||||||
|
spenderAddress,
|
||||||
);
|
);
|
||||||
const expectedAllowance = amountInBaseUnits;
|
const expectedAllowance = amountInBaseUnits;
|
||||||
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
|
return expect(allowance).to.be.bignumber.equal(expectedAllowance);
|
||||||
@ -378,8 +398,7 @@ describe('TokenWrapper', () => {
|
|||||||
expect(args._value).to.be.bignumber.equal(transferAmount);
|
expect(args._value).to.be.bignumber.equal(transferAmount);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -394,8 +413,7 @@ describe('TokenWrapper', () => {
|
|||||||
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
expect(args._value).to.be.bignumber.equal(allowanceAmount);
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
||||||
tokenAddress, TokenEvents.Approval, indexFilterValues, callback);
|
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -404,17 +422,13 @@ describe('TokenWrapper', () => {
|
|||||||
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
};
|
};
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled,
|
|
||||||
);
|
|
||||||
const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => {
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
const newProvider = web3Factory.getRpcProvider();
|
const newProvider = web3Factory.getRpcProvider();
|
||||||
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID);
|
||||||
zeroEx.token.subscribe(
|
zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled);
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled,
|
|
||||||
);
|
|
||||||
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||||
})().catch(done);
|
})().catch(done);
|
||||||
});
|
});
|
||||||
@ -424,7 +438,11 @@ describe('TokenWrapper', () => {
|
|||||||
done(new Error('Expected this subscription to have been cancelled'));
|
done(new Error('Expected this subscription to have been cancelled'));
|
||||||
};
|
};
|
||||||
const subscriptionToken = zeroEx.token.subscribe(
|
const subscriptionToken = zeroEx.token.subscribe(
|
||||||
tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled);
|
tokenAddress,
|
||||||
|
TokenEvents.Transfer,
|
||||||
|
indexFilterValues,
|
||||||
|
callbackNeverToBeCalled,
|
||||||
|
);
|
||||||
zeroEx.token.unsubscribe(subscriptionToken);
|
zeroEx.token.unsubscribe(subscriptionToken);
|
||||||
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount);
|
||||||
done();
|
done();
|
||||||
@ -450,7 +468,10 @@ describe('TokenWrapper', () => {
|
|||||||
const eventName = TokenEvents.Approval;
|
const eventName = TokenEvents.Approval;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
tokenAddress, eventName, blockRange, indexFilterValues,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@ -465,7 +486,10 @@ describe('TokenWrapper', () => {
|
|||||||
const differentEventName = TokenEvents.Transfer;
|
const differentEventName = TokenEvents.Transfer;
|
||||||
const indexFilterValues = {};
|
const indexFilterValues = {};
|
||||||
const logs = await zeroEx.token.getLogsAsync(
|
const logs = await zeroEx.token.getLogsAsync(
|
||||||
tokenAddress, differentEventName, blockRange, indexFilterValues,
|
tokenAddress,
|
||||||
|
differentEventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(0);
|
expect(logs).to.have.length(0);
|
||||||
});
|
});
|
||||||
@ -479,7 +503,10 @@ describe('TokenWrapper', () => {
|
|||||||
_owner: coinbase,
|
_owner: coinbase,
|
||||||
};
|
};
|
||||||
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
const logs = await zeroEx.token.getLogsAsync<ApprovalContractEventArgs>(
|
||||||
tokenAddress, eventName, blockRange, indexFilterValues,
|
tokenAddress,
|
||||||
|
eventName,
|
||||||
|
blockRange,
|
||||||
|
indexFilterValues,
|
||||||
);
|
);
|
||||||
expect(logs).to.have.length(1);
|
expect(logs).to.have.length(1);
|
||||||
const args = logs[0].args;
|
const args = logs[0].args;
|
||||||
@ -487,3 +514,4 @@ describe('TokenWrapper', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// tslint:disable:max-file-line-count
|
||||||
|
@ -17,8 +17,13 @@ export class FillScenarios {
|
|||||||
private _coinbase: string;
|
private _coinbase: string;
|
||||||
private _zrxTokenAddress: string;
|
private _zrxTokenAddress: string;
|
||||||
private _exchangeContractAddress: string;
|
private _exchangeContractAddress: string;
|
||||||
constructor(zeroEx: ZeroEx, userAddresses: string[],
|
constructor(
|
||||||
tokens: Token[], zrxTokenAddress: string, exchangeContractAddress: string) {
|
zeroEx: ZeroEx,
|
||||||
|
userAddresses: string[],
|
||||||
|
tokens: Token[],
|
||||||
|
zrxTokenAddress: string,
|
||||||
|
exchangeContractAddress: string,
|
||||||
|
) {
|
||||||
this._zeroEx = zeroEx;
|
this._zeroEx = zeroEx;
|
||||||
this._userAddresses = userAddresses;
|
this._userAddresses = userAddresses;
|
||||||
this._tokens = tokens;
|
this._tokens = tokens;
|
||||||
@ -31,7 +36,8 @@ export class FillScenarios {
|
|||||||
for (const token of this._tokens) {
|
for (const token of this._tokens) {
|
||||||
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
|
if (token.symbol !== 'ZRX' && token.symbol !== 'WETH') {
|
||||||
const contractInstance = web3Wrapper.getContractInstance(
|
const contractInstance = web3Wrapper.getContractInstance(
|
||||||
artifacts.DummyTokenArtifact.abi, token.address,
|
artifacts.DummyTokenArtifact.abi,
|
||||||
|
token.address,
|
||||||
);
|
);
|
||||||
const defaults = {};
|
const defaults = {};
|
||||||
const dummyToken = new DummyTokenContract(contractInstance, defaults);
|
const dummyToken = new DummyTokenContract(contractInstance, defaults);
|
||||||
@ -43,61 +49,110 @@ export class FillScenarios {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async createFillableSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
public async createFillableSignedOrderAsync(
|
||||||
makerAddress: string, takerAddress: string,
|
makerTokenAddress: string,
|
||||||
|
takerTokenAddress: string,
|
||||||
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
fillableAmount: BigNumber,
|
fillableAmount: BigNumber,
|
||||||
expirationUnixTimestampSec?: BigNumber):
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
Promise<SignedOrder> {
|
): Promise<SignedOrder> {
|
||||||
return this.createAsymmetricFillableSignedOrderAsync(
|
return this.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, fillableAmount, expirationUnixTimestampSec,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
fillableAmount,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async createFillableSignedOrderWithFeesAsync(
|
public async createFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress: string, takerTokenAddress: string,
|
makerTokenAddress: string,
|
||||||
makerFee: BigNumber, takerFee: BigNumber,
|
takerTokenAddress: string,
|
||||||
makerAddress: string, takerAddress: string,
|
makerFee: BigNumber,
|
||||||
|
takerFee: BigNumber,
|
||||||
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
fillableAmount: BigNumber,
|
fillableAmount: BigNumber,
|
||||||
feeRecepient: string, expirationUnixTimestampSec?: BigNumber,
|
feeRecepient: string,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
): Promise<SignedOrder> {
|
): Promise<SignedOrder> {
|
||||||
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, fillableAmount, feeRecepient, expirationUnixTimestampSec,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
fillableAmount,
|
||||||
|
feeRecepient,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async createAsymmetricFillableSignedOrderAsync(
|
public async createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress: string, takerTokenAddress: string, makerAddress: string, takerAddress: string,
|
makerTokenAddress: string,
|
||||||
makerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
|
takerTokenAddress: string,
|
||||||
expirationUnixTimestampSec?: BigNumber): Promise<SignedOrder> {
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
|
makerFillableAmount: BigNumber,
|
||||||
|
takerFillableAmount: BigNumber,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
const makerFee = new BigNumber(0);
|
const makerFee = new BigNumber(0);
|
||||||
const takerFee = new BigNumber(0);
|
const takerFee = new BigNumber(0);
|
||||||
const feeRecepient = constants.NULL_ADDRESS;
|
const feeRecepient = constants.NULL_ADDRESS;
|
||||||
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
return this._createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerFee, takerFee, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
makerFillableAmount, takerFillableAmount, feeRecepient, expirationUnixTimestampSec,
|
takerTokenAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
makerFillableAmount,
|
||||||
|
takerFillableAmount,
|
||||||
|
feeRecepient,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public async createPartiallyFilledSignedOrderAsync(makerTokenAddress: string, takerTokenAddress: string,
|
public async createPartiallyFilledSignedOrderAsync(
|
||||||
takerAddress: string, fillableAmount: BigNumber,
|
makerTokenAddress: string,
|
||||||
partialFillAmount: BigNumber) {
|
takerTokenAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
|
fillableAmount: BigNumber,
|
||||||
|
partialFillAmount: BigNumber,
|
||||||
|
) {
|
||||||
const [makerAddress] = this._userAddresses;
|
const [makerAddress] = this._userAddresses;
|
||||||
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
|
const signedOrder = await this.createAsymmetricFillableSignedOrderAsync(
|
||||||
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
|
makerTokenAddress,
|
||||||
fillableAmount, fillableAmount,
|
takerTokenAddress,
|
||||||
|
makerAddress,
|
||||||
|
takerAddress,
|
||||||
|
fillableAmount,
|
||||||
|
fillableAmount,
|
||||||
);
|
);
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = false;
|
const shouldThrowOnInsufficientBalanceOrAllowance = false;
|
||||||
await this._zeroEx.exchange.fillOrderAsync(
|
await this._zeroEx.exchange.fillOrderAsync(
|
||||||
signedOrder, partialFillAmount, shouldThrowOnInsufficientBalanceOrAllowance, takerAddress,
|
signedOrder,
|
||||||
|
partialFillAmount,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
takerAddress,
|
||||||
);
|
);
|
||||||
return signedOrder;
|
return signedOrder;
|
||||||
}
|
}
|
||||||
private async _createAsymmetricFillableSignedOrderWithFeesAsync(
|
private async _createAsymmetricFillableSignedOrderWithFeesAsync(
|
||||||
makerTokenAddress: string, takerTokenAddress: string,
|
makerTokenAddress: string,
|
||||||
makerFee: BigNumber, takerFee: BigNumber,
|
takerTokenAddress: string,
|
||||||
makerAddress: string, takerAddress: string,
|
makerFee: BigNumber,
|
||||||
makerFillableAmount: BigNumber, takerFillableAmount: BigNumber,
|
takerFee: BigNumber,
|
||||||
feeRecepient: string, expirationUnixTimestampSec?: BigNumber): Promise<SignedOrder> {
|
makerAddress: string,
|
||||||
|
takerAddress: string,
|
||||||
|
makerFillableAmount: BigNumber,
|
||||||
|
takerFillableAmount: BigNumber,
|
||||||
|
feeRecepient: string,
|
||||||
|
expirationUnixTimestampSec?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
|
this._increaseBalanceAndAllowanceAsync(makerTokenAddress, makerAddress, makerFillableAmount),
|
||||||
this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
|
this._increaseBalanceAndAllowanceAsync(takerTokenAddress, takerAddress, takerFillableAmount),
|
||||||
@ -107,14 +162,27 @@ export class FillScenarios {
|
|||||||
this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
|
this._increaseBalanceAndAllowanceAsync(this._zrxTokenAddress, takerAddress, takerFee),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const signedOrder = await orderFactory.createSignedOrderAsync(this._zeroEx,
|
const signedOrder = await orderFactory.createSignedOrderAsync(
|
||||||
makerAddress, takerAddress, makerFee, takerFee,
|
this._zeroEx,
|
||||||
makerFillableAmount, makerTokenAddress, takerFillableAmount, takerTokenAddress,
|
makerAddress,
|
||||||
this._exchangeContractAddress, feeRecepient, expirationUnixTimestampSec);
|
takerAddress,
|
||||||
|
makerFee,
|
||||||
|
takerFee,
|
||||||
|
makerFillableAmount,
|
||||||
|
makerTokenAddress,
|
||||||
|
takerFillableAmount,
|
||||||
|
takerTokenAddress,
|
||||||
|
this._exchangeContractAddress,
|
||||||
|
feeRecepient,
|
||||||
|
expirationUnixTimestampSec,
|
||||||
|
);
|
||||||
return signedOrder;
|
return signedOrder;
|
||||||
}
|
}
|
||||||
private async _increaseBalanceAndAllowanceAsync(
|
private async _increaseBalanceAndAllowanceAsync(
|
||||||
tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
tokenAddress: string,
|
||||||
|
address: string,
|
||||||
|
amount: BigNumber,
|
||||||
|
): Promise<void> {
|
||||||
if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
|
if (amount.isZero() || address === ZeroEx.NULL_ADDRESS) {
|
||||||
return; // noop
|
return; // noop
|
||||||
}
|
}
|
||||||
@ -123,16 +191,12 @@ export class FillScenarios {
|
|||||||
this._increaseAllowanceAsync(tokenAddress, address, amount),
|
this._increaseAllowanceAsync(tokenAddress, address, amount),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
private async _increaseBalanceAsync(
|
private async _increaseBalanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
||||||
tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
|
||||||
await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
|
await this._zeroEx.token.transferAsync(tokenAddress, this._coinbase, address, amount);
|
||||||
}
|
}
|
||||||
private async _increaseAllowanceAsync(
|
private async _increaseAllowanceAsync(tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
||||||
tokenAddress: string, address: string, amount: BigNumber): Promise<void> {
|
|
||||||
const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
|
const oldMakerAllowance = await this._zeroEx.token.getProxyAllowanceAsync(tokenAddress, address);
|
||||||
const newMakerAllowance = oldMakerAllowance.plus(amount);
|
const newMakerAllowance = oldMakerAllowance.plus(amount);
|
||||||
await this._zeroEx.token.setProxyAllowanceAsync(
|
await this._zeroEx.token.setProxyAllowanceAsync(tokenAddress, address, newMakerAllowance);
|
||||||
tokenAddress, address, newMakerAllowance,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,12 @@ export const orderFactory = {
|
|||||||
takerTokenAddress: string,
|
takerTokenAddress: string,
|
||||||
exchangeContractAddress: string,
|
exchangeContractAddress: string,
|
||||||
feeRecipient: string,
|
feeRecipient: string,
|
||||||
expirationUnixTimestampSecIfExists?: BigNumber): Promise<SignedOrder> {
|
expirationUnixTimestampSecIfExists?: BigNumber,
|
||||||
|
): Promise<SignedOrder> {
|
||||||
const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
|
const defaultExpirationUnixTimestampSec = new BigNumber(2524604400); // Close to infinite
|
||||||
const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists) ?
|
const expirationUnixTimestampSec = _.isUndefined(expirationUnixTimestampSecIfExists)
|
||||||
defaultExpirationUnixTimestampSec :
|
? defaultExpirationUnixTimestampSec
|
||||||
expirationUnixTimestampSecIfExists;
|
: expirationUnixTimestampSecIfExists;
|
||||||
const order = {
|
const order = {
|
||||||
maker,
|
maker,
|
||||||
taker,
|
taker,
|
||||||
|
@ -31,9 +31,11 @@ export const web3Factory = {
|
|||||||
provider.addProvider(new EmptyWalletSubprovider());
|
provider.addProvider(new EmptyWalletSubprovider());
|
||||||
}
|
}
|
||||||
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
|
provider.addProvider(new FakeGasEstimateSubprovider(constants.GAS_ESTIMATE));
|
||||||
provider.addProvider(new RpcSubprovider({
|
provider.addProvider(
|
||||||
|
new RpcSubprovider({
|
||||||
rpcUrl: constants.RPC_URL,
|
rpcUrl: constants.RPC_URL,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
provider.start();
|
provider.start();
|
||||||
return provider;
|
return provider;
|
||||||
},
|
},
|
||||||
|
@ -32,8 +32,7 @@ const args = yargs
|
|||||||
describe: 'Folder where to put the output files',
|
describe: 'Folder where to put the output files',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
demand: true,
|
demand: true,
|
||||||
})
|
}).argv;
|
||||||
.argv;
|
|
||||||
|
|
||||||
function writeOutputFile(name: string, renderedTsCode: string): void {
|
function writeOutputFile(name: string, renderedTsCode: string): void {
|
||||||
const fileName = toSnakeCase(name);
|
const fileName = toSnakeCase(name);
|
||||||
@ -66,9 +65,9 @@ for (const abiFileName of abiFileNames) {
|
|||||||
const namedContent = utils.getNamedContent(abiFileName);
|
const namedContent = utils.getNamedContent(abiFileName);
|
||||||
utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
|
utils.log(`Processing: ${chalk.bold(namedContent.name)}...`);
|
||||||
const parsedContent = JSON.parse(namedContent.content);
|
const parsedContent = JSON.parse(namedContent.content);
|
||||||
const ABI = _.isArray(parsedContent) ?
|
const ABI = _.isArray(parsedContent)
|
||||||
parsedContent : // ABI file
|
? parsedContent // ABI file
|
||||||
parsedContent.abi; // Truffle contracts file
|
: parsedContent.abi; // Truffle contracts file
|
||||||
if (_.isUndefined(ABI)) {
|
if (_.isUndefined(ABI)) {
|
||||||
utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
|
utils.log(`${chalk.red(`ABI not found in ${abiFileName}.`)}`);
|
||||||
utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
|
utils.log(`Please make sure your ABI file is either an array with ABI entries or an object with the abi key`);
|
||||||
|
@ -23,7 +23,10 @@ export const utils = {
|
|||||||
if (paramKind === ParamKind.Input) {
|
if (paramKind === ParamKind.Input) {
|
||||||
// web3 allows to pass those an non-bignumbers and that's nice
|
// web3 allows to pass those an non-bignumbers and that's nice
|
||||||
// but it always returns stuff as BigNumbers
|
// but it always returns stuff as BigNumbers
|
||||||
solTypeRegexToTsType.unshift({regex: '^u?int(8|16|32)?$', tsType: 'number|BigNumber'});
|
solTypeRegexToTsType.unshift({
|
||||||
|
regex: '^u?int(8|16|32)?$',
|
||||||
|
tsType: 'number|BigNumber',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
for (const regexAndTxType of solTypeRegexToTsType) {
|
for (const regexAndTxType of solTypeRegexToTsType) {
|
||||||
const { regex, tsType } = regexAndTxType;
|
const { regex, tsType } = regexAndTxType;
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import {
|
import { Schema, SchemaValidator } from '@0xproject/json-schemas';
|
||||||
Schema,
|
|
||||||
SchemaValidator,
|
|
||||||
} from '@0xproject/json-schemas';
|
|
||||||
import { addressUtils } from '@0xproject/utils';
|
import { addressUtils } from '@0xproject/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
@ -18,7 +15,8 @@ export const assert = {
|
|||||||
assert.isBigNumber(variableName, value);
|
assert.isBigNumber(variableName, value);
|
||||||
const hasDecimals = value.decimalPlaces() !== 0;
|
const hasDecimals = value.decimalPlaces() !== 0;
|
||||||
this.assert(
|
this.assert(
|
||||||
!hasDecimals, `${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
|
!hasDecimals,
|
||||||
|
`${variableName} should be in baseUnits (no decimals), found value: ${value.toNumber()}`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
isUndefined(value: any, variableName?: string): void {
|
isUndefined(value: any, variableName?: string): void {
|
||||||
@ -31,8 +29,10 @@ export const assert = {
|
|||||||
this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value));
|
this.assert(_.isFunction(value), this.typeAssertionMessage(variableName, 'function', value));
|
||||||
},
|
},
|
||||||
isHexString(variableName: string, value: string): void {
|
isHexString(variableName: string, value: string): void {
|
||||||
this.assert(_.isString(value) && HEX_REGEX.test(value),
|
this.assert(
|
||||||
this.typeAssertionMessage(variableName, 'HexString', value));
|
_.isString(value) && HEX_REGEX.test(value),
|
||||||
|
this.typeAssertionMessage(variableName, 'HexString', value),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
isETHAddressHex(variableName: string, value: string): void {
|
isETHAddressHex(variableName: string, value: string): void {
|
||||||
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
|
this.assert(addressUtils.isAddress(value), this.typeAssertionMessage(variableName, 'ETHAddressHex', value));
|
||||||
@ -41,8 +41,11 @@ export const assert = {
|
|||||||
`Checksummed addresses are not supported. Convert ${variableName} to lower case before passing`,
|
`Checksummed addresses are not supported. Convert ${variableName} to lower case before passing`,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
doesBelongToStringEnum(variableName: string, value: string,
|
doesBelongToStringEnum(
|
||||||
stringEnum: any /* There is no base type for every string enum */): void {
|
variableName: string,
|
||||||
|
value: string,
|
||||||
|
stringEnum: any /* There is no base type for every string enum */,
|
||||||
|
): void {
|
||||||
const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]);
|
const doesBelongToStringEnum = !_.isUndefined(stringEnum[value]);
|
||||||
const enumValues = _.keys(stringEnum);
|
const enumValues = _.keys(stringEnum);
|
||||||
const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`);
|
const enumValuesAsStrings = _.map(enumValues, enumValue => `'${enumValue}'`);
|
||||||
@ -62,7 +65,7 @@ export const assert = {
|
|||||||
this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value));
|
this.assert(_.isBoolean(value), this.typeAssertionMessage(variableName, 'boolean', value));
|
||||||
},
|
},
|
||||||
isWeb3Provider(variableName: string, value: any): void {
|
isWeb3Provider(variableName: string, value: any): void {
|
||||||
const isWeb3Provider = _.isFunction((value).send) || _.isFunction((value).sendAsync);
|
const isWeb3Provider = _.isFunction(value.send) || _.isFunction(value.sendAsync);
|
||||||
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
|
this.assert(isWeb3Provider, this.typeAssertionMessage(variableName, 'Web3.Provider', value));
|
||||||
},
|
},
|
||||||
doesConformToSchema(variableName: string, value: any, schema: Schema): void {
|
doesConformToSchema(variableName: string, value: any, schema: Schema): void {
|
||||||
|
@ -14,75 +14,41 @@ describe('Assertions', () => {
|
|||||||
const variableName = 'variable';
|
const variableName = 'variable';
|
||||||
describe('#isBigNumber', () => {
|
describe('#isBigNumber', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [new BigNumber(23), new BigNumber('45')];
|
||||||
new BigNumber(23),
|
|
||||||
new BigNumber('45'),
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = ['test', 42, false, { random: 'test' }, undefined];
|
||||||
'test',
|
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isBigNumber.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isUndefined', () => {
|
describe('#isUndefined', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [undefined];
|
||||||
undefined,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isUndefined.bind(assert, input, variableName)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isUndefined.bind(assert, input, variableName)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = ['test', 42, false, { random: 'test' }];
|
||||||
'test',
|
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isUndefined.bind(assert, input, variableName)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isUndefined.bind(assert, input, variableName)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isString', () => {
|
describe('#isString', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = ['hello', 'goodbye'];
|
||||||
'hello',
|
|
||||||
'goodbye',
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isString.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isFunction', () => {
|
describe('#isFunction', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [BigNumber, assert.isString.bind(this)];
|
||||||
BigNumber,
|
|
||||||
assert.isString.bind(this),
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isFunction.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -127,9 +93,7 @@ describe('Assertions', () => {
|
|||||||
'0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
|
'0x6FFFd0ae3f7d88c9b4925323f54c6e4b2918c5fd',
|
||||||
'0x6FFFd0ae3f7d88c9b4925323f54c6e4',
|
'0x6FFFd0ae3f7d88c9b4925323f54c6e4',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input => expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw());
|
||||||
expect(assert.isETHAddressHex.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#doesBelongToStringEnum', () => {
|
describe('#doesBelongToStringEnum', () => {
|
||||||
@ -138,22 +102,13 @@ describe('Assertions', () => {
|
|||||||
Test2 = 'Test2',
|
Test2 = 'Test2',
|
||||||
}
|
}
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [TestEnums.Test1, TestEnums.Test2];
|
||||||
TestEnums.Test1,
|
|
||||||
TestEnums.Test2,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input =>
|
||||||
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
|
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.not.throw(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input =>
|
||||||
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
|
expect(assert.doesBelongToStringEnum.bind(assert, variableName, input, TestEnums)).to.throw(),
|
||||||
);
|
);
|
||||||
@ -162,19 +117,13 @@ describe('Assertions', () => {
|
|||||||
describe('#hasAtMostOneUniqueValue', () => {
|
describe('#hasAtMostOneUniqueValue', () => {
|
||||||
const errorMsg = 'more than one unique value';
|
const errorMsg = 'more than one unique value';
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [['hello'], ['goodbye', 'goodbye', 'goodbye']];
|
||||||
['hello'],
|
|
||||||
['goodbye', 'goodbye', 'goodbye'],
|
|
||||||
];
|
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input =>
|
||||||
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
|
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.not.throw(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [['hello', 'goodbye'], ['goodbye', 42, false, false]];
|
||||||
['hello', 'goodbye'],
|
|
||||||
['goodbye', 42, false, false],
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input =>
|
||||||
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
|
expect(assert.hasAtMostOneUniqueValue.bind(assert, input, errorMsg)).to.throw(),
|
||||||
);
|
);
|
||||||
@ -182,61 +131,34 @@ describe('Assertions', () => {
|
|||||||
});
|
});
|
||||||
describe('#isNumber', () => {
|
describe('#isNumber', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [42, 0, 21e42];
|
||||||
42,
|
|
||||||
0,
|
|
||||||
21e+42,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [false, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
false,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isNumber.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isBoolean', () => {
|
describe('#isBoolean', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [true, false];
|
||||||
true,
|
|
||||||
false,
|
|
||||||
];
|
|
||||||
validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
|
validInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.not.throw());
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
|
invalidInputs.forEach(input => expect(assert.isBoolean.bind(assert, variableName, input)).to.throw());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isWeb3Provider', () => {
|
describe('#isWeb3Provider', () => {
|
||||||
it('should not throw for valid input', () => {
|
it('should not throw for valid input', () => {
|
||||||
const validInputs = [
|
const validInputs = [{ send: () => 45 }, { sendAsync: () => 45 }];
|
||||||
{send: () => 45},
|
|
||||||
{sendAsync: () => 45},
|
|
||||||
];
|
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input =>
|
||||||
expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
|
expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.not.throw(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
invalidInputs.forEach(input => expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw());
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
|
||||||
expect(assert.isWeb3Provider.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#doesConformToSchema', () => {
|
describe('#doesConformToSchema', () => {
|
||||||
@ -251,12 +173,7 @@ describe('Assertions', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [42, { random: 'test' }, undefined, new BigNumber(45)];
|
||||||
42,
|
|
||||||
{random: 'test'},
|
|
||||||
undefined,
|
|
||||||
new BigNumber(45),
|
|
||||||
];
|
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input =>
|
||||||
expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
|
expect(assert.doesConformToSchema.bind(assert, variableName, input, schema)).to.throw(),
|
||||||
);
|
);
|
||||||
@ -270,9 +187,7 @@ describe('Assertions', () => {
|
|||||||
'https://api.radarrelay.com/0x/v0/',
|
'https://api.radarrelay.com/0x/v0/',
|
||||||
'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
|
'https://zeroex.beta.radarrelay.com:8000/0x/v0/',
|
||||||
];
|
];
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw());
|
||||||
expect(assert.isHttpUrl.bind(assert, variableName, input)).to.not.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
@ -286,9 +201,7 @@ describe('Assertions', () => {
|
|||||||
'user:password@api.example-relayer.net',
|
'user:password@api.example-relayer.net',
|
||||||
'//api.example-relayer.net',
|
'//api.example-relayer.net',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input => expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw());
|
||||||
expect(assert.isHttpUrl.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#isUri', () => {
|
describe('#isUri', () => {
|
||||||
@ -302,9 +215,7 @@ describe('Assertions', () => {
|
|||||||
'wss://www.api.example-relayer.net',
|
'wss://www.api.example-relayer.net',
|
||||||
'user:password@api.example-relayer.net',
|
'user:password@api.example-relayer.net',
|
||||||
];
|
];
|
||||||
validInputs.forEach(input =>
|
validInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.not.throw());
|
||||||
expect(assert.isUri.bind(assert, variableName, input)).to.not.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
it('should throw for invalid input', () => {
|
it('should throw for invalid input', () => {
|
||||||
const invalidInputs = [
|
const invalidInputs = [
|
||||||
@ -316,9 +227,7 @@ describe('Assertions', () => {
|
|||||||
'api.example-relayer.net',
|
'api.example-relayer.net',
|
||||||
'//api.example-relayer.net',
|
'//api.example-relayer.net',
|
||||||
];
|
];
|
||||||
invalidInputs.forEach(input =>
|
invalidInputs.forEach(input => expect(assert.isUri.bind(assert, variableName, input)).to.throw());
|
||||||
expect(assert.isUri.bind(assert, variableName, input)).to.throw(),
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#assert', () => {
|
describe('#assert', () => {
|
||||||
@ -332,8 +241,9 @@ describe('Assertions', () => {
|
|||||||
});
|
});
|
||||||
describe('#typeAssertionMessage', () => {
|
describe('#typeAssertionMessage', () => {
|
||||||
it('should render correct message', () => {
|
it('should render correct message', () => {
|
||||||
expect(assert.typeAssertionMessage('variable', 'string', 'number'))
|
expect(assert.typeAssertionMessage('variable', 'string', 'number')).to.equal(
|
||||||
.to.equal(`Expected variable to be of type string, encountered: number`);
|
`Expected variable to be of type string, encountered: number`,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -49,8 +49,7 @@ export class HttpClient implements Client {
|
|||||||
params: request,
|
params: request,
|
||||||
};
|
};
|
||||||
const tokenPairs = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
|
const tokenPairs = await this._requestAsync('/token_pairs', HttpRequestType.Get, requestOpts);
|
||||||
assert.doesConformToSchema(
|
assert.doesConformToSchema('tokenPairs', tokenPairs, schemas.relayerApiTokenPairsResponseSchema);
|
||||||
'tokenPairs', tokenPairs, schemas.relayerApiTokenPairsResponseSchema);
|
|
||||||
_.each(tokenPairs, (tokenPair: object) => {
|
_.each(tokenPairs, (tokenPair: object) => {
|
||||||
typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
|
typeConverters.convertStringsFieldsToBigNumbers(tokenPair, [
|
||||||
'tokenA.minAmount',
|
'tokenA.minAmount',
|
||||||
@ -137,8 +136,11 @@ export class HttpClient implements Client {
|
|||||||
};
|
};
|
||||||
await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
|
await this._requestAsync('/order', HttpRequestType.Post, requestOpts);
|
||||||
}
|
}
|
||||||
private async _requestAsync(path: string, requestType: HttpRequestType,
|
private async _requestAsync(
|
||||||
requestOptions?: HttpRequestOptions): Promise<any> {
|
path: string,
|
||||||
|
requestType: HttpRequestType,
|
||||||
|
requestOptions?: HttpRequestOptions,
|
||||||
|
): Promise<any> {
|
||||||
const params = _.get(requestOptions, 'params');
|
const params = _.get(requestOptions, 'params');
|
||||||
const payload = _.get(requestOptions, 'payload');
|
const payload = _.get(requestOptions, 'payload');
|
||||||
let query = '';
|
let query = '';
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
import {
|
import { relayerOrderBookRequestSchema } from './relayer_orderbook_request_schema';
|
||||||
relayerOrderBookRequestSchema,
|
import { relayerOrdersRequestSchema } from './relayer_orders_request_schema';
|
||||||
} from './relayer_orderbook_request_schema';
|
import { relayerTokenPairsRequestSchema } from './relayer_token_pairs_request_schema';
|
||||||
import {
|
|
||||||
relayerOrdersRequestSchema,
|
|
||||||
} from './relayer_orders_request_schema';
|
|
||||||
import {
|
|
||||||
relayerTokenPairsRequestSchema,
|
|
||||||
} from './relayer_token_pairs_request_schema';
|
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
relayerOrderBookRequestSchema,
|
relayerOrderBookRequestSchema,
|
||||||
|
@ -57,19 +57,24 @@ export interface OrderbookChannelSubscriptionOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface OrderbookChannelHandler {
|
export interface OrderbookChannelHandler {
|
||||||
onSnapshot: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
onSnapshot: (
|
||||||
snapshot: OrderbookResponse) => void;
|
channel: OrderbookChannel,
|
||||||
onUpdate: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
||||||
order: SignedOrder) => void;
|
snapshot: OrderbookResponse,
|
||||||
onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
) => void;
|
||||||
err: Error) => void;
|
onUpdate: (
|
||||||
|
channel: OrderbookChannel,
|
||||||
|
subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
||||||
|
order: SignedOrder,
|
||||||
|
) => void;
|
||||||
|
onError: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts, err: Error) => void;
|
||||||
onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
|
onClose: (channel: OrderbookChannel, subscriptionOpts: OrderbookChannelSubscriptionOpts) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OrderbookChannelMessage =
|
export type OrderbookChannelMessage =
|
||||||
SnapshotOrderbookChannelMessage |
|
| SnapshotOrderbookChannelMessage
|
||||||
UpdateOrderbookChannelMessage |
|
| UpdateOrderbookChannelMessage
|
||||||
UnknownOrderbookChannelMessage;
|
| UnknownOrderbookChannelMessage;
|
||||||
|
|
||||||
export enum OrderbookChannelMessageTypes {
|
export enum OrderbookChannelMessageTypes {
|
||||||
Snapshot = 'snapshot',
|
Snapshot = 'snapshot',
|
||||||
|
@ -2,10 +2,7 @@ import {assert} from '@0xproject/assert';
|
|||||||
import { schemas } from '@0xproject/json-schemas';
|
import { schemas } from '@0xproject/json-schemas';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import {
|
import { OrderbookChannelMessage, OrderbookChannelMessageTypes } from '../types';
|
||||||
OrderbookChannelMessage,
|
|
||||||
OrderbookChannelMessageTypes,
|
|
||||||
} from '../types';
|
|
||||||
|
|
||||||
import { typeConverters } from './type_converters';
|
import { typeConverters } from './type_converters';
|
||||||
|
|
||||||
@ -16,13 +13,13 @@ export const orderbookChannelMessageParsers = {
|
|||||||
assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
|
assert.assert(!_.isUndefined(type), `Message is missing a type parameter: ${utf8Data}`);
|
||||||
assert.isString('type', type);
|
assert.isString('type', type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case (OrderbookChannelMessageTypes.Snapshot): {
|
case OrderbookChannelMessageTypes.Snapshot: {
|
||||||
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
|
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelSnapshotSchema);
|
||||||
const orderbook = messageObj.payload;
|
const orderbook = messageObj.payload;
|
||||||
typeConverters.convertOrderbookStringFieldsToBigNumber(orderbook);
|
typeConverters.convertOrderbookStringFieldsToBigNumber(orderbook);
|
||||||
return messageObj;
|
return messageObj;
|
||||||
}
|
}
|
||||||
case (OrderbookChannelMessageTypes.Update): {
|
case OrderbookChannelMessageTypes.Update: {
|
||||||
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
|
assert.doesConformToSchema('message', messageObj, schemas.relayerApiOrderbookChannelUpdateSchema);
|
||||||
const order = messageObj.payload;
|
const order = messageObj.payload;
|
||||||
typeConverters.convertOrderStringFieldsToBigNumber(order);
|
typeConverters.convertOrderStringFieldsToBigNumber(order);
|
||||||
|
@ -41,7 +41,10 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
|
|||||||
*/
|
*/
|
||||||
public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
|
public subscribe(subscriptionOpts: OrderbookChannelSubscriptionOpts, handler: OrderbookChannelHandler): void {
|
||||||
assert.doesConformToSchema(
|
assert.doesConformToSchema(
|
||||||
'subscriptionOpts', subscriptionOpts, schemas.relayerApiOrderbookChannelSubscribePayload);
|
'subscriptionOpts',
|
||||||
|
subscriptionOpts,
|
||||||
|
schemas.relayerApiOrderbookChannelSubscribePayload,
|
||||||
|
);
|
||||||
assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
|
assert.isFunction('handler.onSnapshot', _.get(handler, 'onSnapshot'));
|
||||||
assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
|
assert.isFunction('handler.onUpdate', _.get(handler, 'onUpdate'));
|
||||||
assert.isFunction('handler.onError', _.get(handler, 'onError'));
|
assert.isFunction('handler.onError', _.get(handler, 'onError'));
|
||||||
@ -92,25 +95,32 @@ export class WebSocketOrderbookChannel implements OrderbookChannel {
|
|||||||
this._client.connect(this._apiEndpointUrl);
|
this._client.connect(this._apiEndpointUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private _handleWebSocketMessage(requestId: number, subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
private _handleWebSocketMessage(
|
||||||
message: WebSocket.IMessage, handler: OrderbookChannelHandler): void {
|
requestId: number,
|
||||||
|
subscriptionOpts: OrderbookChannelSubscriptionOpts,
|
||||||
|
message: WebSocket.IMessage,
|
||||||
|
handler: OrderbookChannelHandler,
|
||||||
|
): void {
|
||||||
if (!_.isUndefined(message.utf8Data)) {
|
if (!_.isUndefined(message.utf8Data)) {
|
||||||
try {
|
try {
|
||||||
const utf8Data = message.utf8Data;
|
const utf8Data = message.utf8Data;
|
||||||
const parserResult = orderbookChannelMessageParsers.parser(utf8Data);
|
const parserResult = orderbookChannelMessageParsers.parser(utf8Data);
|
||||||
if (parserResult.requestId === requestId) {
|
if (parserResult.requestId === requestId) {
|
||||||
switch (parserResult.type) {
|
switch (parserResult.type) {
|
||||||
case (OrderbookChannelMessageTypes.Snapshot): {
|
case OrderbookChannelMessageTypes.Snapshot: {
|
||||||
handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
|
handler.onSnapshot(this, subscriptionOpts, parserResult.payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (OrderbookChannelMessageTypes.Update): {
|
case OrderbookChannelMessageTypes.Update: {
|
||||||
handler.onUpdate(this, subscriptionOpts, parserResult.payload);
|
handler.onUpdate(this, subscriptionOpts, parserResult.payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
handler.onError(
|
handler.onError(
|
||||||
this, subscriptionOpts, new Error(`Message has missing a type parameter: ${utf8Data}`));
|
this,
|
||||||
|
subscriptionOpts,
|
||||||
|
new Error(`Message has missing a type parameter: ${utf8Data}`),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,7 @@ import {HttpClient} from '../src/index';
|
|||||||
|
|
||||||
import { feesResponse } from './fixtures/standard_relayer_api/fees';
|
import { feesResponse } from './fixtures/standard_relayer_api/fees';
|
||||||
import * as feesResponseJSON from './fixtures/standard_relayer_api/fees.json';
|
import * as feesResponseJSON from './fixtures/standard_relayer_api/fees.json';
|
||||||
import {
|
import { orderResponse } from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
|
||||||
orderResponse,
|
|
||||||
} from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f';
|
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
import * as orderResponseJSON from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json';
|
import * as orderResponseJSON from './fixtures/standard_relayer_api/order/0xabc67323774bdbd24d94f977fa9ac94a50f016026fd13f42990861238897721f.json';
|
||||||
import { orderbookResponse } from './fixtures/standard_relayer_api/orderbook';
|
import { orderbookResponse } from './fixtures/standard_relayer_api/orderbook';
|
||||||
@ -95,7 +93,9 @@ describe('HttpClient', () => {
|
|||||||
quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
|
quoteTokenAddress: '0xa2b31dacf30a9c50ca473337c01d8a201ae33e32',
|
||||||
};
|
};
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
const url = `${relayUrl}/v0/orderbook?baseTokenAddress=${request.baseTokenAddress}"eTokenAddress=${request.quoteTokenAddress}`;
|
const url = `${relayUrl}/v0/orderbook?baseTokenAddress=${request.baseTokenAddress}"eTokenAddress=${
|
||||||
|
request.quoteTokenAddress
|
||||||
|
}`;
|
||||||
it('gets order book', async () => {
|
it('gets order book', async () => {
|
||||||
fetchMock.get(url, orderbookJSON);
|
fetchMock.get(url, orderbookJSON);
|
||||||
const orderbook = await relayerClient.getOrderbookAsync(request);
|
const orderbook = await relayerClient.getOrderbookAsync(request);
|
||||||
|
@ -58,15 +58,14 @@ describe('orderbookChannelMessageParsers', () => {
|
|||||||
expect(badCall).throws('Expected type to be of type string, encountered: 1');
|
expect(badCall).throws('Expected type to be of type string, encountered: 1');
|
||||||
});
|
});
|
||||||
it('throws when snapshot message has malformed payload', () => {
|
it('throws when snapshot message has malformed payload', () => {
|
||||||
const badCall = () =>
|
const badCall = () => orderbookChannelMessageParsers.parser(malformedSnapshotOrderbookChannelMessage);
|
||||||
orderbookChannelMessageParsers.parser(malformedSnapshotOrderbookChannelMessage);
|
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
const errMsg = 'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
|
const errMsg =
|
||||||
|
'Validation errors: instance.payload requires property "bids", instance.payload requires property "asks"';
|
||||||
expect(badCall).throws(errMsg);
|
expect(badCall).throws(errMsg);
|
||||||
});
|
});
|
||||||
it('throws when update message has malformed payload', () => {
|
it('throws when update message has malformed payload', () => {
|
||||||
const badCall = () =>
|
const badCall = () => orderbookChannelMessageParsers.parser(malformedUpdateOrderbookChannelMessage);
|
||||||
orderbookChannelMessageParsers.parser(malformedUpdateOrderbookChannelMessage);
|
|
||||||
expect(badCall).throws(/^Expected message to conform to schema/);
|
expect(badCall).throws(/^Expected message to conform to schema/);
|
||||||
});
|
});
|
||||||
it('throws when input message is not valid JSON', () => {
|
it('throws when input message is not valid JSON', () => {
|
||||||
|
@ -3,9 +3,7 @@ import * as dirtyChai from 'dirty-chai';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import 'mocha';
|
import 'mocha';
|
||||||
|
|
||||||
import {
|
import { WebSocketOrderbookChannel } from '../src/ws_orderbook_channel';
|
||||||
WebSocketOrderbookChannel,
|
|
||||||
} from '../src/ws_orderbook_channel';
|
|
||||||
|
|
||||||
chai.config.includeStack = true;
|
chai.config.includeStack = true;
|
||||||
chai.use(dirtyChai);
|
chai.use(dirtyChai);
|
||||||
@ -21,26 +19,43 @@ describe('WebSocketOrderbookChannel', () => {
|
|||||||
limit: 100,
|
limit: 100,
|
||||||
};
|
};
|
||||||
const emptyOrderbookChannelHandler = {
|
const emptyOrderbookChannelHandler = {
|
||||||
onSnapshot: () => { _.noop(); },
|
onSnapshot: () => {
|
||||||
onUpdate: () => { _.noop(); },
|
_.noop();
|
||||||
onError: () => { _.noop(); },
|
},
|
||||||
onClose: () => { _.noop(); },
|
onUpdate: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
|
onClose: () => {
|
||||||
|
_.noop();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
describe('#subscribe', () => {
|
describe('#subscribe', () => {
|
||||||
it('throws when subscriptionOpts does not conform to schema', () => {
|
it('throws when subscriptionOpts does not conform to schema', () => {
|
||||||
const badSubscribeCall = orderbookChannel.subscribe.bind(
|
const badSubscribeCall = orderbookChannel.subscribe.bind(
|
||||||
orderbookChannel, {}, emptyOrderbookChannelHandler);
|
orderbookChannel,
|
||||||
|
{},
|
||||||
|
emptyOrderbookChannelHandler,
|
||||||
|
);
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
expect(badSubscribeCall).throws('Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"');
|
expect(badSubscribeCall).throws(
|
||||||
|
'Expected subscriptionOpts to conform to schema /RelayerApiOrderbookChannelSubscribePayload\nEncountered: {}\nValidation errors: instance requires property "baseTokenAddress", instance requires property "quoteTokenAddress"',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('throws when handler has the incorrect members', () => {
|
it('throws when handler has the incorrect members', () => {
|
||||||
const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
|
const badSubscribeCall = orderbookChannel.subscribe.bind(orderbookChannel, subscriptionOpts, {});
|
||||||
expect(badSubscribeCall)
|
expect(badSubscribeCall).throws(
|
||||||
.throws('Expected handler.onSnapshot to be of type function, encountered: undefined');
|
'Expected handler.onSnapshot to be of type function, encountered: undefined',
|
||||||
|
);
|
||||||
});
|
});
|
||||||
it('does not throw when inputs are of correct types', () => {
|
it('does not throw when inputs are of correct types', () => {
|
||||||
const goodSubscribeCall = orderbookChannel.subscribe.bind(
|
const goodSubscribeCall = orderbookChannel.subscribe.bind(
|
||||||
orderbookChannel, subscriptionOpts, emptyOrderbookChannelHandler);
|
orderbookChannel,
|
||||||
|
subscriptionOpts,
|
||||||
|
emptyOrderbookChannelHandler,
|
||||||
|
);
|
||||||
expect(goodSubscribeCall).to.not.throw();
|
expect(goodSubscribeCall).to.not.throw();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -6,18 +6,14 @@ import * as Web3 from 'web3';
|
|||||||
import * as yargs from 'yargs';
|
import * as yargs from 'yargs';
|
||||||
|
|
||||||
import { commands } from './src/commands';
|
import { commands } from './src/commands';
|
||||||
import {
|
import { CliOptions, CompilerOptions, DeployerOptions } from './src/utils/types';
|
||||||
CliOptions,
|
|
||||||
CompilerOptions,
|
|
||||||
DeployerOptions,
|
|
||||||
} from './src/utils/types';
|
|
||||||
|
|
||||||
const DEFAULT_OPTIMIZER_ENABLED = false;
|
const DEFAULT_OPTIMIZER_ENABLED = false;
|
||||||
const DEFAULT_CONTRACTS_DIR = path.resolve('contracts');
|
const DEFAULT_CONTRACTS_DIR = path.resolve('contracts');
|
||||||
const DEFAULT_ARTIFACTS_DIR = `${path.resolve('build')}/artifacts/`;
|
const DEFAULT_ARTIFACTS_DIR = `${path.resolve('build')}/artifacts/`;
|
||||||
const DEFAULT_NETWORK_ID = 50;
|
const DEFAULT_NETWORK_ID = 50;
|
||||||
const DEFAULT_JSONRPC_PORT = 8545;
|
const DEFAULT_JSONRPC_PORT = 8545;
|
||||||
const DEFAULT_GAS_PRICE = ((10 ** 9) * 2).toString();
|
const DEFAULT_GAS_PRICE = (10 ** 9 * 2).toString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles all contracts with options passed in through CLI.
|
* Compiles all contracts with options passed in through CLI.
|
||||||
@ -108,8 +104,7 @@ function deployCommandBuilder(yargsInstance: any) {
|
|||||||
description: 'comma separated list of constructor args to deploy contract with',
|
description: 'comma separated list of constructor args to deploy contract with',
|
||||||
})
|
})
|
||||||
.demandOption(['contract', 'args'])
|
.demandOption(['contract', 'args'])
|
||||||
.help()
|
.help().argv;
|
||||||
.argv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
@ -149,18 +144,13 @@ function deployCommandBuilder(yargsInstance: any) {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'account to use for deploying contracts',
|
description: 'account to use for deploying contracts',
|
||||||
})
|
})
|
||||||
.command('compile',
|
.command('compile', 'compile contracts', identityCommandBuilder, onCompileCommand)
|
||||||
'compile contracts',
|
.command(
|
||||||
identityCommandBuilder,
|
'migrate',
|
||||||
onCompileCommand)
|
|
||||||
.command('migrate',
|
|
||||||
'compile and deploy contracts using migration scripts',
|
'compile and deploy contracts using migration scripts',
|
||||||
identityCommandBuilder,
|
identityCommandBuilder,
|
||||||
onMigrateCommand)
|
onMigrateCommand,
|
||||||
.command('deploy',
|
)
|
||||||
'deploy a single contract with provided arguments',
|
.command('deploy', 'deploy a single contract with provided arguments', deployCommandBuilder, onDeployCommand)
|
||||||
deployCommandBuilder,
|
.help().argv;
|
||||||
onDeployCommand)
|
|
||||||
.help()
|
|
||||||
.argv;
|
|
||||||
})();
|
})();
|
||||||
|
@ -29,7 +29,8 @@ export const migrator = {
|
|||||||
const multiSigArgs = [owners, confirmationsRequired, secondsRequired, tokenTransferProxy.address];
|
const multiSigArgs = [owners, confirmationsRequired, secondsRequired, tokenTransferProxy.address];
|
||||||
const exchange = await deployer.deployAndSaveAsync('Exchange', exchangeArgs);
|
const exchange = await deployer.deployAndSaveAsync('Exchange', exchangeArgs);
|
||||||
const multiSig = await deployer.deployAndSaveAsync(
|
const multiSig = await deployer.deployAndSaveAsync(
|
||||||
'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', multiSigArgs,
|
'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
|
||||||
|
multiSigArgs,
|
||||||
);
|
);
|
||||||
|
|
||||||
const owner = accounts[0];
|
const owner = accounts[0];
|
||||||
@ -70,12 +71,7 @@ export const migrator = {
|
|||||||
);
|
);
|
||||||
for (const token of tokenInfo) {
|
for (const token of tokenInfo) {
|
||||||
const totalSupply = new BigNumber(0);
|
const totalSupply = new BigNumber(0);
|
||||||
const args = [
|
const args = [token.name, token.symbol, token.decimals, totalSupply];
|
||||||
token.name,
|
|
||||||
token.symbol,
|
|
||||||
token.decimals,
|
|
||||||
totalSupply,
|
|
||||||
];
|
|
||||||
const dummyToken = await deployer.deployAsync('DummyToken', args);
|
const dummyToken = await deployer.deployAsync('DummyToken', args);
|
||||||
await tokenReg.addToken.sendTransactionAsync(
|
await tokenReg.addToken.sendTransactionAsync(
|
||||||
dummyToken.address,
|
dummyToken.address,
|
||||||
|
@ -150,7 +150,8 @@ export class Compiler {
|
|||||||
currentArtifact = JSON.parse(currentArtifactString);
|
currentArtifact = JSON.parse(currentArtifactString);
|
||||||
oldNetworks = currentArtifact.networks;
|
oldNetworks = currentArtifact.networks;
|
||||||
const oldNetwork: ContractData = oldNetworks[this._networkId];
|
const oldNetwork: ContractData = oldNetworks[this._networkId];
|
||||||
shouldCompile = _.isUndefined(oldNetwork) ||
|
shouldCompile =
|
||||||
|
_.isUndefined(oldNetwork) ||
|
||||||
oldNetwork.keccak256 !== sourceHash ||
|
oldNetwork.keccak256 !== sourceHash ||
|
||||||
oldNetwork.optimizer_enabled !== this._optimizerEnabled;
|
oldNetwork.optimizer_enabled !== this._optimizerEnabled;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -174,9 +175,11 @@ export class Compiler {
|
|||||||
const sourcesToCompile = {
|
const sourcesToCompile = {
|
||||||
sources: input,
|
sources: input,
|
||||||
};
|
};
|
||||||
const compiled = solcInstance.compile(sourcesToCompile,
|
const compiled = solcInstance.compile(
|
||||||
|
sourcesToCompile,
|
||||||
this._optimizerEnabled,
|
this._optimizerEnabled,
|
||||||
this._findImportsIfSourcesExist.bind(this));
|
this._findImportsIfSourcesExist.bind(this),
|
||||||
|
);
|
||||||
|
|
||||||
if (!_.isUndefined(compiled.errors)) {
|
if (!_.isUndefined(compiled.errors)) {
|
||||||
_.each(compiled.errors, errMsg => {
|
_.each(compiled.errors, errMsg => {
|
||||||
|
@ -6,11 +6,7 @@ import * as Web3 from 'web3';
|
|||||||
import { Contract } from './utils/contract';
|
import { Contract } from './utils/contract';
|
||||||
import { encoder } from './utils/encoder';
|
import { encoder } from './utils/encoder';
|
||||||
import { fsWrapper } from './utils/fs_wrapper';
|
import { fsWrapper } from './utils/fs_wrapper';
|
||||||
import {
|
import { ContractArtifact, ContractData, DeployerOptions } from './utils/types';
|
||||||
ContractArtifact,
|
|
||||||
ContractData,
|
|
||||||
DeployerOptions,
|
|
||||||
} from './utils/types';
|
|
||||||
import { utils } from './utils/utils';
|
import { utils } from './utils/utils';
|
||||||
|
|
||||||
// Gas added to gas estimate to make sure there is sufficient gas for deployment.
|
// Gas added to gas estimate to make sure there is sufficient gas for deployment.
|
||||||
@ -99,8 +95,11 @@ export class Deployer {
|
|||||||
* @param contractAddress Contract address to save to artifact.
|
* @param contractAddress Contract address to save to artifact.
|
||||||
* @param args Contract constructor arguments that will be encoded and saved to artifact.
|
* @param args Contract constructor arguments that will be encoded and saved to artifact.
|
||||||
*/
|
*/
|
||||||
private async _saveContractDataToArtifactAsync(contractName: string,
|
private async _saveContractDataToArtifactAsync(
|
||||||
contractAddress: string, args: any[]): Promise<void> {
|
contractName: string,
|
||||||
|
contractAddress: string,
|
||||||
|
args: any[],
|
||||||
|
): Promise<void> {
|
||||||
const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
|
const contractArtifact: ContractArtifact = this._loadContractArtifactIfExists(contractName);
|
||||||
const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
|
const contractData: ContractData = this._getContractDataFromArtifactIfExists(contractArtifact);
|
||||||
const abi = contractData.abi;
|
const abi = contractData.abi;
|
||||||
|
File diff suppressed because one or more lines are too long
@ -1,11 +1,6 @@
|
|||||||
import { Artifacts } from '../util/artifacts';
|
import { Artifacts } from '../util/artifacts';
|
||||||
import { MultiSigConfigByNetwork } from '../util/types';
|
import { MultiSigConfigByNetwork } from '../util/types';
|
||||||
const {
|
const { MultiSigWalletWithTimeLock, TokenTransferProxy, EtherToken, TokenRegistry } = new Artifacts(artifacts);
|
||||||
MultiSigWalletWithTimeLock,
|
|
||||||
TokenTransferProxy,
|
|
||||||
EtherToken,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
let multiSigConfigByNetwork: MultiSigConfigByNetwork;
|
let multiSigConfigByNetwork: MultiSigConfigByNetwork;
|
||||||
try {
|
try {
|
||||||
@ -25,13 +20,15 @@ module.exports = (deployer: any, network: string, accounts: string[]) => {
|
|||||||
};
|
};
|
||||||
const config = multiSigConfigByNetwork[network] || defaultConfig;
|
const config = multiSigConfigByNetwork[network] || defaultConfig;
|
||||||
if (network !== 'live') {
|
if (network !== 'live') {
|
||||||
deployer.deploy(MultiSigWalletWithTimeLock, config.owners,
|
deployer
|
||||||
config.confirmationsRequired, config.secondsRequired)
|
.deploy(MultiSigWalletWithTimeLock, config.owners, config.confirmationsRequired, config.secondsRequired)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return deployer.deploy(TokenTransferProxy);
|
return deployer.deploy(TokenTransferProxy);
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
return deployer.deploy(TokenRegistry);
|
return deployer.deploy(TokenRegistry);
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
return deployer.deploy(EtherToken);
|
return deployer.deploy(EtherToken);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -6,26 +6,21 @@ import {constants} from '../util/constants';
|
|||||||
import { ContractInstance, Token } from '../util/types';
|
import { ContractInstance, Token } from '../util/types';
|
||||||
|
|
||||||
import { tokenInfo } from './config/token_info';
|
import { tokenInfo } from './config/token_info';
|
||||||
const {
|
const { DummyToken, EtherToken, ZRXToken, TokenRegistry } = new Artifacts(artifacts);
|
||||||
DummyToken,
|
|
||||||
EtherToken,
|
|
||||||
ZRXToken,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
module.exports = (deployer: any, network: string) => {
|
module.exports = (deployer: any, network: string) => {
|
||||||
const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development;
|
const tokens = network === 'live' ? tokenInfo.live : tokenInfo.development;
|
||||||
deployer.then(() => {
|
deployer
|
||||||
|
.then(() => {
|
||||||
return TokenRegistry.deployed();
|
return TokenRegistry.deployed();
|
||||||
}).then((tokenRegistry: ContractInstance) => {
|
})
|
||||||
|
.then((tokenRegistry: ContractInstance) => {
|
||||||
if (network !== 'live') {
|
if (network !== 'live') {
|
||||||
const totalSupply = Math.pow(10, 18) * 1000000000;
|
const totalSupply = Math.pow(10, 18) * 1000000000;
|
||||||
return Bluebird.each(tokens.map((token: Token) => DummyToken.new(
|
return Bluebird.each(
|
||||||
token.name,
|
tokens.map((token: Token) => DummyToken.new(token.name, token.symbol, token.decimals, totalSupply)),
|
||||||
token.symbol,
|
_.noop,
|
||||||
token.decimals,
|
).then((dummyTokens: ContractInstance[]) => {
|
||||||
totalSupply,
|
|
||||||
)), _.noop).then((dummyTokens: ContractInstance[]) => {
|
|
||||||
const weth = {
|
const weth = {
|
||||||
address: EtherToken.address,
|
address: EtherToken.address,
|
||||||
name: 'Ether Token',
|
name: 'Ether Token',
|
||||||
@ -35,7 +30,9 @@ module.exports = (deployer: any, network: string) => {
|
|||||||
ipfsHash: constants.NULL_BYTES,
|
ipfsHash: constants.NULL_BYTES,
|
||||||
swarmHash: constants.NULL_BYTES,
|
swarmHash: constants.NULL_BYTES,
|
||||||
};
|
};
|
||||||
return Bluebird.each(dummyTokens.map((tokenContract: ContractInstance, i: number) => {
|
return Bluebird.each(
|
||||||
|
dummyTokens
|
||||||
|
.map((tokenContract: ContractInstance, i: number) => {
|
||||||
const token = tokens[i];
|
const token = tokens[i];
|
||||||
return tokenRegistry.addToken(
|
return tokenRegistry.addToken(
|
||||||
tokenContract.address,
|
tokenContract.address,
|
||||||
@ -45,14 +42,19 @@ module.exports = (deployer: any, network: string) => {
|
|||||||
token.ipfsHash,
|
token.ipfsHash,
|
||||||
token.swarmHash,
|
token.swarmHash,
|
||||||
);
|
);
|
||||||
}).concat(tokenRegistry.addToken(
|
})
|
||||||
|
.concat(
|
||||||
|
tokenRegistry.addToken(
|
||||||
weth.address,
|
weth.address,
|
||||||
weth.name,
|
weth.name,
|
||||||
weth.symbol,
|
weth.symbol,
|
||||||
weth.decimals,
|
weth.decimals,
|
||||||
weth.ipfsHash,
|
weth.ipfsHash,
|
||||||
weth.swarmHash,
|
weth.swarmHash,
|
||||||
)), _.noop);
|
),
|
||||||
|
),
|
||||||
|
_.noop,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const zrx = {
|
const zrx = {
|
||||||
@ -64,7 +66,9 @@ module.exports = (deployer: any, network: string) => {
|
|||||||
ipfsHash: constants.NULL_BYTES,
|
ipfsHash: constants.NULL_BYTES,
|
||||||
swarmHash: constants.NULL_BYTES,
|
swarmHash: constants.NULL_BYTES,
|
||||||
};
|
};
|
||||||
return Bluebird.each(tokens.map((token: Token) => {
|
return Bluebird.each(
|
||||||
|
tokens
|
||||||
|
.map((token: Token) => {
|
||||||
return tokenRegistry.addToken(
|
return tokenRegistry.addToken(
|
||||||
token.address,
|
token.address,
|
||||||
token.name,
|
token.name,
|
||||||
@ -73,14 +77,19 @@ module.exports = (deployer: any, network: string) => {
|
|||||||
token.ipfsHash,
|
token.ipfsHash,
|
||||||
token.swarmHash,
|
token.swarmHash,
|
||||||
);
|
);
|
||||||
}).concat(tokenRegistry.addToken(
|
})
|
||||||
|
.concat(
|
||||||
|
tokenRegistry.addToken(
|
||||||
zrx.address,
|
zrx.address,
|
||||||
zrx.name,
|
zrx.name,
|
||||||
zrx.symbol,
|
zrx.symbol,
|
||||||
zrx.decimals,
|
zrx.decimals,
|
||||||
zrx.ipfsHash,
|
zrx.ipfsHash,
|
||||||
zrx.swarmHash,
|
zrx.swarmHash,
|
||||||
)), _.noop);
|
),
|
||||||
|
),
|
||||||
|
_.noop,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,12 @@
|
|||||||
import { Artifacts } from '../util/artifacts';
|
import { Artifacts } from '../util/artifacts';
|
||||||
import { ContractInstance } from '../util/types';
|
import { ContractInstance } from '../util/types';
|
||||||
const {
|
const { TokenTransferProxy, Exchange, TokenRegistry } = new Artifacts(artifacts);
|
||||||
TokenTransferProxy,
|
|
||||||
Exchange,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
let tokenTransferProxy: ContractInstance;
|
let tokenTransferProxy: ContractInstance;
|
||||||
module.exports = (deployer: any) => {
|
module.exports = (deployer: any) => {
|
||||||
deployer.then(async () => {
|
deployer
|
||||||
return Promise.all([
|
.then(async () => {
|
||||||
TokenTransferProxy.deployed(),
|
return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()]);
|
||||||
TokenRegistry.deployed(),
|
|
||||||
]);
|
|
||||||
})
|
})
|
||||||
.then((instances: ContractInstance[]) => {
|
.then((instances: ContractInstance[]) => {
|
||||||
let tokenRegistry: ContractInstance;
|
let tokenRegistry: ContractInstance;
|
||||||
@ -21,7 +15,8 @@ module.exports = (deployer: any) => {
|
|||||||
})
|
})
|
||||||
.then((ptAddress: string) => {
|
.then((ptAddress: string) => {
|
||||||
return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address);
|
return deployer.deploy(Exchange, ptAddress, tokenTransferProxy.address);
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
return tokenTransferProxy.addAuthorizedAddress(Exchange.address);
|
return tokenTransferProxy.addAuthorizedAddress(Exchange.address);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,23 +1,18 @@
|
|||||||
import { Artifacts } from '../util/artifacts';
|
import { Artifacts } from '../util/artifacts';
|
||||||
import { ContractInstance } from '../util/types';
|
import { ContractInstance } from '../util/types';
|
||||||
const {
|
const { TokenTransferProxy, MultiSigWalletWithTimeLock, TokenRegistry } = new Artifacts(artifacts);
|
||||||
TokenTransferProxy,
|
|
||||||
MultiSigWalletWithTimeLock,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
let tokenRegistry: ContractInstance;
|
let tokenRegistry: ContractInstance;
|
||||||
module.exports = (deployer: any, network: string) => {
|
module.exports = (deployer: any, network: string) => {
|
||||||
if (network !== 'development') {
|
if (network !== 'development') {
|
||||||
deployer.then(async () => {
|
deployer.then(async () => {
|
||||||
return Promise.all([
|
return Promise.all([TokenTransferProxy.deployed(), TokenRegistry.deployed()])
|
||||||
TokenTransferProxy.deployed(),
|
.then((instances: ContractInstance[]) => {
|
||||||
TokenRegistry.deployed(),
|
|
||||||
]).then((instances: ContractInstance[]) => {
|
|
||||||
let tokenTransferProxy: ContractInstance;
|
let tokenTransferProxy: ContractInstance;
|
||||||
[tokenTransferProxy, tokenRegistry] = instances;
|
[tokenTransferProxy, tokenRegistry] = instances;
|
||||||
return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address);
|
return tokenTransferProxy.transferOwnership(MultiSigWalletWithTimeLock.address);
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address);
|
return tokenRegistry.transferOwnership(MultiSigWalletWithTimeLock.address);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -44,8 +44,9 @@ contract('EtherToken', (accounts: string[]) => {
|
|||||||
const initEthBalance = await getEthBalanceAsync(account);
|
const initEthBalance = await getEthBalanceAsync(account);
|
||||||
const ethToDeposit = initEthBalance.plus(1);
|
const ethToDeposit = initEthBalance.plus(1);
|
||||||
|
|
||||||
return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account))
|
return expect(zeroEx.etherToken.depositAsync(etherTokenAddress, ethToDeposit, account)).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
|
ZeroExError.InsufficientEthBalanceForDeposit,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should convert deposited Ether to wrapped Ether tokens', async () => {
|
it('should convert deposited Ether to wrapped Ether tokens', async () => {
|
||||||
@ -71,8 +72,9 @@ contract('EtherToken', (accounts: string[]) => {
|
|||||||
const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
|
const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
|
||||||
const ethTokensToWithdraw = initEthTokenBalance.plus(1);
|
const ethTokensToWithdraw = initEthTokenBalance.plus(1);
|
||||||
|
|
||||||
return expect(zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account))
|
return expect(
|
||||||
.to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
|
zeroEx.etherToken.withdrawAsync(etherTokenAddress, ethTokensToWithdraw, account),
|
||||||
|
).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should convert ether tokens to ether with sufficient balance', async () => {
|
it('should convert ether tokens to ether with sufficient balance', async () => {
|
||||||
@ -89,8 +91,9 @@ contract('EtherToken', (accounts: string[]) => {
|
|||||||
const finalEthBalance = await getEthBalanceAsync(account);
|
const finalEthBalance = await getEthBalanceAsync(account);
|
||||||
const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
|
const finalEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account);
|
||||||
|
|
||||||
expect(finalEthBalance).to.be.bignumber
|
expect(finalEthBalance).to.be.bignumber.equal(
|
||||||
.equal(initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)));
|
initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)),
|
||||||
|
);
|
||||||
expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
|
expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,13 +16,7 @@ import {chaiSetup} from '../utils/chai_setup';
|
|||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
const {
|
const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry, MaliciousToken } = new Artifacts(artifacts);
|
||||||
Exchange,
|
|
||||||
TokenTransferProxy,
|
|
||||||
DummyToken,
|
|
||||||
TokenRegistry,
|
|
||||||
MaliciousToken,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
// In order to benefit from type-safety, we re-assign the global web3 instance injected by Truffle
|
// In order to benefit from type-safety, we re-assign the global web3 instance injected by Truffle
|
||||||
// with type `any` to a variable of type `Web3`.
|
// with type `any` to a variable of type `Web3`.
|
||||||
@ -52,10 +46,7 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
let zeroEx: ZeroEx;
|
let zeroEx: ZeroEx;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
[tokenRegistry, exchange] = await Promise.all([
|
[tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
|
||||||
TokenRegistry.deployed(),
|
|
||||||
Exchange.deployed(),
|
|
||||||
]);
|
|
||||||
exWrapper = new ExchangeWrapper(exchange);
|
exWrapper = new ExchangeWrapper(exchange);
|
||||||
zeroEx = new ZeroEx(web3.currentProvider, {
|
zeroEx = new ZeroEx(web3.currentProvider, {
|
||||||
exchangeContractAddress: exchange.address,
|
exchangeContractAddress: exchange.address,
|
||||||
@ -88,16 +79,28 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
]);
|
]);
|
||||||
dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
|
dmyBalances = new Balances([rep, dgd, zrx], [maker, taker, feeRecipient]);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: maker}),
|
rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: taker}),
|
from: maker,
|
||||||
|
}),
|
||||||
|
rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: taker,
|
||||||
|
}),
|
||||||
rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
|
rep.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
|
||||||
rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
|
rep.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
|
||||||
dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: maker}),
|
dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: taker}),
|
from: maker,
|
||||||
|
}),
|
||||||
|
dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: taker,
|
||||||
|
}),
|
||||||
dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
|
dgd.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
|
||||||
dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
|
dgd.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
|
||||||
zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: maker}),
|
zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: taker}),
|
from: maker,
|
||||||
|
}),
|
||||||
|
zrx.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: taker,
|
||||||
|
}),
|
||||||
zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
|
zrx.setBalance(maker, INITIAL_BALANCE, { from: tokenOwner }),
|
||||||
zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
|
zrx.setBalance(taker, INITIAL_BALANCE, { from: tokenOwner }),
|
||||||
]);
|
]);
|
||||||
@ -133,22 +136,29 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerTokenAmount: new BigNumber(3),
|
takerTokenAmount: new BigNumber(3),
|
||||||
});
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountBefore =
|
const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
const fillTakerTokenAmount1 = new BigNumber(2);
|
const fillTakerTokenAmount1 = new BigNumber(2);
|
||||||
await exWrapper.fillOrderAsync(order, taker, {fillTakerTokenAmount: fillTakerTokenAmount1});
|
await exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
fillTakerTokenAmount: fillTakerTokenAmount1,
|
||||||
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountAfter1 =
|
const filledTakerTokenAmountAfter1 = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1);
|
expect(filledTakerTokenAmountAfter1).to.be.bignumber.equal(fillTakerTokenAmount1);
|
||||||
|
|
||||||
const fillTakerTokenAmount2 = new BigNumber(1);
|
const fillTakerTokenAmount2 = new BigNumber(1);
|
||||||
await exWrapper.fillOrderAsync(order, taker, {fillTakerTokenAmount: fillTakerTokenAmount2});
|
await exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
fillTakerTokenAmount: fillTakerTokenAmount2,
|
||||||
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountAfter2 =
|
const filledTakerTokenAmountAfter2 = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1);
|
expect(filledTakerTokenAmountAfter2).to.be.bignumber.equal(filledTakerTokenAmountAfter1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -158,15 +168,17 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountBefore =
|
const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
||||||
|
|
||||||
const filledTakerTokenAmountAfter =
|
const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
|
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
@ -180,20 +192,27 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
const paidTakerFee = order.params.takerFee
|
const paidTakerFee = order.params.takerFee
|
||||||
.times(fillMakerTokenAmount)
|
.times(fillMakerTokenAmount)
|
||||||
.dividedToIntegerBy(order.params.makerTokenAmount);
|
.dividedToIntegerBy(order.params.makerTokenAmount);
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(fillMakerTokenAmount));
|
balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(fillTakerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address]).to.be.bignumber
|
balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
|
||||||
.equal(balances[maker][zrx.address].minus(paidMakerFee));
|
);
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(fillTakerTokenAmount));
|
balances[maker][zrx.address].minus(paidMakerFee),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(fillMakerTokenAmount));
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber
|
balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
|
||||||
.equal(balances[taker][zrx.address].minus(paidTakerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)));
|
balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(paidTakerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transfer the correct amounts when makerTokenAmount > takerTokenAmount', async () => {
|
it('should transfer the correct amounts when makerTokenAmount > takerTokenAmount', async () => {
|
||||||
@ -202,15 +221,17 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountBefore =
|
const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
||||||
|
|
||||||
const filledTakerTokenAmountAfter =
|
const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
|
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
@ -224,20 +245,27 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
const paidTakerFee = order.params.takerFee
|
const paidTakerFee = order.params.takerFee
|
||||||
.times(fillMakerTokenAmount)
|
.times(fillMakerTokenAmount)
|
||||||
.dividedToIntegerBy(order.params.makerTokenAmount);
|
.dividedToIntegerBy(order.params.makerTokenAmount);
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(fillMakerTokenAmount));
|
balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(fillTakerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address]).to.be.bignumber
|
balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
|
||||||
.equal(balances[maker][zrx.address].minus(paidMakerFee));
|
);
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(fillTakerTokenAmount));
|
balances[maker][zrx.address].minus(paidMakerFee),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(fillMakerTokenAmount));
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber
|
balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
|
||||||
.equal(balances[taker][zrx.address].minus(paidTakerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)));
|
balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(paidTakerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transfer the correct amounts when makerTokenAmount < takerTokenAmount', async () => {
|
it('should transfer the correct amounts when makerTokenAmount < takerTokenAmount', async () => {
|
||||||
@ -246,15 +274,17 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountBefore =
|
const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
||||||
|
|
||||||
const filledTakerTokenAmountAfter =
|
const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
|
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(fillTakerTokenAmount);
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
@ -268,20 +298,27 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
const paidTakerFee = order.params.takerFee
|
const paidTakerFee = order.params.takerFee
|
||||||
.times(fillMakerTokenAmount)
|
.times(fillMakerTokenAmount)
|
||||||
.dividedToIntegerBy(order.params.makerTokenAmount);
|
.dividedToIntegerBy(order.params.makerTokenAmount);
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(fillMakerTokenAmount));
|
balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(fillTakerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address]).to.be.bignumber
|
balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
|
||||||
.equal(balances[maker][zrx.address].minus(paidMakerFee));
|
);
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(fillTakerTokenAmount));
|
balances[maker][zrx.address].minus(paidMakerFee),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(fillMakerTokenAmount));
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber
|
balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
|
||||||
.equal(balances[taker][zrx.address].minus(paidTakerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)));
|
balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(paidTakerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transfer the correct amounts when taker is specified and order is claimed by taker', async () => {
|
it('should transfer the correct amounts when taker is specified and order is claimed by taker', async () => {
|
||||||
@ -291,15 +328,17 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
const filledTakerTokenAmountBefore =
|
const filledTakerTokenAmountBefore = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
expect(filledTakerTokenAmountBefore).to.be.bignumber.equal(0);
|
||||||
|
|
||||||
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
||||||
|
|
||||||
const filledTakerTokenAmountAfter =
|
const filledTakerTokenAmountAfter = await zeroEx.exchange.getFilledTakerAmountAsync(
|
||||||
await zeroEx.exchange.getFilledTakerAmountAsync(order.params.orderHashHex);
|
order.params.orderHashHex,
|
||||||
|
);
|
||||||
const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore);
|
const expectedFillAmountTAfter = fillTakerTokenAmount.add(filledTakerTokenAmountBefore);
|
||||||
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter);
|
expect(filledTakerTokenAmountAfter).to.be.bignumber.equal(expectedFillAmountTAfter);
|
||||||
|
|
||||||
@ -314,55 +353,70 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
const paidTakerFee = order.params.takerFee
|
const paidTakerFee = order.params.takerFee
|
||||||
.times(fillMakerTokenAmount)
|
.times(fillMakerTokenAmount)
|
||||||
.dividedToIntegerBy(order.params.makerTokenAmount);
|
.dividedToIntegerBy(order.params.makerTokenAmount);
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(fillMakerTokenAmount));
|
balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(fillTakerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address]).to.be.bignumber
|
balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
|
||||||
.equal(balances[maker][zrx.address].minus(paidMakerFee));
|
);
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(fillTakerTokenAmount));
|
balances[maker][zrx.address].minus(paidMakerFee),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(fillMakerTokenAmount));
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber
|
balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
|
||||||
.equal(balances[taker][zrx.address].minus(paidTakerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)));
|
balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(paidTakerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill remaining value if fillTakerTokenAmount > remaining takerTokenAmount', async () => {
|
it('should fill remaining value if fillTakerTokenAmount > remaining takerTokenAmount', async () => {
|
||||||
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
await exWrapper.fillOrderAsync(order, taker, { fillTakerTokenAmount });
|
||||||
|
|
||||||
const res = await exWrapper.fillOrderAsync(order, taker,
|
const res = await exWrapper.fillOrderAsync(order, taker, {
|
||||||
{fillTakerTokenAmount: order.params.takerTokenAmount});
|
fillTakerTokenAmount: order.params.takerTokenAmount,
|
||||||
|
});
|
||||||
|
|
||||||
expect(res.logs[0].args.filledTakerTokenAmount)
|
expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(order.params.takerTokenAmount.minus(fillTakerTokenAmount));
|
order.params.takerTokenAmount.minus(fillTakerTokenAmount),
|
||||||
|
);
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
|
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(order.params.makerTokenAmount));
|
balances[maker][order.params.makerToken].minus(order.params.makerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(order.params.takerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address])
|
balances[maker][order.params.takerToken].add(order.params.takerTokenAmount),
|
||||||
.to.be.bignumber.equal(balances[maker][zrx.address].minus(order.params.makerFee));
|
);
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(order.params.takerTokenAmount));
|
balances[maker][zrx.address].minus(order.params.makerFee),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(order.params.makerTokenAmount));
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address])
|
balances[taker][order.params.takerToken].minus(order.params.takerTokenAmount),
|
||||||
.to.be.bignumber.equal(balances[taker][zrx.address].minus(order.params.takerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(
|
balances[taker][order.params.makerToken].add(order.params.makerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(order.params.takerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee)),
|
balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee)),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log 1 event with the correct arguments when order has a feeRecipient', async () => {
|
it('should log 1 event with the correct arguments when order has a feeRecipient', async () => {
|
||||||
const divisor = 2;
|
const divisor = 2;
|
||||||
const res = await exWrapper.fillOrderAsync(order, taker,
|
const res = await exWrapper.fillOrderAsync(order, taker, {
|
||||||
{fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor)});
|
fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
|
||||||
|
});
|
||||||
expect(res.logs).to.have.length(1);
|
expect(res.logs).to.have.length(1);
|
||||||
|
|
||||||
const logArgs = res.logs[0].args;
|
const logArgs = res.logs[0].args;
|
||||||
@ -391,8 +445,9 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
feeRecipient: ZeroEx.NULL_ADDRESS,
|
feeRecipient: ZeroEx.NULL_ADDRESS,
|
||||||
});
|
});
|
||||||
const divisor = 2;
|
const divisor = 2;
|
||||||
const res = await exWrapper.fillOrderAsync(order, taker,
|
const res = await exWrapper.fillOrderAsync(order, taker, {
|
||||||
{fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor)});
|
fillTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
|
||||||
|
});
|
||||||
expect(res.logs).to.have.length(1);
|
expect(res.logs).to.have.length(1);
|
||||||
|
|
||||||
const logArgs = res.logs[0].args;
|
const logArgs = res.logs[0].args;
|
||||||
@ -455,13 +510,15 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
it('should throw if fillTakerTokenAmount is 0', async () => {
|
it('should throw if fillTakerTokenAmount is 0', async () => {
|
||||||
order = await orderFactory.newSignedOrderAsync();
|
order = await orderFactory.newSignedOrderAsync();
|
||||||
|
|
||||||
return expect(exWrapper.fillOrderAsync(order, taker, {fillTakerTokenAmount: new BigNumber(0)}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
fillTakerTokenAmount: new BigNumber(0),
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if maker balances are too low to fill order and \
|
it('should not change balances if maker balances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = false',
|
shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||||
});
|
});
|
||||||
@ -472,19 +529,20 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if maker balances are too low to fill order and \
|
it('should throw if maker balances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = true',
|
shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
|
||||||
async () => {
|
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
makerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(exWrapper.fillOrderAsync(order, taker, {shouldThrowOnInsufficientBalanceOrAllowance: true}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance: true,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if taker balances are too low to fill order and \
|
it('should not change balances if taker balances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = false',
|
shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||||
});
|
});
|
||||||
@ -495,59 +553,70 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if taker balances are too low to fill order and \
|
it('should throw if taker balances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = true',
|
shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
|
||||||
async () => {
|
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(exWrapper.fillOrderAsync(order, taker, {shouldThrowOnInsufficientBalanceOrAllowance: true}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance: true,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if maker allowances are too low to fill order and \
|
it('should not change balances if maker allowances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = false',
|
shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
await rep.approve(TokenTransferProxy.address, 0, { from: maker });
|
await rep.approve(TokenTransferProxy.address, 0, { from: maker });
|
||||||
await exWrapper.fillOrderAsync(order, taker);
|
await exWrapper.fillOrderAsync(order, taker);
|
||||||
await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: maker});
|
await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: maker,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances).to.be.deep.equal(balances);
|
expect(newBalances).to.be.deep.equal(balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if maker allowances are too low to fill order and \
|
it('should throw if maker allowances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = true',
|
shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
|
||||||
async () => {
|
|
||||||
await rep.approve(TokenTransferProxy.address, 0, { from: maker });
|
await rep.approve(TokenTransferProxy.address, 0, { from: maker });
|
||||||
expect(exWrapper.fillOrderAsync(order, taker, {shouldThrowOnInsufficientBalanceOrAllowance: true}))
|
expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.fillOrderAsync(order, taker, {
|
||||||
await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: maker});
|
shouldThrowOnInsufficientBalanceOrAllowance: true,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
|
await rep.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: maker,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if taker allowances are too low to fill order and \
|
it('should not change balances if taker allowances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = false',
|
shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
|
await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
|
||||||
await exWrapper.fillOrderAsync(order, taker);
|
await exWrapper.fillOrderAsync(order, taker);
|
||||||
await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: taker});
|
await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: taker,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances).to.be.deep.equal(balances);
|
expect(newBalances).to.be.deep.equal(balances);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if taker allowances are too low to fill order and \
|
it('should throw if taker allowances are too low to fill order and \
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance = true',
|
shouldThrowOnInsufficientBalanceOrAllowance = true', async () => {
|
||||||
async () => {
|
|
||||||
await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
|
await dgd.approve(TokenTransferProxy.address, 0, { from: taker });
|
||||||
expect(exWrapper.fillOrderAsync(order, taker, {shouldThrowOnInsufficientBalanceOrAllowance: true}))
|
expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.fillOrderAsync(order, taker, {
|
||||||
await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {from: taker});
|
shouldThrowOnInsufficientBalanceOrAllowance: true,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
|
await dgd.approve(TokenTransferProxy.address, INITIAL_ALLOWANCE, {
|
||||||
|
from: taker,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker balance, \
|
it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker balance, \
|
||||||
and shouldThrowOnInsufficientBalanceOrAllowance = false',
|
and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
const makerZRXBalance = new BigNumber(balances[maker][zrx.address]);
|
const makerZRXBalance = new BigNumber(balances[maker][zrx.address]);
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
makerToken: zrx.address,
|
makerToken: zrx.address,
|
||||||
@ -560,8 +629,7 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \
|
it('should not change balances if makerToken is ZRX, makerTokenAmount + makerFee > maker allowance, \
|
||||||
and shouldThrowOnInsufficientBalanceOrAllowance = false',
|
and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address);
|
const makerZRXAllowance = await zrx.allowance(maker, TokenTransferProxy.address);
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
makerToken: zrx.address,
|
makerToken: zrx.address,
|
||||||
@ -574,8 +642,7 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker balance, \
|
it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker balance, \
|
||||||
and shouldThrowOnInsufficientBalanceOrAllowance = false',
|
and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
const takerZRXBalance = new BigNumber(balances[taker][zrx.address]);
|
const takerZRXBalance = new BigNumber(balances[taker][zrx.address]);
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
takerToken: zrx.address,
|
takerToken: zrx.address,
|
||||||
@ -588,8 +655,7 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \
|
it('should not change balances if takerToken is ZRX, takerTokenAmount + takerFee > taker allowance, \
|
||||||
and shouldThrowOnInsufficientBalanceOrAllowance = false',
|
and shouldThrowOnInsufficientBalanceOrAllowance = false', async () => {
|
||||||
async () => {
|
|
||||||
const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address);
|
const takerZRXAllowance = await zrx.allowance(taker, TokenTransferProxy.address);
|
||||||
order = await orderFactory.newSignedOrderAsync({
|
order = await orderFactory.newSignedOrderAsync({
|
||||||
takerToken: zrx.address,
|
takerToken: zrx.address,
|
||||||
@ -610,8 +676,11 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerToken: maliciousToken.address,
|
takerToken: maliciousToken.address,
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(exWrapper.fillOrderAsync(order, taker, {shouldThrowOnInsufficientBalanceOrAllowance: false}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance: false,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not change balances if an order is expired', async () => {
|
it('should not change balances if an order is expired', async () => {
|
||||||
@ -674,13 +743,18 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
it('should throw if cancelTakerTokenAmount is 0', async () => {
|
it('should throw if cancelTakerTokenAmount is 0', async () => {
|
||||||
order = await orderFactory.newSignedOrderAsync();
|
order = await orderFactory.newSignedOrderAsync();
|
||||||
|
|
||||||
return expect(exWrapper.cancelOrderAsync(order, maker, {cancelTakerTokenAmount: new BigNumber(0)}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.cancelOrderAsync(order, maker, {
|
||||||
|
cancelTakerTokenAmount: new BigNumber(0),
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to cancel a full order', async () => {
|
it('should be able to cancel a full order', async () => {
|
||||||
await exWrapper.cancelOrderAsync(order, maker);
|
await exWrapper.cancelOrderAsync(order, maker);
|
||||||
await exWrapper.fillOrderAsync(order, taker, {fillTakerTokenAmount: order.params.takerTokenAmount.div(2)});
|
await exWrapper.fillOrderAsync(order, taker, {
|
||||||
|
fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances).to.be.deep.equal(balances);
|
expect(newBalances).to.be.deep.equal(balances);
|
||||||
@ -688,12 +762,16 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
|
|
||||||
it('should be able to cancel part of an order', async () => {
|
it('should be able to cancel part of an order', async () => {
|
||||||
const cancelTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const cancelTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.cancelOrderAsync(order, maker, {cancelTakerTokenAmount});
|
await exWrapper.cancelOrderAsync(order, maker, {
|
||||||
|
cancelTakerTokenAmount,
|
||||||
|
});
|
||||||
|
|
||||||
const res = await exWrapper.fillOrderAsync(order, taker,
|
const res = await exWrapper.fillOrderAsync(order, taker, {
|
||||||
{fillTakerTokenAmount: order.params.takerTokenAmount});
|
fillTakerTokenAmount: order.params.takerTokenAmount,
|
||||||
expect(res.logs[0].args.filledTakerTokenAmount)
|
});
|
||||||
.to.be.bignumber.equal(order.params.takerTokenAmount.minus(cancelTakerTokenAmount));
|
expect(res.logs[0].args.filledTakerTokenAmount).to.be.bignumber.equal(
|
||||||
|
order.params.takerTokenAmount.minus(cancelTakerTokenAmount),
|
||||||
|
);
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
const cancelMakerTokenAmount = cancelTakerTokenAmount
|
const cancelMakerTokenAmount = cancelTakerTokenAmount
|
||||||
@ -705,26 +783,34 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
const paidTakerFee = order.params.takerFee
|
const paidTakerFee = order.params.takerFee
|
||||||
.times(cancelMakerTokenAmount)
|
.times(cancelMakerTokenAmount)
|
||||||
.dividedToIntegerBy(order.params.makerTokenAmount);
|
.dividedToIntegerBy(order.params.makerTokenAmount);
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(cancelMakerTokenAmount));
|
balances[maker][order.params.makerToken].minus(cancelMakerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(cancelTakerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address])
|
balances[maker][order.params.takerToken].add(cancelTakerTokenAmount),
|
||||||
.to.be.bignumber.equal(balances[maker][zrx.address].minus(paidMakerFee));
|
);
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(cancelTakerTokenAmount));
|
balances[maker][zrx.address].minus(paidMakerFee),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(cancelMakerTokenAmount));
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber
|
balances[taker][order.params.takerToken].minus(cancelTakerTokenAmount),
|
||||||
.equal(balances[taker][zrx.address].minus(paidTakerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)));
|
balances[taker][order.params.makerToken].add(cancelMakerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(paidTakerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[feeRecipient][zrx.address].add(paidMakerFee.add(paidTakerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should log 1 event with correct arguments', async () => {
|
it('should log 1 event with correct arguments', async () => {
|
||||||
const divisor = 2;
|
const divisor = 2;
|
||||||
const res = await exWrapper.cancelOrderAsync(order, maker,
|
const res = await exWrapper.cancelOrderAsync(order, maker, {
|
||||||
{cancelTakerTokenAmount: order.params.takerTokenAmount.div(divisor)});
|
cancelTakerTokenAmount: order.params.takerTokenAmount.div(divisor),
|
||||||
|
});
|
||||||
expect(res.logs).to.have.length(1);
|
expect(res.logs).to.have.length(1);
|
||||||
|
|
||||||
const logArgs = res.logs[0].args;
|
const logArgs = res.logs[0].args;
|
||||||
|
@ -12,10 +12,7 @@ import {chaiSetup} from '../utils/chai_setup';
|
|||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
|
|
||||||
const {
|
const { Exchange, TokenRegistry } = new Artifacts(artifacts);
|
||||||
Exchange,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
contract('Exchange', (accounts: string[]) => {
|
contract('Exchange', (accounts: string[]) => {
|
||||||
const maker = accounts[0];
|
const maker = accounts[0];
|
||||||
@ -26,10 +23,7 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
let orderFactory: OrderFactory;
|
let orderFactory: OrderFactory;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
const [tokenRegistry, exchange] = await Promise.all([
|
const [tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
|
||||||
TokenRegistry.deployed(),
|
|
||||||
Exchange.deployed(),
|
|
||||||
]);
|
|
||||||
exchangeWrapper = new ExchangeWrapper(exchange);
|
exchangeWrapper = new ExchangeWrapper(exchange);
|
||||||
const [repAddress, dgdAddress] = await Promise.all([
|
const [repAddress, dgdAddress] = await Promise.all([
|
||||||
tokenRegistry.getTokenAddressBySymbol('REP'),
|
tokenRegistry.getTokenAddressBySymbol('REP'),
|
||||||
|
@ -14,12 +14,7 @@ import {chaiSetup} from '../utils/chai_setup';
|
|||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
const {
|
const { Exchange, TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts);
|
||||||
Exchange,
|
|
||||||
TokenTransferProxy,
|
|
||||||
DummyToken,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
contract('Exchange', (accounts: string[]) => {
|
contract('Exchange', (accounts: string[]) => {
|
||||||
const maker = accounts[0];
|
const maker = accounts[0];
|
||||||
@ -43,10 +38,7 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
let orderFactory: OrderFactory;
|
let orderFactory: OrderFactory;
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
[tokenRegistry, exchange] = await Promise.all([
|
[tokenRegistry, exchange] = await Promise.all([TokenRegistry.deployed(), Exchange.deployed()]);
|
||||||
TokenRegistry.deployed(),
|
|
||||||
Exchange.deployed(),
|
|
||||||
]);
|
|
||||||
exWrapper = new ExchangeWrapper(exchange);
|
exWrapper = new ExchangeWrapper(exchange);
|
||||||
const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
|
const [repAddress, dgdAddress, zrxAddress] = await Promise.all([
|
||||||
tokenRegistry.getTokenAddressBySymbol('REP'),
|
tokenRegistry.getTokenAddressBySymbol('REP'),
|
||||||
@ -100,7 +92,9 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
|
takerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
|
||||||
});
|
});
|
||||||
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
const fillTakerTokenAmount = order.params.takerTokenAmount.div(2);
|
||||||
await exWrapper.fillOrKillOrderAsync(order, taker, {fillTakerTokenAmount});
|
await exWrapper.fillOrKillOrderAsync(order, taker, {
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
|
|
||||||
@ -113,18 +107,23 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
const takerFee = order.params.takerFee
|
const takerFee = order.params.takerFee
|
||||||
.times(fillMakerTokenAmount)
|
.times(fillMakerTokenAmount)
|
||||||
.dividedToIntegerBy(order.params.makerTokenAmount);
|
.dividedToIntegerBy(order.params.makerTokenAmount);
|
||||||
expect(newBalances[maker][order.params.makerToken])
|
expect(newBalances[maker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.makerToken].minus(fillMakerTokenAmount));
|
balances[maker][order.params.makerToken].minus(fillMakerTokenAmount),
|
||||||
expect(newBalances[maker][order.params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][order.params.takerToken].add(fillTakerTokenAmount));
|
expect(newBalances[maker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
|
balances[maker][order.params.takerToken].add(fillTakerTokenAmount),
|
||||||
|
);
|
||||||
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(balances[maker][zrx.address].minus(makerFee));
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(balances[maker][zrx.address].minus(makerFee));
|
||||||
expect(newBalances[taker][order.params.takerToken])
|
expect(newBalances[taker][order.params.takerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.takerToken].minus(fillTakerTokenAmount));
|
balances[taker][order.params.takerToken].minus(fillTakerTokenAmount),
|
||||||
expect(newBalances[taker][order.params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][order.params.makerToken].add(fillMakerTokenAmount));
|
expect(newBalances[taker][order.params.makerToken]).to.be.bignumber.equal(
|
||||||
|
balances[taker][order.params.makerToken].add(fillMakerTokenAmount),
|
||||||
|
);
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(balances[taker][zrx.address].minus(takerFee));
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(balances[taker][zrx.address].minus(takerFee));
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)));
|
balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if an order is expired', async () => {
|
it('should throw if an order is expired', async () => {
|
||||||
@ -132,18 +131,18 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
expirationTimestampInSec: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
|
||||||
});
|
});
|
||||||
|
|
||||||
return expect(exWrapper.fillOrKillOrderAsync(order, taker))
|
return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if entire fillTakerTokenAmount not filled', async () => {
|
it('should throw if entire fillTakerTokenAmount not filled', async () => {
|
||||||
const order = await orderFactory.newSignedOrderAsync();
|
const order = await orderFactory.newSignedOrderAsync();
|
||||||
|
|
||||||
const from = taker;
|
const from = taker;
|
||||||
await exWrapper.fillOrderAsync(order, from, {fillTakerTokenAmount: order.params.takerTokenAmount.div(2)});
|
await exWrapper.fillOrderAsync(order, from, {
|
||||||
|
fillTakerTokenAmount: order.params.takerTokenAmount.div(2),
|
||||||
|
});
|
||||||
|
|
||||||
return expect(exWrapper.fillOrKillOrderAsync(order, taker))
|
return expect(exWrapper.fillOrKillOrderAsync(order, taker)).to.be.rejectedWith(constants.REVERT);
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -181,11 +180,14 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
|
balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
|
||||||
balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
|
balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
|
||||||
balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
|
balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
|
||||||
balances[feeRecipient][zrx.address] =
|
balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
|
||||||
balances[feeRecipient][zrx.address].add(makerFee.add(takerFee));
|
makerFee.add(takerFee),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await exWrapper.batchFillOrdersAsync(orders, taker, {fillTakerTokenAmounts});
|
await exWrapper.batchFillOrdersAsync(orders, taker, {
|
||||||
|
fillTakerTokenAmounts,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances).to.be.deep.equal(balances);
|
expect(newBalances).to.be.deep.equal(balances);
|
||||||
@ -215,11 +217,14 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
|
balances[taker][makerToken] = balances[taker][makerToken].add(fillMakerTokenAmount);
|
||||||
balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
|
balances[taker][takerToken] = balances[taker][takerToken].minus(fillTakerTokenAmount);
|
||||||
balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
|
balances[taker][zrx.address] = balances[taker][zrx.address].minus(takerFee);
|
||||||
balances[feeRecipient][zrx.address] =
|
balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
|
||||||
balances[feeRecipient][zrx.address].add(makerFee.add(takerFee));
|
makerFee.add(takerFee),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await exWrapper.batchFillOrKillOrdersAsync(orders, taker, {fillTakerTokenAmounts});
|
await exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
|
||||||
|
fillTakerTokenAmounts,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances).to.be.deep.equal(balances);
|
expect(newBalances).to.be.deep.equal(balances);
|
||||||
@ -234,57 +239,77 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
|
|
||||||
await exWrapper.fillOrKillOrderAsync(orders[0], taker);
|
await exWrapper.fillOrKillOrderAsync(orders[0], taker);
|
||||||
|
|
||||||
return expect(exWrapper.batchFillOrKillOrdersAsync(orders, taker, {fillTakerTokenAmounts}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
exWrapper.batchFillOrKillOrdersAsync(orders, taker, {
|
||||||
|
fillTakerTokenAmounts,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fillOrdersUpTo', () => {
|
describe('fillOrdersUpTo', () => {
|
||||||
it('should stop when the entire fillTakerTokenAmount is filled', async () => {
|
it('should stop when the entire fillTakerTokenAmount is filled', async () => {
|
||||||
const fillTakerTokenAmount =
|
const fillTakerTokenAmount = orders[0].params.takerTokenAmount.plus(
|
||||||
orders[0].params.takerTokenAmount.plus(orders[1].params.takerTokenAmount.div(2));
|
orders[1].params.takerTokenAmount.div(2),
|
||||||
await exWrapper.fillOrdersUpToAsync(orders, taker, {fillTakerTokenAmount});
|
);
|
||||||
|
await exWrapper.fillOrdersUpToAsync(orders, taker, {
|
||||||
|
fillTakerTokenAmount,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
|
|
||||||
const fillMakerTokenAmount = orders[0].params.makerTokenAmount.add(
|
const fillMakerTokenAmount = orders[0].params.makerTokenAmount.add(
|
||||||
orders[1].params.makerTokenAmount.dividedToIntegerBy(2));
|
orders[1].params.makerTokenAmount.dividedToIntegerBy(2),
|
||||||
|
);
|
||||||
const makerFee = orders[0].params.makerFee.add(orders[1].params.makerFee.dividedToIntegerBy(2));
|
const makerFee = orders[0].params.makerFee.add(orders[1].params.makerFee.dividedToIntegerBy(2));
|
||||||
const takerFee = orders[0].params.takerFee.add(orders[1].params.takerFee.dividedToIntegerBy(2));
|
const takerFee = orders[0].params.takerFee.add(orders[1].params.takerFee.dividedToIntegerBy(2));
|
||||||
expect(newBalances[maker][orders[0].params.makerToken])
|
expect(newBalances[maker][orders[0].params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[maker][orders[0].params.makerToken].minus(fillMakerTokenAmount));
|
balances[maker][orders[0].params.makerToken].minus(fillMakerTokenAmount),
|
||||||
expect(newBalances[maker][orders[0].params.takerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[maker][orders[0].params.takerToken].add(fillTakerTokenAmount));
|
expect(newBalances[maker][orders[0].params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[maker][zrx.address]).to.be.bignumber
|
balances[maker][orders[0].params.takerToken].add(fillTakerTokenAmount),
|
||||||
.equal(balances[maker][zrx.address].minus(makerFee));
|
);
|
||||||
expect(newBalances[taker][orders[0].params.takerToken])
|
expect(newBalances[maker][zrx.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[taker][orders[0].params.takerToken].minus(fillTakerTokenAmount));
|
balances[maker][zrx.address].minus(makerFee),
|
||||||
expect(newBalances[taker][orders[0].params.makerToken])
|
);
|
||||||
.to.be.bignumber.equal(balances[taker][orders[0].params.makerToken].add(fillMakerTokenAmount));
|
expect(newBalances[taker][orders[0].params.takerToken]).to.be.bignumber.equal(
|
||||||
expect(newBalances[taker][zrx.address]).to.be.bignumber
|
balances[taker][orders[0].params.takerToken].minus(fillTakerTokenAmount),
|
||||||
.equal(balances[taker][zrx.address].minus(takerFee));
|
);
|
||||||
expect(newBalances[feeRecipient][zrx.address])
|
expect(newBalances[taker][orders[0].params.makerToken]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)));
|
balances[taker][orders[0].params.makerToken].add(fillMakerTokenAmount),
|
||||||
|
);
|
||||||
|
expect(newBalances[taker][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[taker][zrx.address].minus(takerFee),
|
||||||
|
);
|
||||||
|
expect(newBalances[feeRecipient][zrx.address]).to.be.bignumber.equal(
|
||||||
|
balances[feeRecipient][zrx.address].add(makerFee.add(takerFee)),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill all orders if cannot fill entire fillTakerTokenAmount', async () => {
|
it('should fill all orders if cannot fill entire fillTakerTokenAmount', async () => {
|
||||||
const fillTakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18);
|
const fillTakerTokenAmount = ZeroEx.toBaseUnitAmount(new BigNumber(100000), 18);
|
||||||
orders.forEach(order => {
|
orders.forEach(order => {
|
||||||
balances[maker][order.params.makerToken] = balances[maker][order.params.makerToken]
|
balances[maker][order.params.makerToken] = balances[maker][order.params.makerToken].minus(
|
||||||
.minus(order.params.makerTokenAmount);
|
order.params.makerTokenAmount,
|
||||||
balances[maker][order.params.takerToken] = balances[maker][order.params.takerToken]
|
);
|
||||||
.add(order.params.takerTokenAmount);
|
balances[maker][order.params.takerToken] = balances[maker][order.params.takerToken].add(
|
||||||
balances[maker][zrx.address] = balances[maker][zrx.address]
|
order.params.takerTokenAmount,
|
||||||
.minus(order.params.makerFee);
|
);
|
||||||
balances[taker][order.params.makerToken] = balances[taker][order.params.makerToken]
|
balances[maker][zrx.address] = balances[maker][zrx.address].minus(order.params.makerFee);
|
||||||
.add(order.params.makerTokenAmount);
|
balances[taker][order.params.makerToken] = balances[taker][order.params.makerToken].add(
|
||||||
balances[taker][order.params.takerToken] = balances[taker][order.params.takerToken]
|
order.params.makerTokenAmount,
|
||||||
.minus(order.params.takerTokenAmount);
|
);
|
||||||
|
balances[taker][order.params.takerToken] = balances[taker][order.params.takerToken].minus(
|
||||||
|
order.params.takerTokenAmount,
|
||||||
|
);
|
||||||
balances[taker][zrx.address] = balances[taker][zrx.address].minus(order.params.takerFee);
|
balances[taker][zrx.address] = balances[taker][zrx.address].minus(order.params.takerFee);
|
||||||
balances[feeRecipient][zrx.address] =
|
balances[feeRecipient][zrx.address] = balances[feeRecipient][zrx.address].add(
|
||||||
balances[feeRecipient][zrx.address].add(order.params.makerFee.add(order.params.takerFee));
|
order.params.makerFee.add(order.params.takerFee),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await exWrapper.fillOrdersUpToAsync(orders, taker, {
|
||||||
|
fillTakerTokenAmount,
|
||||||
});
|
});
|
||||||
await exWrapper.fillOrdersUpToAsync(orders, taker, {fillTakerTokenAmount});
|
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances).to.be.deep.equal(balances);
|
expect(newBalances).to.be.deep.equal(balances);
|
||||||
@ -298,8 +323,9 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
return expect(
|
return expect(
|
||||||
exWrapper.fillOrdersUpToAsync(
|
exWrapper.fillOrdersUpToAsync(orders, taker, {
|
||||||
orders, taker, {fillTakerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(1000), 18)}),
|
fillTakerTokenAmount: ZeroEx.toBaseUnitAmount(new BigNumber(1000), 18),
|
||||||
|
}),
|
||||||
).to.be.rejectedWith(constants.REVERT);
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -307,10 +333,13 @@ contract('Exchange', (accounts: string[]) => {
|
|||||||
describe('batchCancelOrders', () => {
|
describe('batchCancelOrders', () => {
|
||||||
it('should be able to cancel multiple orders', async () => {
|
it('should be able to cancel multiple orders', async () => {
|
||||||
const cancelTakerTokenAmounts = _.map(orders, order => order.params.takerTokenAmount);
|
const cancelTakerTokenAmounts = _.map(orders, order => order.params.takerTokenAmount);
|
||||||
await exWrapper.batchCancelOrdersAsync(orders, maker, {cancelTakerTokenAmounts});
|
await exWrapper.batchCancelOrdersAsync(orders, maker, {
|
||||||
|
cancelTakerTokenAmounts,
|
||||||
|
});
|
||||||
|
|
||||||
await exWrapper.batchFillOrdersAsync(
|
await exWrapper.batchFillOrdersAsync(orders, taker, {
|
||||||
orders, taker, {fillTakerTokenAmounts: cancelTakerTokenAmounts});
|
fillTakerTokenAmounts: cancelTakerTokenAmounts,
|
||||||
|
});
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(balances).to.be.deep.equal(newBalances);
|
expect(balances).to.be.deep.equal(newBalances);
|
||||||
});
|
});
|
||||||
|
@ -45,8 +45,9 @@ contract('MultiSigWalletWithTimeLock', (accounts: string[]) => {
|
|||||||
|
|
||||||
describe('changeTimeLock', () => {
|
describe('changeTimeLock', () => {
|
||||||
it('should throw when not called by wallet', async () => {
|
it('should throw when not called by wallet', async () => {
|
||||||
return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, {from: owners[0]}))
|
return expect(multiSig.changeTimeLock(SECONDS_TIME_LOCKED, { from: owners[0] })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw without enough confirmations', async () => {
|
it('should throw without enough confirmations', async () => {
|
||||||
@ -96,7 +97,9 @@ contract('MultiSigWalletWithTimeLock', (accounts: string[]) => {
|
|||||||
const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
|
const subRes = await multiSigWrapper.submitTransactionAsync(destination, from, dataParams);
|
||||||
|
|
||||||
txId = subRes.logs[0].args.transactionId.toNumber();
|
txId = subRes.logs[0].args.transactionId.toNumber();
|
||||||
const confRes = await multiSig.confirmTransaction(txId, {from: owners[1]});
|
const confRes = await multiSig.confirmTransaction(txId, {
|
||||||
|
from: owners[1],
|
||||||
|
});
|
||||||
expect(confRes.logs).to.have.length(2);
|
expect(confRes.logs).to.have.length(2);
|
||||||
|
|
||||||
return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
|
return expect(multiSig.executeTransaction(txId)).to.be.rejectedWith(constants.REVERT);
|
||||||
|
@ -20,8 +20,14 @@ contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: s
|
|||||||
const SECONDS_TIME_LOCKED = 1000000;
|
const SECONDS_TIME_LOCKED = 1000000;
|
||||||
|
|
||||||
// initialize fake addresses
|
// initialize fake addresses
|
||||||
const authorizedAddress = `0x${crypto.solSHA3([accounts[0]]).slice(0, 20).toString('hex')}`;
|
const authorizedAddress = `0x${crypto
|
||||||
const unauthorizedAddress = `0x${crypto.solSHA3([accounts[1]]).slice(0, 20).toString('hex')}`;
|
.solSHA3([accounts[0]])
|
||||||
|
.slice(0, 20)
|
||||||
|
.toString('hex')}`;
|
||||||
|
const unauthorizedAddress = `0x${crypto
|
||||||
|
.solSHA3([accounts[1]])
|
||||||
|
.slice(0, 20)
|
||||||
|
.toString('hex')}`;
|
||||||
|
|
||||||
let tokenTransferProxy: ContractInstance;
|
let tokenTransferProxy: ContractInstance;
|
||||||
let multiSig: ContractInstance;
|
let multiSig: ContractInstance;
|
||||||
@ -32,10 +38,18 @@ contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: s
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const initialOwner = accounts[0];
|
const initialOwner = accounts[0];
|
||||||
tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
|
tokenTransferProxy = await TokenTransferProxy.new({ from: initialOwner });
|
||||||
await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {from: initialOwner});
|
await tokenTransferProxy.addAuthorizedAddress(authorizedAddress, {
|
||||||
|
from: initialOwner,
|
||||||
|
});
|
||||||
multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
|
multiSig = await MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress.new(
|
||||||
owners, requiredApprovals, SECONDS_TIME_LOCKED, tokenTransferProxy.address);
|
owners,
|
||||||
await tokenTransferProxy.transferOwnership(multiSig.address, {from: initialOwner});
|
requiredApprovals,
|
||||||
|
SECONDS_TIME_LOCKED,
|
||||||
|
tokenTransferProxy.address,
|
||||||
|
);
|
||||||
|
await tokenTransferProxy.transferOwnership(multiSig.address, {
|
||||||
|
from: initialOwner,
|
||||||
|
});
|
||||||
multiSigWrapper = new MultiSigWrapper(multiSig);
|
multiSigWrapper = new MultiSigWrapper(multiSig);
|
||||||
validDestination = tokenTransferProxy.address;
|
validDestination = tokenTransferProxy.address;
|
||||||
});
|
});
|
||||||
@ -43,8 +57,7 @@ contract('MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress', (accounts: s
|
|||||||
describe('isFunctionRemoveAuthorizedAddress', () => {
|
describe('isFunctionRemoveAuthorizedAddress', () => {
|
||||||
it('should throw if data is not for removeAuthorizedAddress', async () => {
|
it('should throw if data is not for removeAuthorizedAddress', async () => {
|
||||||
const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
|
const data = MultiSigWrapper.encodeFnArgs('addAuthorizedAddress', PROXY_ABI, [owners[0]]);
|
||||||
return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data))
|
return expect(multiSig.isFunctionRemoveAuthorizedAddress.call(data)).to.be.rejectedWith(constants.REVERT);
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true if data is for removeAuthorizedAddress', async () => {
|
it('should return true if data is for removeAuthorizedAddress', async () => {
|
||||||
|
@ -81,16 +81,20 @@ contract('TokenRegistry', (accounts: string[]) => {
|
|||||||
await tokenRegWrapper.addTokenAsync(token1, owner);
|
await tokenRegWrapper.addTokenAsync(token1, owner);
|
||||||
const duplicateNameToken = _.assign({}, token2, { name: token1.name });
|
const duplicateNameToken = _.assign({}, token2, { name: token1.name });
|
||||||
|
|
||||||
return expect(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner))
|
return expect(tokenRegWrapper.addTokenAsync(duplicateNameToken, owner)).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if symbol already exists', async () => {
|
it('should throw if symbol already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token1, owner);
|
await tokenRegWrapper.addTokenAsync(token1, owner);
|
||||||
const duplicateSymbolToken = _.assign({}, token2, {symbol: token1.symbol});
|
const duplicateSymbolToken = _.assign({}, token2, {
|
||||||
|
symbol: token1.symbol,
|
||||||
|
});
|
||||||
|
|
||||||
return expect(tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner))
|
return expect(tokenRegWrapper.addTokenAsync(duplicateSymbolToken, owner)).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -115,12 +119,15 @@ contract('TokenRegistry', (accounts: string[]) => {
|
|||||||
|
|
||||||
describe('setTokenName', () => {
|
describe('setTokenName', () => {
|
||||||
it('should throw when not called by owner', async () => {
|
it('should throw when not called by owner', async () => {
|
||||||
return expect(tokenReg.setTokenName(token1.address, token2.name, {from: notOwner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenReg.setTokenName(token1.address, token2.name, { from: notOwner }),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change the token name when called by owner', async () => {
|
it('should change the token name when called by owner', async () => {
|
||||||
const res = await tokenReg.setTokenName(token1.address, token2.name, {from: owner});
|
const res = await tokenReg.setTokenName(token1.address, token2.name, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
expect(res.logs).to.have.length(1);
|
expect(res.logs).to.have.length(1);
|
||||||
const [newData, oldData] = await Promise.all([
|
const [newData, oldData] = await Promise.all([
|
||||||
tokenRegWrapper.getTokenByNameAsync(token2.name),
|
tokenRegWrapper.getTokenByNameAsync(token2.name),
|
||||||
@ -136,20 +143,25 @@ contract('TokenRegistry', (accounts: string[]) => {
|
|||||||
it('should throw if the name already exists', async () => {
|
it('should throw if the name already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token2, owner);
|
await tokenRegWrapper.addTokenAsync(token2, owner);
|
||||||
|
|
||||||
return expect(tokenReg.setTokenName(token1.address, token2.name, {from: owner}))
|
return expect(tokenReg.setTokenName(token1.address, token2.name, { from: owner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if token does not exist', async () => {
|
it('should throw if token does not exist', async () => {
|
||||||
return expect(tokenReg.setTokenName(nullToken.address, token2.name, {from: owner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenReg.setTokenName(nullToken.address, token2.name, { from: owner }),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('setTokenSymbol', () => {
|
describe('setTokenSymbol', () => {
|
||||||
it('should throw when not called by owner', async () => {
|
it('should throw when not called by owner', async () => {
|
||||||
return expect(tokenReg.setTokenSymbol(token1.address, token2.symbol, {from: notOwner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenReg.setTokenSymbol(token1.address, token2.symbol, {
|
||||||
|
from: notOwner,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change the token symbol when called by owner', async () => {
|
it('should change the token symbol when called by owner', async () => {
|
||||||
@ -169,26 +181,35 @@ contract('TokenRegistry', (accounts: string[]) => {
|
|||||||
it('should throw if the symbol already exists', async () => {
|
it('should throw if the symbol already exists', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token2, owner);
|
await tokenRegWrapper.addTokenAsync(token2, owner);
|
||||||
|
|
||||||
return expect(tokenReg.setTokenSymbol(token1.address, token2.symbol, {from: owner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenReg.setTokenSymbol(token1.address, token2.symbol, {
|
||||||
|
from: owner,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if token does not exist', async () => {
|
it('should throw if token does not exist', async () => {
|
||||||
return expect(tokenReg.setTokenSymbol(nullToken.address, token2.symbol, {from: owner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenReg.setTokenSymbol(nullToken.address, token2.symbol, {
|
||||||
|
from: owner,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('removeToken', () => {
|
describe('removeToken', () => {
|
||||||
it('should throw if not called by owner', async () => {
|
it('should throw if not called by owner', async () => {
|
||||||
const index = 0;
|
const index = 0;
|
||||||
return expect(tokenReg.removeToken(token1.address, index, {from: notOwner}))
|
return expect(tokenReg.removeToken(token1.address, index, { from: notOwner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove token metadata when called by owner', async () => {
|
it('should remove token metadata when called by owner', async () => {
|
||||||
const index = 0;
|
const index = 0;
|
||||||
const res = await tokenReg.removeToken(token1.address, index, {from: owner});
|
const res = await tokenReg.removeToken(token1.address, index, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
expect(res.logs).to.have.length(1);
|
expect(res.logs).to.have.length(1);
|
||||||
const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
|
const tokenData = await tokenRegWrapper.getTokenMetaDataAsync(token1.address);
|
||||||
expect(tokenData).to.be.deep.equal(nullToken);
|
expect(tokenData).to.be.deep.equal(nullToken);
|
||||||
@ -196,17 +217,18 @@ contract('TokenRegistry', (accounts: string[]) => {
|
|||||||
|
|
||||||
it('should throw if token does not exist', async () => {
|
it('should throw if token does not exist', async () => {
|
||||||
const index = 0;
|
const index = 0;
|
||||||
return expect(tokenReg.removeToken(nullToken.address, index, {from: owner}))
|
return expect(tokenReg.removeToken(nullToken.address, index, { from: owner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if token at given index does not match address', async () => {
|
it('should throw if token at given index does not match address', async () => {
|
||||||
await tokenRegWrapper.addTokenAsync(token2, owner);
|
await tokenRegWrapper.addTokenAsync(token2, owner);
|
||||||
const incorrectIndex = 0;
|
const incorrectIndex = 0;
|
||||||
return expect(tokenReg.removeToken(token2.address, incorrectIndex, {from: owner}))
|
return expect(tokenReg.removeToken(token2.address, incorrectIndex, { from: owner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
});
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -22,12 +22,15 @@ contract('TokenTransferProxy', (accounts: string[]) => {
|
|||||||
|
|
||||||
describe('addAuthorizedAddress', () => {
|
describe('addAuthorizedAddress', () => {
|
||||||
it('should throw if not called by owner', async () => {
|
it('should throw if not called by owner', async () => {
|
||||||
return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, {from: notOwner}))
|
return expect(tokenTransferProxy.addAuthorizedAddress(notOwner, { from: notOwner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow owner to add an authorized address', async () => {
|
it('should allow owner to add an authorized address', async () => {
|
||||||
await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {from: owner});
|
await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
authorized = notAuthorized;
|
authorized = notAuthorized;
|
||||||
notAuthorized = null;
|
notAuthorized = null;
|
||||||
const isAuthorized = await tokenTransferProxy.authorized.call(authorized);
|
const isAuthorized = await tokenTransferProxy.authorized.call(authorized);
|
||||||
@ -35,19 +38,25 @@ contract('TokenTransferProxy', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if owner attempts to authorize a duplicate address', async () => {
|
it('should throw if owner attempts to authorize a duplicate address', async () => {
|
||||||
return expect(tokenTransferProxy.addAuthorizedAddress(authorized, {from: owner}))
|
return expect(tokenTransferProxy.addAuthorizedAddress(authorized, { from: owner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('removeAuthorizedAddress', () => {
|
describe('removeAuthorizedAddress', () => {
|
||||||
it('should throw if not called by owner', async () => {
|
it('should throw if not called by owner', async () => {
|
||||||
return expect(tokenTransferProxy.removeAuthorizedAddress(authorized, {from: notOwner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenTransferProxy.removeAuthorizedAddress(authorized, {
|
||||||
|
from: notOwner,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow owner to remove an authorized address', async () => {
|
it('should allow owner to remove an authorized address', async () => {
|
||||||
await tokenTransferProxy.removeAuthorizedAddress(authorized, {from: owner});
|
await tokenTransferProxy.removeAuthorizedAddress(authorized, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
notAuthorized = authorized;
|
notAuthorized = authorized;
|
||||||
authorized = null;
|
authorized = null;
|
||||||
|
|
||||||
@ -56,8 +65,11 @@ contract('TokenTransferProxy', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
it('should throw if owner attempts to remove an address that is not authorized', async () => {
|
||||||
return expect(tokenTransferProxy.removeAuthorizedAddress(notAuthorized, {from: owner}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenTransferProxy.removeAuthorizedAddress(notAuthorized, {
|
||||||
|
from: owner,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -65,7 +77,9 @@ contract('TokenTransferProxy', (accounts: string[]) => {
|
|||||||
it('should return all authorized addresses', async () => {
|
it('should return all authorized addresses', async () => {
|
||||||
const initial = await tokenTransferProxy.getAuthorizedAddresses();
|
const initial = await tokenTransferProxy.getAuthorizedAddresses();
|
||||||
expect(initial).to.have.length(1);
|
expect(initial).to.have.length(1);
|
||||||
await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {from: owner});
|
await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
|
|
||||||
authorized = notAuthorized;
|
authorized = notAuthorized;
|
||||||
notAuthorized = null;
|
notAuthorized = null;
|
||||||
@ -73,7 +87,9 @@ contract('TokenTransferProxy', (accounts: string[]) => {
|
|||||||
expect(afterAdd).to.have.length(2);
|
expect(afterAdd).to.have.length(2);
|
||||||
expect(afterAdd).to.include(authorized);
|
expect(afterAdd).to.include(authorized);
|
||||||
|
|
||||||
await tokenTransferProxy.removeAuthorizedAddress(authorized, {from: owner});
|
await tokenTransferProxy.removeAuthorizedAddress(authorized, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
notAuthorized = authorized;
|
notAuthorized = authorized;
|
||||||
authorized = null;
|
authorized = null;
|
||||||
const afterRemove = await tokenTransferProxy.getAuthorizedAddresses();
|
const afterRemove = await tokenTransferProxy.getAuthorizedAddresses();
|
||||||
|
@ -8,11 +8,7 @@ import {chaiSetup} from '../utils/chai_setup';
|
|||||||
|
|
||||||
chaiSetup.configure();
|
chaiSetup.configure();
|
||||||
const expect = chai.expect;
|
const expect = chai.expect;
|
||||||
const {
|
const { TokenTransferProxy, DummyToken, TokenRegistry } = new Artifacts(artifacts);
|
||||||
TokenTransferProxy,
|
|
||||||
DummyToken,
|
|
||||||
TokenRegistry,
|
|
||||||
} = new Artifacts(artifacts);
|
|
||||||
|
|
||||||
contract('TokenTransferProxy', (accounts: string[]) => {
|
contract('TokenTransferProxy', (accounts: string[]) => {
|
||||||
const INIT_BAL = 100000000;
|
const INIT_BAL = 100000000;
|
||||||
@ -36,32 +32,42 @@ contract('TokenTransferProxy', (accounts: string[]) => {
|
|||||||
|
|
||||||
dmyBalances = new Balances([rep], [accounts[0], accounts[1]]);
|
dmyBalances = new Balances([rep], [accounts[0], accounts[1]]);
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
rep.approve(TokenTransferProxy.address, INIT_ALLOW, {from: accounts[0]}),
|
rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
|
||||||
|
from: accounts[0],
|
||||||
|
}),
|
||||||
rep.setBalance(accounts[0], INIT_BAL, { from: owner }),
|
rep.setBalance(accounts[0], INIT_BAL, { from: owner }),
|
||||||
rep.approve(TokenTransferProxy.address, INIT_ALLOW, {from: accounts[1]}),
|
rep.approve(TokenTransferProxy.address, INIT_ALLOW, {
|
||||||
|
from: accounts[1],
|
||||||
|
}),
|
||||||
rep.setBalance(accounts[1], INIT_BAL, { from: owner }),
|
rep.setBalance(accounts[1], INIT_BAL, { from: owner }),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('transferFrom', () => {
|
describe('transferFrom', () => {
|
||||||
it('should throw when called by an unauthorized address', async () => {
|
it('should throw when called by an unauthorized address', async () => {
|
||||||
expect(tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], 1000, {from: notAuthorized}))
|
expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], 1000, { from: notAuthorized }),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow an authorized address to transfer', async () => {
|
it('should allow an authorized address to transfer', async () => {
|
||||||
const balances = await dmyBalances.getAsync();
|
const balances = await dmyBalances.getAsync();
|
||||||
|
|
||||||
await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {from: owner});
|
await tokenTransferProxy.addAuthorizedAddress(notAuthorized, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
const transferAmt = 10000;
|
const transferAmt = 10000;
|
||||||
await tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1],
|
await tokenTransferProxy.transferFrom(rep.address, accounts[0], accounts[1], transferAmt, {
|
||||||
transferAmt, {from: notAuthorized});
|
from: notAuthorized,
|
||||||
|
});
|
||||||
|
|
||||||
const newBalances = await dmyBalances.getAsync();
|
const newBalances = await dmyBalances.getAsync();
|
||||||
expect(newBalances[accounts[0]][rep.address])
|
expect(newBalances[accounts[0]][rep.address]).to.be.bignumber.equal(
|
||||||
.to.be.bignumber.equal(balances[accounts[0]][rep.address].minus(transferAmt));
|
balances[accounts[0]][rep.address].minus(transferAmt),
|
||||||
expect(newBalances[accounts[1]][rep.address])
|
);
|
||||||
.to.be.bignumber.equal(balances[accounts[1]][rep.address].add(transferAmt));
|
expect(newBalances[accounts[1]][rep.address]).to.be.bignumber.equal(
|
||||||
|
balances[accounts[1]][rep.address].add(transferAmt),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -48,7 +48,9 @@ contract('UnlimitedAllowanceToken', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true on a 0 value transfer', async () => {
|
it('should return true on a 0 value transfer', async () => {
|
||||||
const didReturnTrue = await token.transfer.call(spender, 0, {from: owner});
|
const didReturnTrue = await token.transfer.call(spender, 0, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
expect(didReturnTrue).to.be.true();
|
expect(didReturnTrue).to.be.true();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -36,8 +36,9 @@ contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => {
|
|||||||
it('should throw if owner has insufficient balance', async () => {
|
it('should throw if owner has insufficient balance', async () => {
|
||||||
const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
|
const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
|
||||||
const amountToTransfer = ownerBalance.plus(1);
|
const amountToTransfer = ownerBalance.plus(1);
|
||||||
return expect(token.transfer.call(spender, amountToTransfer, {from: owner}))
|
return expect(token.transfer.call(spender, amountToTransfer, { from: owner })).to.be.rejectedWith(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
constants.REVERT,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should transfer balance from sender to receiver', async () => {
|
it('should transfer balance from sender to receiver', async () => {
|
||||||
@ -55,7 +56,9 @@ contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true on a 0 value transfer', async () => {
|
it('should return true on a 0 value transfer', async () => {
|
||||||
const didReturnTrue = await token.transfer.call(spender, 0, {from: owner});
|
const didReturnTrue = await token.transfer.call(spender, 0, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
expect(didReturnTrue).to.be.true();
|
expect(didReturnTrue).to.be.true();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -65,8 +68,11 @@ contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => {
|
|||||||
const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
|
const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner);
|
||||||
const amountToTransfer = ownerBalance.plus(1);
|
const amountToTransfer = ownerBalance.plus(1);
|
||||||
await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
|
await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer);
|
||||||
return expect(token.transferFrom.call(owner, spender, amountToTransfer, {from: spender}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
token.transferFrom.call(owner, spender, amountToTransfer, {
|
||||||
|
from: spender,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if spender has insufficient allowance', async () => {
|
it('should throw if spender has insufficient allowance', async () => {
|
||||||
@ -77,8 +83,11 @@ contract('UnlimitedAllowanceTokenV2', (accounts: string[]) => {
|
|||||||
const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
|
const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
|
||||||
expect(spenderAllowanceIsInsufficient).to.be.true();
|
expect(spenderAllowanceIsInsufficient).to.be.true();
|
||||||
|
|
||||||
return expect(token.transferFrom.call(owner, spender, amountToTransfer, {from: spender}))
|
return expect(
|
||||||
.to.be.rejectedWith(constants.REVERT);
|
token.transferFrom.call(owner, spender, amountToTransfer, {
|
||||||
|
from: spender,
|
||||||
|
}),
|
||||||
|
).to.be.rejectedWith(constants.REVERT);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return true on a 0 value transfer', async () => {
|
it('should return true on a 0 value transfer', async () => {
|
||||||
|
@ -85,7 +85,9 @@ contract('ZRXToken', (accounts: string[]) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true on a 0 value transfer', async () => {
|
it('should return true on a 0 value transfer', async () => {
|
||||||
const didReturnTrue = await zrx.transfer.call(spender, 0, {from: owner});
|
const didReturnTrue = await zrx.transfer.call(spender, 0, {
|
||||||
|
from: owner,
|
||||||
|
});
|
||||||
expect(didReturnTrue).to.be.true();
|
expect(didReturnTrue).to.be.true();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,7 +21,8 @@ export class Artifacts {
|
|||||||
this.DummyTokenV2 = artifacts.require('DummyToken_v2');
|
this.DummyTokenV2 = artifacts.require('DummyToken_v2');
|
||||||
this.EtherToken = artifacts.require('WETH9');
|
this.EtherToken = artifacts.require('WETH9');
|
||||||
this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require(
|
this.MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress = artifacts.require(
|
||||||
'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress');
|
'MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress',
|
||||||
|
);
|
||||||
this.MaliciousToken = artifacts.require('MaliciousToken');
|
this.MaliciousToken = artifacts.require('MaliciousToken');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ export const crypto = {
|
|||||||
const isNumber = _.isFinite(arg);
|
const isNumber = _.isFinite(arg);
|
||||||
if (isNumber) {
|
if (isNumber) {
|
||||||
argTypes.push('uint8');
|
argTypes.push('uint8');
|
||||||
} else if ((arg).isBigNumber) {
|
} else if (arg.isBigNumber) {
|
||||||
argTypes.push('uint256');
|
argTypes.push('uint256');
|
||||||
args[i] = new BN(arg.toString(10), 10);
|
args[i] = new BN(arg.toString(10), 10);
|
||||||
} else if (ethUtil.isValidAddress(arg)) {
|
} else if (ethUtil.isValidAddress(arg)) {
|
||||||
|
@ -10,11 +10,14 @@ export class ExchangeWrapper {
|
|||||||
constructor(exchangeContractInstance: ContractInstance) {
|
constructor(exchangeContractInstance: ContractInstance) {
|
||||||
this._exchange = exchangeContractInstance;
|
this._exchange = exchangeContractInstance;
|
||||||
}
|
}
|
||||||
public async fillOrderAsync(order: Order, from: string,
|
public async fillOrderAsync(
|
||||||
|
order: Order,
|
||||||
|
from: string,
|
||||||
opts: {
|
opts: {
|
||||||
fillTakerTokenAmount?: BigNumber;
|
fillTakerTokenAmount?: BigNumber;
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
|
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
|
||||||
} = {}) {
|
} = {},
|
||||||
|
) {
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
|
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
|
||||||
const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
|
const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
|
||||||
const tx = await this._exchange.fillOrder(
|
const tx = await this._exchange.fillOrder(
|
||||||
@ -30,8 +33,7 @@ export class ExchangeWrapper {
|
|||||||
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async cancelOrderAsync(order: Order, from: string,
|
public async cancelOrderAsync(order: Order, from: string, opts: { cancelTakerTokenAmount?: BigNumber } = {}) {
|
||||||
opts: {cancelTakerTokenAmount?: BigNumber} = {}) {
|
|
||||||
const params = order.createCancel(opts.cancelTakerTokenAmount);
|
const params = order.createCancel(opts.cancelTakerTokenAmount);
|
||||||
const tx = await this._exchange.cancelOrder(
|
const tx = await this._exchange.cancelOrder(
|
||||||
params.orderAddresses,
|
params.orderAddresses,
|
||||||
@ -42,8 +44,7 @@ export class ExchangeWrapper {
|
|||||||
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async fillOrKillOrderAsync(order: Order, from: string,
|
public async fillOrKillOrderAsync(order: Order, from: string, opts: { fillTakerTokenAmount?: BigNumber } = {}) {
|
||||||
opts: {fillTakerTokenAmount?: BigNumber} = {}) {
|
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
const shouldThrowOnInsufficientBalanceOrAllowance = true;
|
||||||
const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
|
const params = order.createFill(shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmount);
|
||||||
const tx = await this._exchange.fillOrKillOrder(
|
const tx = await this._exchange.fillOrKillOrder(
|
||||||
@ -58,14 +59,20 @@ export class ExchangeWrapper {
|
|||||||
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async batchFillOrdersAsync(orders: Order[], from: string,
|
public async batchFillOrdersAsync(
|
||||||
|
orders: Order[],
|
||||||
|
from: string,
|
||||||
opts: {
|
opts: {
|
||||||
fillTakerTokenAmounts?: BigNumber[];
|
fillTakerTokenAmounts?: BigNumber[];
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
|
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
|
||||||
} = {}) {
|
} = {},
|
||||||
|
) {
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
|
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
|
||||||
const params = formatters.createBatchFill(
|
const params = formatters.createBatchFill(
|
||||||
orders, shouldThrowOnInsufficientBalanceOrAllowance, opts.fillTakerTokenAmounts);
|
orders,
|
||||||
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
|
opts.fillTakerTokenAmounts,
|
||||||
|
);
|
||||||
const tx = await this._exchange.batchFillOrders(
|
const tx = await this._exchange.batchFillOrders(
|
||||||
params.orderAddresses,
|
params.orderAddresses,
|
||||||
params.orderValues,
|
params.orderValues,
|
||||||
@ -79,8 +86,11 @@ export class ExchangeWrapper {
|
|||||||
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async batchFillOrKillOrdersAsync(orders: Order[], from: string,
|
public async batchFillOrKillOrdersAsync(
|
||||||
opts: {fillTakerTokenAmounts?: BigNumber[]} = {}) {
|
orders: Order[],
|
||||||
|
from: string,
|
||||||
|
opts: { fillTakerTokenAmounts?: BigNumber[] } = {},
|
||||||
|
) {
|
||||||
const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts);
|
const params = formatters.createBatchFill(orders, undefined, opts.fillTakerTokenAmounts);
|
||||||
const tx = await this._exchange.batchFillOrKillOrders(
|
const tx = await this._exchange.batchFillOrKillOrders(
|
||||||
params.orderAddresses,
|
params.orderAddresses,
|
||||||
@ -94,15 +104,20 @@ export class ExchangeWrapper {
|
|||||||
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async fillOrdersUpToAsync(orders: Order[], from: string,
|
public async fillOrdersUpToAsync(
|
||||||
|
orders: Order[],
|
||||||
|
from: string,
|
||||||
opts: {
|
opts: {
|
||||||
fillTakerTokenAmount?: BigNumber;
|
fillTakerTokenAmount?: BigNumber;
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
|
shouldThrowOnInsufficientBalanceOrAllowance?: boolean;
|
||||||
} = {}) {
|
} = {},
|
||||||
|
) {
|
||||||
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
|
const shouldThrowOnInsufficientBalanceOrAllowance = !!opts.shouldThrowOnInsufficientBalanceOrAllowance;
|
||||||
const params = formatters.createFillUpTo(orders,
|
const params = formatters.createFillUpTo(
|
||||||
|
orders,
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance,
|
shouldThrowOnInsufficientBalanceOrAllowance,
|
||||||
opts.fillTakerTokenAmount);
|
opts.fillTakerTokenAmount,
|
||||||
|
);
|
||||||
const tx = await this._exchange.fillOrdersUpTo(
|
const tx = await this._exchange.fillOrdersUpTo(
|
||||||
params.orderAddresses,
|
params.orderAddresses,
|
||||||
params.orderValues,
|
params.orderValues,
|
||||||
@ -116,8 +131,11 @@ export class ExchangeWrapper {
|
|||||||
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
_.each(tx.logs, log => wrapLogBigNumbers(log));
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
public async batchCancelOrdersAsync(orders: Order[], from: string,
|
public async batchCancelOrdersAsync(
|
||||||
opts: {cancelTakerTokenAmounts?: BigNumber[]} = {}) {
|
orders: Order[],
|
||||||
|
from: string,
|
||||||
|
opts: { cancelTakerTokenAmounts?: BigNumber[] } = {},
|
||||||
|
) {
|
||||||
const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts);
|
const params = formatters.createBatchCancel(orders, opts.cancelTakerTokenAmounts);
|
||||||
const tx = await this._exchange.batchCancelOrders(
|
const tx = await this._exchange.batchCancelOrders(
|
||||||
params.orderAddresses,
|
params.orderAddresses,
|
||||||
@ -144,13 +162,19 @@ export class ExchangeWrapper {
|
|||||||
);
|
);
|
||||||
return isValidSignature;
|
return isValidSignature;
|
||||||
}
|
}
|
||||||
public async isRoundingErrorAsync(numerator: BigNumber, denominator: BigNumber,
|
public async isRoundingErrorAsync(
|
||||||
target: BigNumber): Promise<boolean> {
|
numerator: BigNumber,
|
||||||
|
denominator: BigNumber,
|
||||||
|
target: BigNumber,
|
||||||
|
): Promise<boolean> {
|
||||||
const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target);
|
const isRoundingError = await this._exchange.isRoundingError(numerator, denominator, target);
|
||||||
return isRoundingError;
|
return isRoundingError;
|
||||||
}
|
}
|
||||||
public async getPartialAmountAsync(numerator: BigNumber, denominator: BigNumber,
|
public async getPartialAmountAsync(
|
||||||
target: BigNumber): Promise<BigNumber> {
|
numerator: BigNumber,
|
||||||
|
denominator: BigNumber,
|
||||||
|
target: BigNumber,
|
||||||
|
): Promise<BigNumber> {
|
||||||
const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target));
|
const partialAmount = new BigNumber(await this._exchange.getPartialAmount(numerator, denominator, target));
|
||||||
return partialAmount;
|
return partialAmount;
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,11 @@ import {Order} from './order';
|
|||||||
import { BatchCancelOrders, BatchFillOrders, FillOrdersUpTo } from './types';
|
import { BatchCancelOrders, BatchFillOrders, FillOrdersUpTo } from './types';
|
||||||
|
|
||||||
export const formatters = {
|
export const formatters = {
|
||||||
createBatchFill(orders: Order[],
|
createBatchFill(
|
||||||
|
orders: Order[],
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
fillTakerTokenAmounts: BigNumber[] = []) {
|
fillTakerTokenAmounts: BigNumber[] = [],
|
||||||
|
) {
|
||||||
const batchFill: BatchFillOrders = {
|
const batchFill: BatchFillOrders = {
|
||||||
orderAddresses: [],
|
orderAddresses: [],
|
||||||
orderValues: [],
|
orderValues: [],
|
||||||
@ -18,11 +20,21 @@ export const formatters = {
|
|||||||
s: [],
|
s: [],
|
||||||
};
|
};
|
||||||
_.forEach(orders, order => {
|
_.forEach(orders, order => {
|
||||||
batchFill.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken,
|
batchFill.orderAddresses.push([
|
||||||
order.params.takerToken, order.params.feeRecipient]);
|
order.params.maker,
|
||||||
batchFill.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount,
|
order.params.taker,
|
||||||
order.params.makerFee, order.params.takerFee,
|
order.params.makerToken,
|
||||||
order.params.expirationTimestampInSec, order.params.salt]);
|
order.params.takerToken,
|
||||||
|
order.params.feeRecipient,
|
||||||
|
]);
|
||||||
|
batchFill.orderValues.push([
|
||||||
|
order.params.makerTokenAmount,
|
||||||
|
order.params.takerTokenAmount,
|
||||||
|
order.params.makerFee,
|
||||||
|
order.params.takerFee,
|
||||||
|
order.params.expirationTimestampInSec,
|
||||||
|
order.params.salt,
|
||||||
|
]);
|
||||||
batchFill.v.push(order.params.v);
|
batchFill.v.push(order.params.v);
|
||||||
batchFill.r.push(order.params.r);
|
batchFill.r.push(order.params.r);
|
||||||
batchFill.s.push(order.params.s);
|
batchFill.s.push(order.params.s);
|
||||||
@ -32,9 +44,11 @@ export const formatters = {
|
|||||||
});
|
});
|
||||||
return batchFill;
|
return batchFill;
|
||||||
},
|
},
|
||||||
createFillUpTo(orders: Order[],
|
createFillUpTo(
|
||||||
|
orders: Order[],
|
||||||
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
shouldThrowOnInsufficientBalanceOrAllowance: boolean,
|
||||||
fillTakerTokenAmount: BigNumber) {
|
fillTakerTokenAmount: BigNumber,
|
||||||
|
) {
|
||||||
const fillUpTo: FillOrdersUpTo = {
|
const fillUpTo: FillOrdersUpTo = {
|
||||||
orderAddresses: [],
|
orderAddresses: [],
|
||||||
orderValues: [],
|
orderValues: [],
|
||||||
@ -45,11 +59,21 @@ export const formatters = {
|
|||||||
s: [],
|
s: [],
|
||||||
};
|
};
|
||||||
orders.forEach(order => {
|
orders.forEach(order => {
|
||||||
fillUpTo.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken,
|
fillUpTo.orderAddresses.push([
|
||||||
order.params.takerToken, order.params.feeRecipient]);
|
order.params.maker,
|
||||||
fillUpTo.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount,
|
order.params.taker,
|
||||||
order.params.makerFee, order.params.takerFee,
|
order.params.makerToken,
|
||||||
order.params.expirationTimestampInSec, order.params.salt]);
|
order.params.takerToken,
|
||||||
|
order.params.feeRecipient,
|
||||||
|
]);
|
||||||
|
fillUpTo.orderValues.push([
|
||||||
|
order.params.makerTokenAmount,
|
||||||
|
order.params.takerTokenAmount,
|
||||||
|
order.params.makerFee,
|
||||||
|
order.params.takerFee,
|
||||||
|
order.params.expirationTimestampInSec,
|
||||||
|
order.params.salt,
|
||||||
|
]);
|
||||||
fillUpTo.v.push(order.params.v);
|
fillUpTo.v.push(order.params.v);
|
||||||
fillUpTo.r.push(order.params.r);
|
fillUpTo.r.push(order.params.r);
|
||||||
fillUpTo.s.push(order.params.s);
|
fillUpTo.s.push(order.params.s);
|
||||||
@ -63,11 +87,21 @@ export const formatters = {
|
|||||||
cancelTakerTokenAmounts,
|
cancelTakerTokenAmounts,
|
||||||
};
|
};
|
||||||
orders.forEach(order => {
|
orders.forEach(order => {
|
||||||
batchCancel.orderAddresses.push([order.params.maker, order.params.taker, order.params.makerToken,
|
batchCancel.orderAddresses.push([
|
||||||
order.params.takerToken, order.params.feeRecipient]);
|
order.params.maker,
|
||||||
batchCancel.orderValues.push([order.params.makerTokenAmount, order.params.takerTokenAmount,
|
order.params.taker,
|
||||||
order.params.makerFee, order.params.takerFee,
|
order.params.makerToken,
|
||||||
order.params.expirationTimestampInSec, order.params.salt]);
|
order.params.takerToken,
|
||||||
|
order.params.feeRecipient,
|
||||||
|
]);
|
||||||
|
batchCancel.orderValues.push([
|
||||||
|
order.params.makerTokenAmount,
|
||||||
|
order.params.takerTokenAmount,
|
||||||
|
order.params.makerFee,
|
||||||
|
order.params.takerFee,
|
||||||
|
order.params.expirationTimestampInSec,
|
||||||
|
order.params.salt,
|
||||||
|
]);
|
||||||
if (cancelTakerTokenAmounts.length < orders.length) {
|
if (cancelTakerTokenAmounts.length < orders.length) {
|
||||||
batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount);
|
batchCancel.cancelTakerTokenAmounts.push(order.params.takerTokenAmount);
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,16 @@ export class MultiSigWrapper {
|
|||||||
constructor(multiSigContractInstance: ContractInstance) {
|
constructor(multiSigContractInstance: ContractInstance) {
|
||||||
this._multiSig = multiSigContractInstance;
|
this._multiSig = multiSigContractInstance;
|
||||||
}
|
}
|
||||||
public async submitTransactionAsync(destination: string, from: string,
|
public async submitTransactionAsync(
|
||||||
|
destination: string,
|
||||||
|
from: string,
|
||||||
dataParams: TransactionDataParams,
|
dataParams: TransactionDataParams,
|
||||||
value: number = 0) {
|
value: number = 0,
|
||||||
|
) {
|
||||||
const { name, abi, args = [] } = dataParams;
|
const { name, abi, args = [] } = dataParams;
|
||||||
const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
|
const encoded = MultiSigWrapper.encodeFnArgs(name, abi, args);
|
||||||
return this._multiSig.submitTransaction(destination, value, encoded, {from});
|
return this._multiSig.submitTransaction(destination, value, encoded, {
|
||||||
|
from,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,12 +11,17 @@ export class OrderFactory {
|
|||||||
this._defaultOrderParams = defaultOrderParams;
|
this._defaultOrderParams = defaultOrderParams;
|
||||||
}
|
}
|
||||||
public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) {
|
public async newSignedOrderAsync(customOrderParams: OptionalOrderParams = {}) {
|
||||||
const randomExpiration = new BigNumber(Math.floor((Date.now() + (Math.random() * 100000000000)) / 1000));
|
const randomExpiration = new BigNumber(Math.floor((Date.now() + Math.random() * 100000000000) / 1000));
|
||||||
const orderParams: OrderParams = _.assign({}, {
|
const orderParams: OrderParams = _.assign(
|
||||||
|
{},
|
||||||
|
{
|
||||||
expirationTimestampInSec: randomExpiration,
|
expirationTimestampInSec: randomExpiration,
|
||||||
salt: ZeroEx.generatePseudoRandomSalt(),
|
salt: ZeroEx.generatePseudoRandomSalt(),
|
||||||
taker: ZeroEx.NULL_ADDRESS,
|
taker: ZeroEx.NULL_ADDRESS,
|
||||||
}, this._defaultOrderParams, customOrderParams);
|
},
|
||||||
|
this._defaultOrderParams,
|
||||||
|
customOrderParams,
|
||||||
|
);
|
||||||
const order = new Order(orderParams);
|
const order = new Order(orderParams);
|
||||||
await order.signAsync();
|
await order.signAsync();
|
||||||
return order;
|
return order;
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
export const indexFilterValuesSchema = {
|
export const indexFilterValuesSchema = {
|
||||||
id: '/IndexFilterValues',
|
id: '/IndexFilterValues',
|
||||||
additionalProperties: {
|
additionalProperties: {
|
||||||
oneOf: [
|
oneOf: [{ $ref: '/Number' }, { $ref: '/Address' }, { $ref: '/OrderHashSchema' }],
|
||||||
{$ref: '/Number'},
|
|
||||||
{$ref: '/Address'},
|
|
||||||
{$ref: '/OrderHashSchema'},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
type: 'object',
|
type: 'object',
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,16 @@ export const orderSchema = {
|
|||||||
exchangeContractAddress: { $ref: '/Address' },
|
exchangeContractAddress: { $ref: '/Address' },
|
||||||
},
|
},
|
||||||
required: [
|
required: [
|
||||||
'maker', 'taker', 'makerFee', 'takerFee', 'makerTokenAmount', 'takerTokenAmount',
|
'maker',
|
||||||
'salt', 'feeRecipient', 'expirationUnixTimestampSec', 'exchangeContractAddress',
|
'taker',
|
||||||
|
'makerFee',
|
||||||
|
'takerFee',
|
||||||
|
'makerTokenAmount',
|
||||||
|
'takerTokenAmount',
|
||||||
|
'salt',
|
||||||
|
'feeRecipient',
|
||||||
|
'expirationUnixTimestampSec',
|
||||||
|
'exchangeContractAddress',
|
||||||
],
|
],
|
||||||
type: 'object',
|
type: 'object',
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,12 @@ export const relayerApiFeesPayloadSchema = {
|
|||||||
salt: { $ref: '/Number' },
|
salt: { $ref: '/Number' },
|
||||||
},
|
},
|
||||||
required: [
|
required: [
|
||||||
'exchangeContractAddress', 'maker', 'taker', 'makerTokenAddress', 'takerTokenAddress',
|
'exchangeContractAddress',
|
||||||
'expirationUnixTimestampSec', 'salt',
|
'maker',
|
||||||
|
'taker',
|
||||||
|
'makerTokenAddress',
|
||||||
|
'takerTokenAddress',
|
||||||
|
'expirationUnixTimestampSec',
|
||||||
|
'salt',
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
@ -10,22 +10,13 @@ export const txDataSchema = {
|
|||||||
from: { $ref: '/Address' },
|
from: { $ref: '/Address' },
|
||||||
to: { $ref: '/Address' },
|
to: { $ref: '/Address' },
|
||||||
value: {
|
value: {
|
||||||
oneOf: [
|
oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
|
||||||
{$ref: '/Number'},
|
|
||||||
{$ref: '/JsNumber'},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
gas: {
|
gas: {
|
||||||
oneOf: [
|
oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
|
||||||
{$ref: '/Number'},
|
|
||||||
{$ref: '/JsNumber'},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
gasPrice: {
|
gasPrice: {
|
||||||
oneOf: [
|
oneOf: [{ $ref: '/Number' }, { $ref: '/JsNumber' }],
|
||||||
{$ref: '/Number'},
|
|
||||||
{$ref: '/JsNumber'},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
@ -1,43 +1,15 @@
|
|||||||
import {
|
import { addressSchema, numberSchema } from '../schemas/basic_type_schemas';
|
||||||
addressSchema,
|
import { blockParamSchema, blockRangeSchema } from '../schemas/block_range_schema';
|
||||||
numberSchema,
|
import { ecSignatureParameterSchema, ecSignatureSchema } from '../schemas/ec_signature_schema';
|
||||||
} from '../schemas/basic_type_schemas';
|
import { indexFilterValuesSchema } from '../schemas/index_filter_values_schema';
|
||||||
import {
|
import { orderCancellationRequestsSchema } from '../schemas/order_cancel_schema';
|
||||||
blockParamSchema,
|
import { orderFillOrKillRequestsSchema } from '../schemas/order_fill_or_kill_requests_schema';
|
||||||
blockRangeSchema,
|
import { orderFillRequestsSchema } from '../schemas/order_fill_requests_schema';
|
||||||
} from '../schemas/block_range_schema';
|
import { orderHashSchema } from '../schemas/order_hash_schema';
|
||||||
import {
|
import { orderSchema, signedOrderSchema } from '../schemas/order_schemas';
|
||||||
ecSignatureParameterSchema,
|
import { relayerApiErrorResponseSchema } from '../schemas/relayer_api_error_response_schema';
|
||||||
ecSignatureSchema,
|
import { relayerApiFeesPayloadSchema } from '../schemas/relayer_api_fees_payload_schema';
|
||||||
} from '../schemas/ec_signature_schema';
|
import { relayerApiFeesResponseSchema } from '../schemas/relayer_api_fees_response_schema';
|
||||||
import {
|
|
||||||
indexFilterValuesSchema,
|
|
||||||
} from '../schemas/index_filter_values_schema';
|
|
||||||
import {
|
|
||||||
orderCancellationRequestsSchema,
|
|
||||||
} from '../schemas/order_cancel_schema';
|
|
||||||
import {
|
|
||||||
orderFillOrKillRequestsSchema,
|
|
||||||
} from '../schemas/order_fill_or_kill_requests_schema';
|
|
||||||
import {
|
|
||||||
orderFillRequestsSchema,
|
|
||||||
} from '../schemas/order_fill_requests_schema';
|
|
||||||
import {
|
|
||||||
orderHashSchema,
|
|
||||||
} from '../schemas/order_hash_schema';
|
|
||||||
import {
|
|
||||||
orderSchema,
|
|
||||||
signedOrderSchema,
|
|
||||||
} from '../schemas/order_schemas';
|
|
||||||
import {
|
|
||||||
relayerApiErrorResponseSchema,
|
|
||||||
} from '../schemas/relayer_api_error_response_schema';
|
|
||||||
import {
|
|
||||||
relayerApiFeesPayloadSchema,
|
|
||||||
} from '../schemas/relayer_api_fees_payload_schema';
|
|
||||||
import {
|
|
||||||
relayerApiFeesResponseSchema,
|
|
||||||
} from '../schemas/relayer_api_fees_response_schema';
|
|
||||||
import {
|
import {
|
||||||
relayerApiOrderbookChannelSubscribePayload,
|
relayerApiOrderbookChannelSubscribePayload,
|
||||||
relayerApiOrderbookChannelSubscribeSchema,
|
relayerApiOrderbookChannelSubscribeSchema,
|
||||||
@ -46,26 +18,15 @@ import {
|
|||||||
relayerApiOrderbookChannelSnapshotPayload,
|
relayerApiOrderbookChannelSnapshotPayload,
|
||||||
relayerApiOrderbookChannelSnapshotSchema,
|
relayerApiOrderbookChannelSnapshotSchema,
|
||||||
} from '../schemas/relayer_api_orderbook_channel_snapshot_schema';
|
} from '../schemas/relayer_api_orderbook_channel_snapshot_schema';
|
||||||
import {
|
import { relayerApiOrderbookChannelUpdateSchema } from '../schemas/relayer_api_orderbook_channel_update_response_schema';
|
||||||
relayerApiOrderbookChannelUpdateSchema,
|
import { relayerApiOrderBookResponseSchema } from '../schemas/relayer_api_orderbook_response_schema';
|
||||||
} from '../schemas/relayer_api_orderbook_channel_update_response_schema';
|
|
||||||
import {
|
|
||||||
relayerApiOrderBookResponseSchema,
|
|
||||||
} from '../schemas/relayer_api_orderbook_response_schema';
|
|
||||||
import {
|
import {
|
||||||
relayerApiTokenPairsResponseSchema,
|
relayerApiTokenPairsResponseSchema,
|
||||||
relayerApiTokenTradeInfoSchema,
|
relayerApiTokenTradeInfoSchema,
|
||||||
} from '../schemas/relayer_api_token_pairs_response_schema';
|
} from '../schemas/relayer_api_token_pairs_response_schema';
|
||||||
import {
|
import { signedOrdersSchema } from '../schemas/signed_orders_schema';
|
||||||
signedOrdersSchema,
|
import { tokenSchema } from '../schemas/token_schema';
|
||||||
} from '../schemas/signed_orders_schema';
|
import { jsNumber, txDataSchema } from '../schemas/tx_data_schema';
|
||||||
import {
|
|
||||||
tokenSchema,
|
|
||||||
} from '../schemas/token_schema';
|
|
||||||
import {
|
|
||||||
jsNumber,
|
|
||||||
txDataSchema,
|
|
||||||
} from '../schemas/tx_data_schema';
|
|
||||||
|
|
||||||
export const schemas = {
|
export const schemas = {
|
||||||
numberSchema,
|
numberSchema,
|
||||||
|
@ -122,11 +122,7 @@ describe('Schema', () => {
|
|||||||
const v = 27;
|
const v = 27;
|
||||||
const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
|
const r = '0x61a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33';
|
||||||
const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254';
|
const s = '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254';
|
||||||
const testCases = [
|
const testCases = [{}, { v }, { r, s, v: 31 }];
|
||||||
{},
|
|
||||||
{v},
|
|
||||||
{r, s, v: 31},
|
|
||||||
];
|
|
||||||
const shouldFail = true;
|
const shouldFail = true;
|
||||||
validateAgainstSchema(testCases, ecSignatureSchema, shouldFail);
|
validateAgainstSchema(testCases, ecSignatureSchema, shouldFail);
|
||||||
});
|
});
|
||||||
@ -152,37 +148,22 @@ describe('Schema', () => {
|
|||||||
});
|
});
|
||||||
describe('#blockParamSchema', () => {
|
describe('#blockParamSchema', () => {
|
||||||
it('should validate valid block param', () => {
|
it('should validate valid block param', () => {
|
||||||
const testCases = [
|
const testCases = [42, 'latest', 'pending', 'earliest'];
|
||||||
42,
|
|
||||||
'latest',
|
|
||||||
'pending',
|
|
||||||
'earliest',
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, blockParamSchema);
|
validateAgainstSchema(testCases, blockParamSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid block param', () => {
|
it('should fail for invalid block param', () => {
|
||||||
const testCases = [
|
const testCases = [{}, '42', 'pemding'];
|
||||||
{},
|
|
||||||
'42',
|
|
||||||
'pemding',
|
|
||||||
];
|
|
||||||
const shouldFail = true;
|
const shouldFail = true;
|
||||||
validateAgainstSchema(testCases, blockParamSchema, shouldFail);
|
validateAgainstSchema(testCases, blockParamSchema, shouldFail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#blockRangeSchema', () => {
|
describe('#blockRangeSchema', () => {
|
||||||
it('should validate valid subscription opts', () => {
|
it('should validate valid subscription opts', () => {
|
||||||
const testCases = [
|
const testCases = [{ fromBlock: 42, toBlock: 'latest' }, { fromBlock: 42 }, {}];
|
||||||
{fromBlock: 42, toBlock: 'latest'},
|
|
||||||
{fromBlock: 42},
|
|
||||||
{},
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, blockRangeSchema);
|
validateAgainstSchema(testCases, blockRangeSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid subscription opts', () => {
|
it('should fail for invalid subscription opts', () => {
|
||||||
const testCases = [
|
const testCases = [{ fromBlock: '42' }];
|
||||||
{fromBlock: '42'},
|
|
||||||
];
|
|
||||||
const shouldFail = true;
|
const shouldFail = true;
|
||||||
validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
|
validateAgainstSchema(testCases, blockRangeSchema, shouldFail);
|
||||||
});
|
});
|
||||||
@ -196,9 +177,7 @@ describe('Schema', () => {
|
|||||||
url: 'https://0xproject.com',
|
url: 'https://0xproject.com',
|
||||||
};
|
};
|
||||||
it('should validate valid token', () => {
|
it('should validate valid token', () => {
|
||||||
const testCases = [
|
const testCases = [token];
|
||||||
token,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, tokenSchema);
|
validateAgainstSchema(testCases, tokenSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid token', () => {
|
it('should fail for invalid token', () => {
|
||||||
@ -235,9 +214,7 @@ describe('Schema', () => {
|
|||||||
};
|
};
|
||||||
describe('#orderSchema', () => {
|
describe('#orderSchema', () => {
|
||||||
it('should validate valid order', () => {
|
it('should validate valid order', () => {
|
||||||
const testCases = [
|
const testCases = [order];
|
||||||
order,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, orderSchema);
|
validateAgainstSchema(testCases, orderSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid order', () => {
|
it('should fail for invalid order', () => {
|
||||||
@ -267,28 +244,18 @@ describe('Schema', () => {
|
|||||||
};
|
};
|
||||||
describe('#signedOrdersSchema', () => {
|
describe('#signedOrdersSchema', () => {
|
||||||
it('should validate valid signed orders', () => {
|
it('should validate valid signed orders', () => {
|
||||||
const testCases = [
|
const testCases = [[signedOrder], []];
|
||||||
[signedOrder],
|
|
||||||
[],
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, signedOrdersSchema);
|
validateAgainstSchema(testCases, signedOrdersSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid signed orders', () => {
|
it('should fail for invalid signed orders', () => {
|
||||||
const testCases = [
|
const testCases = [[signedOrder, 1]];
|
||||||
[
|
|
||||||
signedOrder,
|
|
||||||
1,
|
|
||||||
],
|
|
||||||
];
|
|
||||||
const shouldFail = true;
|
const shouldFail = true;
|
||||||
validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
|
validateAgainstSchema(testCases, signedOrdersSchema, shouldFail);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('#signedOrderSchema', () => {
|
describe('#signedOrderSchema', () => {
|
||||||
it('should validate valid signed order', () => {
|
it('should validate valid signed order', () => {
|
||||||
const testCases = [
|
const testCases = [signedOrder];
|
||||||
signedOrder,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, signedOrderSchema);
|
validateAgainstSchema(testCases, signedOrderSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid signed order', () => {
|
it('should fail for invalid signed order', () => {
|
||||||
@ -310,9 +277,7 @@ describe('Schema', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
it('should validate valid order fill or kill requests', () => {
|
it('should validate valid order fill or kill requests', () => {
|
||||||
const testCases = [
|
const testCases = [orderFillOrKillRequests];
|
||||||
orderFillOrKillRequests,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
|
validateAgainstSchema(testCases, orderFillOrKillRequestsSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid order fill or kill requests', () => {
|
it('should fail for invalid order fill or kill requests', () => {
|
||||||
@ -336,9 +301,7 @@ describe('Schema', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
it('should validate valid order cancellation requests', () => {
|
it('should validate valid order cancellation requests', () => {
|
||||||
const testCases = [
|
const testCases = [orderCancellationRequests];
|
||||||
orderCancellationRequests,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, orderCancellationRequestsSchema);
|
validateAgainstSchema(testCases, orderCancellationRequestsSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid order cancellation requests', () => {
|
it('should fail for invalid order cancellation requests', () => {
|
||||||
@ -362,9 +325,7 @@ describe('Schema', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
it('should validate valid order fill requests', () => {
|
it('should validate valid order fill requests', () => {
|
||||||
const testCases = [
|
const testCases = [orderFillRequests];
|
||||||
orderFillRequests,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, orderFillRequestsSchema);
|
validateAgainstSchema(testCases, orderFillRequestsSchema);
|
||||||
});
|
});
|
||||||
it('should fail for invalid order fill requests', () => {
|
it('should fail for invalid order fill requests', () => {
|
||||||
@ -559,12 +520,8 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
asks: [signedOrder],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -577,12 +534,8 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
asks: [signedOrder],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -590,24 +543,16 @@ describe('Schema', () => {
|
|||||||
channel: 'bar',
|
channel: 'bar',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
asks: [signedOrder],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'snapshot',
|
type: 'snapshot',
|
||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
asks: [signedOrder],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -615,12 +560,8 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: '2',
|
requestId: '2',
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
asks: [signedOrder],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -628,9 +569,7 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -638,9 +577,7 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
asks: [
|
asks: [signedOrder],
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -648,12 +585,8 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [signedOrder],
|
||||||
signedOrder,
|
asks: [{}],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
{},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -661,12 +594,8 @@ describe('Schema', () => {
|
|||||||
channel: 'orderbook',
|
channel: 'orderbook',
|
||||||
requestId: 2,
|
requestId: 2,
|
||||||
payload: {
|
payload: {
|
||||||
bids: [
|
bids: [{}],
|
||||||
{},
|
asks: [signedOrder],
|
||||||
],
|
|
||||||
asks: [
|
|
||||||
signedOrder,
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -941,18 +870,11 @@ describe('Schema', () => {
|
|||||||
});
|
});
|
||||||
describe('#jsNumberSchema', () => {
|
describe('#jsNumberSchema', () => {
|
||||||
it('should validate valid js number', () => {
|
it('should validate valid js number', () => {
|
||||||
const testCases = [
|
const testCases = [1, 42];
|
||||||
1,
|
|
||||||
42,
|
|
||||||
];
|
|
||||||
validateAgainstSchema(testCases, jsNumber);
|
validateAgainstSchema(testCases, jsNumber);
|
||||||
});
|
});
|
||||||
it('should fail for invalid js number', () => {
|
it('should fail for invalid js number', () => {
|
||||||
const testCases = [
|
const testCases = [NaN, -1, new BigNumber(1)];
|
||||||
NaN,
|
|
||||||
-1,
|
|
||||||
new BigNumber(1),
|
|
||||||
];
|
|
||||||
const shouldFail = true;
|
const shouldFail = true;
|
||||||
validateAgainstSchema(testCases, jsNumber, shouldFail);
|
validateAgainstSchema(testCases, jsNumber, shouldFail);
|
||||||
});
|
});
|
||||||
|
@ -3,9 +3,10 @@ export const configs = {
|
|||||||
DISPENSER_PRIVATE_KEY: process.env.DISPENSER_PRIVATE_KEY,
|
DISPENSER_PRIVATE_KEY: process.env.DISPENSER_PRIVATE_KEY,
|
||||||
ENVIRONMENT: process.env.FAUCET_ENVIRONMENT,
|
ENVIRONMENT: process.env.FAUCET_ENVIRONMENT,
|
||||||
ROLLBAR_ACCESS_KEY: process.env.FAUCET_ROLLBAR_ACCESS_KEY,
|
ROLLBAR_ACCESS_KEY: process.env.FAUCET_ROLLBAR_ACCESS_KEY,
|
||||||
RPC_URL: process.env.FAUCET_ENVIRONMENT === 'development' ?
|
RPC_URL:
|
||||||
'http://127.0.0.1:8545' :
|
process.env.FAUCET_ENVIRONMENT === 'development'
|
||||||
`https://kovan.infura.io/${process.env.INFURA_API_KEY}`,
|
? 'http://127.0.0.1:8545'
|
||||||
|
: `https://kovan.infura.io/${process.env.INFURA_API_KEY}`,
|
||||||
ZRX_TOKEN_ADDRESS: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
|
ZRX_TOKEN_ADDRESS: '0x6ff6c0ff1d68b964901f986d4c9fa3ac68346570',
|
||||||
KOVAN_NETWORK_ID: 42,
|
KOVAN_NETWORK_ID: 42,
|
||||||
};
|
};
|
||||||
|
@ -78,9 +78,11 @@ export class Handler {
|
|||||||
const engine = new ProviderEngine();
|
const engine = new ProviderEngine();
|
||||||
engine.addProvider(new NonceSubprovider());
|
engine.addProvider(new NonceSubprovider());
|
||||||
engine.addProvider(new HookedWalletSubprovider(idManagement));
|
engine.addProvider(new HookedWalletSubprovider(idManagement));
|
||||||
engine.addProvider(new RpcSubprovider({
|
engine.addProvider(
|
||||||
|
new RpcSubprovider({
|
||||||
rpcUrl,
|
rpcUrl,
|
||||||
}));
|
}),
|
||||||
|
);
|
||||||
engine.start();
|
engine.start();
|
||||||
return engine;
|
return engine;
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,7 @@ type Callback = (err: Error, accounts: any) => void;
|
|||||||
export const idManagement = {
|
export const idManagement = {
|
||||||
getAccounts(callback: Callback) {
|
getAccounts(callback: Callback) {
|
||||||
utils.consoleLog(`configs.DISPENSER_ADDRESS: ${configs.DISPENSER_ADDRESS}`);
|
utils.consoleLog(`configs.DISPENSER_ADDRESS: ${configs.DISPENSER_ADDRESS}`);
|
||||||
callback(null, [
|
callback(null, [configs.DISPENSER_ADDRESS]);
|
||||||
configs.DISPENSER_ADDRESS,
|
|
||||||
]);
|
|
||||||
},
|
},
|
||||||
approveTransaction(txData: object, callback: Callback) {
|
approveTransaction(txData: object, callback: Callback) {
|
||||||
callback(null, true);
|
callback(null, true);
|
||||||
|
@ -44,7 +44,6 @@ export class RequestQueue {
|
|||||||
const recipientAddress = this.queue.shift();
|
const recipientAddress = this.queue.shift();
|
||||||
// tslint:disable-next-line:no-floating-promises
|
// tslint:disable-next-line:no-floating-promises
|
||||||
this.processNextRequestFireAndForgetAsync(recipientAddress);
|
this.processNextRequestFireAndForgetAsync(recipientAddress);
|
||||||
|
|
||||||
}, this.queueIntervalMs);
|
}, this.queueIntervalMs);
|
||||||
}
|
}
|
||||||
protected stop() {
|
protected stop() {
|
||||||
|
@ -16,7 +16,9 @@ app.use((req, res, next) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handler = new Handler();
|
const handler = new Handler();
|
||||||
app.get('/ping', (req: express.Request, res: express.Response) => { res.status(200).send('pong'); });
|
app.get('/ping', (req: express.Request, res: express.Response) => {
|
||||||
|
res.status(200).send('pong');
|
||||||
|
});
|
||||||
app.get('/ether/:recipient', handler.dispenseEther.bind(handler));
|
app.get('/ether/:recipient', handler.dispenseEther.bind(handler));
|
||||||
app.get('/zrx/:recipient', handler.dispenseZRX.bind(handler));
|
app.get('/zrx/:recipient', handler.dispenseZRX.bind(handler));
|
||||||
|
|
||||||
|
@ -31,7 +31,10 @@ export class ZRXRequestQueue extends RequestQueue {
|
|||||||
const baseUnitAmount = ZeroEx.toBaseUnitAmount(DISPENSE_AMOUNT_ZRX, 18);
|
const baseUnitAmount = ZeroEx.toBaseUnitAmount(DISPENSE_AMOUNT_ZRX, 18);
|
||||||
try {
|
try {
|
||||||
await this._zeroEx.token.transferAsync(
|
await this._zeroEx.token.transferAsync(
|
||||||
configs.ZRX_TOKEN_ADDRESS, configs.DISPENSER_ADDRESS, recipientAddress, baseUnitAmount,
|
configs.ZRX_TOKEN_ADDRESS,
|
||||||
|
configs.DISPENSER_ADDRESS,
|
||||||
|
recipientAddress,
|
||||||
|
baseUnitAmount,
|
||||||
);
|
);
|
||||||
utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ZRX} ZRX to ${recipientAddress}`);
|
utils.consoleLog(`Sent ${DISPENSE_AMOUNT_ZRX} ZRX to ${recipientAddress}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
16
packages/subproviders/src/globals.d.ts
vendored
16
packages/subproviders/src/globals.d.ts
vendored
@ -47,10 +47,16 @@ declare module 'ledgerco' {
|
|||||||
export class eth {
|
export class eth {
|
||||||
public comm: comm;
|
public comm: comm;
|
||||||
constructor(comm: comm);
|
constructor(comm: comm);
|
||||||
public getAddress_async(path: string, display?: boolean, chaincode?: boolean):
|
public getAddress_async(
|
||||||
Promise<{publicKey: string; address: string; chainCode: string}>;
|
path: string,
|
||||||
|
display?: boolean,
|
||||||
|
chaincode?: boolean,
|
||||||
|
): Promise<{ publicKey: string; address: string; chainCode: string }>;
|
||||||
public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
|
public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
|
||||||
public getAppConfiguration_async(): Promise<{ arbitraryDataEnabled: number; version: string }>;
|
public getAppConfiguration_async(): Promise<{
|
||||||
|
arbitraryDataEnabled: number;
|
||||||
|
version: string;
|
||||||
|
}>;
|
||||||
public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
|
public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +81,9 @@ declare module 'web3-provider-engine/subproviders/rpc' {
|
|||||||
class RpcSubprovider {
|
class RpcSubprovider {
|
||||||
constructor(options: { rpcUrl: string });
|
constructor(options: { rpcUrl: string });
|
||||||
public handleRequest(
|
public handleRequest(
|
||||||
payload: Web3.JSONRPCRequestPayload, next: () => void, end: (err: Error|null, data?: any) => void,
|
payload: Web3.JSONRPCRequestPayload,
|
||||||
|
next: () => void,
|
||||||
|
end: (err: Error | null, data?: any) => void,
|
||||||
): void;
|
): void;
|
||||||
}
|
}
|
||||||
export = RpcSubprovider;
|
export = RpcSubprovider;
|
||||||
|
@ -8,14 +8,8 @@ import {LedgerEthereumClient} from './types';
|
|||||||
|
|
||||||
export { InjectedWeb3Subprovider } from './subproviders/injected_web3';
|
export { InjectedWeb3Subprovider } from './subproviders/injected_web3';
|
||||||
export { RedundantRPCSubprovider } from './subproviders/redundant_rpc';
|
export { RedundantRPCSubprovider } from './subproviders/redundant_rpc';
|
||||||
export {
|
export { LedgerSubprovider } from './subproviders/ledger';
|
||||||
LedgerSubprovider,
|
export { ECSignature, LedgerWalletSubprovider, LedgerCommunicationClient } from './types';
|
||||||
} from './subproviders/ledger';
|
|
||||||
export {
|
|
||||||
ECSignature,
|
|
||||||
LedgerWalletSubprovider,
|
|
||||||
LedgerCommunicationClient,
|
|
||||||
} from './types';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory method for creating a LedgerEthereumClient usable in a browser context.
|
* A factory method for creating a LedgerEthereumClient usable in a browser context.
|
||||||
|
@ -14,7 +14,9 @@ export class InjectedWeb3Subprovider {
|
|||||||
this._injectedWeb3 = injectedWeb3;
|
this._injectedWeb3 = injectedWeb3;
|
||||||
}
|
}
|
||||||
public handleRequest(
|
public handleRequest(
|
||||||
payload: Web3.JSONRPCRequestPayload, next: () => void, end: (err: Error|null, result: any) => void,
|
payload: Web3.JSONRPCRequestPayload,
|
||||||
|
next: () => void,
|
||||||
|
end: (err: Error | null, result: any) => void,
|
||||||
) {
|
) {
|
||||||
switch (payload.method) {
|
switch (payload.method) {
|
||||||
case 'web3_clientVersion':
|
case 'web3_clientVersion':
|
||||||
|
@ -44,12 +44,11 @@ export class LedgerSubprovider extends Subprovider {
|
|||||||
this._networkId = config.networkId;
|
this._networkId = config.networkId;
|
||||||
this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
|
this._ledgerEthereumClientFactoryAsync = config.ledgerEthereumClientFactoryAsync;
|
||||||
this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
|
this._derivationPath = config.derivationPath || DEFAULT_DERIVATION_PATH;
|
||||||
this._shouldAlwaysAskForConfirmation = !_.isUndefined(config.accountFetchingConfigs) &&
|
this._shouldAlwaysAskForConfirmation =
|
||||||
!_.isUndefined(
|
!_.isUndefined(config.accountFetchingConfigs) &&
|
||||||
config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation,
|
!_.isUndefined(config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation)
|
||||||
) ?
|
? config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation
|
||||||
config.accountFetchingConfigs.shouldAskForOnDeviceConfirmation :
|
: ASK_FOR_ON_DEVICE_CONFIRMATION;
|
||||||
ASK_FOR_ON_DEVICE_CONFIRMATION;
|
|
||||||
this._derivationPathIndex = 0;
|
this._derivationPathIndex = 0;
|
||||||
}
|
}
|
||||||
public getPath(): string {
|
public getPath(): string {
|
||||||
@ -62,7 +61,9 @@ export class LedgerSubprovider extends Subprovider {
|
|||||||
this._derivationPathIndex = pathIndex;
|
this._derivationPathIndex = pathIndex;
|
||||||
}
|
}
|
||||||
public async handleRequest(
|
public async handleRequest(
|
||||||
payload: Web3.JSONRPCRequestPayload, next: () => void, end: (err: Error|null, result?: any) => void,
|
payload: Web3.JSONRPCRequestPayload,
|
||||||
|
next: () => void,
|
||||||
|
end: (err: Error | null, result?: any) => void,
|
||||||
) {
|
) {
|
||||||
let accounts;
|
let accounts;
|
||||||
let txParams;
|
let txParams;
|
||||||
@ -132,7 +133,9 @@ export class LedgerSubprovider extends Subprovider {
|
|||||||
let ledgerResponse;
|
let ledgerResponse;
|
||||||
try {
|
try {
|
||||||
ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
|
ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
|
||||||
this._derivationPath, this._shouldAlwaysAskForConfirmation, SHOULD_GET_CHAIN_CODE,
|
this._derivationPath,
|
||||||
|
this._shouldAlwaysAskForConfirmation,
|
||||||
|
SHOULD_GET_CHAIN_CODE,
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
await this._destroyLedgerClientAsync();
|
await this._destroyLedgerClientAsync();
|
||||||
@ -147,9 +150,9 @@ export class LedgerSubprovider extends Subprovider {
|
|||||||
const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
|
const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
|
||||||
const derivedPublicKey = derivedHDNode.publicKey;
|
const derivedPublicKey = derivedHDNode.publicKey;
|
||||||
const shouldSanitizePublicKey = true;
|
const shouldSanitizePublicKey = true;
|
||||||
const ethereumAddressUnprefixed = ethUtil.publicToAddress(
|
const ethereumAddressUnprefixed = ethUtil
|
||||||
derivedPublicKey, shouldSanitizePublicKey,
|
.publicToAddress(derivedPublicKey, shouldSanitizePublicKey)
|
||||||
).toString('hex');
|
.toString('hex');
|
||||||
const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
|
const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
|
||||||
accounts.push(ethereumAddressPrefixed.toLowerCase());
|
accounts.push(ethereumAddressPrefixed.toLowerCase());
|
||||||
}
|
}
|
||||||
@ -195,7 +198,9 @@ export class LedgerSubprovider extends Subprovider {
|
|||||||
try {
|
try {
|
||||||
const derivationPath = this._getDerivationPath();
|
const derivationPath = this._getDerivationPath();
|
||||||
const result = await this._ledgerClientIfExists.signPersonalMessage_async(
|
const result = await this._ledgerClientIfExists.signPersonalMessage_async(
|
||||||
derivationPath, ethUtil.stripHexPrefix(data));
|
derivationPath,
|
||||||
|
ethUtil.stripHexPrefix(data),
|
||||||
|
);
|
||||||
const v = result.v - 27;
|
const v = result.v - 27;
|
||||||
let vHex = v.toString(16);
|
let vHex = v.toString(16);
|
||||||
if (vHex.length < 2) {
|
if (vHex.length < 2) {
|
||||||
|
@ -9,7 +9,9 @@ import {Subprovider} from './subprovider';
|
|||||||
export class RedundantRPCSubprovider extends Subprovider {
|
export class RedundantRPCSubprovider extends Subprovider {
|
||||||
private _rpcs: RpcSubprovider[];
|
private _rpcs: RpcSubprovider[];
|
||||||
private static async _firstSuccessAsync(
|
private static async _firstSuccessAsync(
|
||||||
rpcs: RpcSubprovider[], payload: JSONRPCPayload, next: () => void,
|
rpcs: RpcSubprovider[],
|
||||||
|
payload: JSONRPCPayload,
|
||||||
|
next: () => void,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
let lastErr: Error | undefined;
|
let lastErr: Error | undefined;
|
||||||
for (const rpc of rpcs) {
|
for (const rpc of rpcs) {
|
||||||
@ -34,8 +36,11 @@ export class RedundantRPCSubprovider extends Subprovider {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// tslint:disable-next-line:async-suffix
|
// tslint:disable-next-line:async-suffix
|
||||||
public async handleRequest(payload: JSONRPCPayload, next: () => void,
|
public async handleRequest(
|
||||||
end: (err: Error|null, data?: any) => void): Promise<void> {
|
payload: JSONRPCPayload,
|
||||||
|
next: () => void,
|
||||||
|
end: (err: Error | null, data?: any) => void,
|
||||||
|
): Promise<void> {
|
||||||
const rpcsCopy = this._rpcs.slice();
|
const rpcsCopy = this._rpcs.slice();
|
||||||
try {
|
try {
|
||||||
const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
|
const data = await RedundantRPCSubprovider._firstSuccessAsync(rpcsCopy, payload, next);
|
||||||
@ -43,6 +48,5 @@ export class RedundantRPCSubprovider extends Subprovider {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
end(err);
|
end(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user