aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--packages/0x.js/CHANGELOG.json4
-rw-r--r--packages/abi-gen/CHANGELOG.json13
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts36
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts3
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts3
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts3
-rw-r--r--packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts3
-rw-r--r--packages/contract-wrappers/test/subscription_test.ts38
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol16
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol16
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol8
-rw-r--r--packages/contracts/test/exchange/core.ts160
-rw-r--r--packages/contracts/test/exchange/libs.ts2
-rw-r--r--packages/contracts/test/exchange/match_orders.ts80
-rw-r--r--packages/contracts/test/exchange/signature_validator.ts2
-rw-r--r--packages/contracts/test/exchange/transactions.ts8
-rw-r--r--packages/contracts/test/exchange/wrapper.ts248
-rw-r--r--packages/contracts/test/forwarder/forwarder.ts54
-rw-r--r--packages/contracts/test/multisig/asset_proxy_owner.ts2
-rw-r--r--packages/contracts/test/multisig/multi_sig_with_time_lock.ts2
-rw-r--r--packages/contracts/test/utils/block_timestamp.ts (renamed from packages/contracts/test/utils/increase_time.ts)9
-rw-r--r--packages/contracts/test/utils/exchange_wrapper.ts4
-rw-r--r--packages/contracts/test/utils/order_factory.ts11
-rw-r--r--packages/dev-utils/src/blockchain_lifecycle.ts39
-rw-r--r--packages/order-watcher/CHANGELOG.json8
-rw-r--r--packages/order-watcher/src/order_watcher/event_watcher.ts12
-rw-r--r--packages/order-watcher/src/order_watcher/order_watcher.ts9
-rw-r--r--packages/order-watcher/src/types.ts4
-rw-r--r--packages/website/ts/pages/about/about.tsx16
-rw-r--r--packages/website/ts/utils/constants.ts2
30 files changed, 572 insertions, 243 deletions
diff --git a/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json
index 3ec09cd7e..9419311dd 100644
--- a/packages/0x.js/CHANGELOG.json
+++ b/packages/0x.js/CHANGELOG.json
@@ -32,6 +32,10 @@
{
"note": "0x.js exports renamed contract events and event arg types",
"pr": 863
+ },
+ {
+ "note": "Remove stateLayer config from OrderWatcher. It now always operates on the latest block",
+ "pr": 875
}
]
},
diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json
index ef8f5dd39..933ffe30c 100644
--- a/packages/abi-gen/CHANGELOG.json
+++ b/packages/abi-gen/CHANGELOG.json
@@ -1,14 +1,5 @@
[
{
- "version": "0.4.1",
- "changes": [
- {
- "note": "skip generation of wrappers that are already up to date",
- "pr": 788
- }
- ]
- },
- {
"version": "0.4.0",
"changes": [
{
@@ -18,6 +9,10 @@
{
"note": "Remove the output directory before writing to it",
"pr": 822
+ },
+ {
+ "note": "skip generation of wrappers that are already up to date",
+ "pr": 788
}
]
},
diff --git a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
index b8ca4d29b..daf70253a 100644
--- a/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/contract_wrapper.ts
@@ -1,5 +1,5 @@
import { ContractArtifact } from '@0xproject/sol-compiler';
-import { AbiDecoder, intervalUtils } from '@0xproject/utils';
+import { AbiDecoder, intervalUtils, logUtils } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { BlockParamLiteral, ContractAbi, FilterObject, LogEntry, LogWithDecodedArgs, RawLog } from 'ethereum-types';
import { Block, BlockAndLogStreamer, Log } from 'ethereumjs-blockstream';
@@ -41,6 +41,13 @@ export abstract class ContractWrapper {
};
private _onLogAddedSubscriptionToken: string | undefined;
private _onLogRemovedSubscriptionToken: string | undefined;
+ private static _onBlockAndLogStreamerError(isVerbose: boolean, err: Error): void {
+ // Since Blockstream errors are all recoverable, we simply log them if the verbose
+ // config is passed in.
+ if (isVerbose) {
+ logUtils.warn(err);
+ }
+ }
constructor(web3Wrapper: Web3Wrapper, networkId: number, blockPollingIntervalMs?: number) {
this._web3Wrapper = web3Wrapper;
this._networkId = networkId;
@@ -79,10 +86,11 @@ export abstract class ContractWrapper {
indexFilterValues: IndexedFilterValues,
abi: ContractAbi,
callback: EventCallback<ArgsType>,
+ isVerbose: boolean = false,
): string {
const filter = filterUtils.getFilter(address, eventName, indexFilterValues, abi);
if (_.isUndefined(this._blockAndLogStreamerIfExists)) {
- this._startBlockAndLogStream();
+ this._startBlockAndLogStream(isVerbose);
}
const filterToken = filterUtils.generateUUID();
this._filters[filterToken] = filter;
@@ -151,21 +159,21 @@ export abstract class ContractWrapper {
}
});
}
- private _startBlockAndLogStream(): void {
+ private _startBlockAndLogStream(isVerbose: boolean): void {
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
throw new Error(ContractWrappersError.SubscriptionAlreadyPresent);
}
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
- this._onBlockAndLogStreamerError.bind(this),
+ ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose),
);
const catchAllLogFilter = {};
this._blockAndLogStreamerIfExists.addLogFilter(catchAllLogFilter);
this._blockAndLogStreamIntervalIfExists = intervalUtils.setAsyncExcludingInterval(
this._reconcileBlockAsync.bind(this),
this._blockPollingIntervalMs,
- this._onReconcileBlockError.bind(this),
+ ContractWrapper._onBlockAndLogStreamerError.bind(this, isVerbose),
);
let isRemoved = false;
this._onLogAddedSubscriptionToken = this._blockAndLogStreamerIfExists.subscribeToOnLogAdded(
@@ -176,20 +184,10 @@ export abstract class ContractWrapper {
this._onLogStateChanged.bind(this, isRemoved),
);
}
- private _onBlockAndLogStreamerError(err: Error): void {
- // Propogate all Blockstream subscriber errors to all
- // top-level subscriptions
- const filterCallbacks = _.values(this._filterCallbacks);
- _.each(filterCallbacks, filterCallback => {
- filterCallback(err);
- });
- }
- private _onReconcileBlockError(err: Error): void {
- const filterTokens = _.keys(this._filterCallbacks);
- _.each(filterTokens, filterToken => {
- this._unsubscribe(filterToken, err);
- });
- }
+ // HACK: This should be a package-scoped method (which doesn't exist in TS)
+ // We don't want this method available in the public interface for all classes
+ // who inherit from ContractWrapper, and it is only used by the internal implementation
+ // of those higher classes.
// tslint:disable-next-line:no-unused-variable
private _setNetworkId(networkId: number): void {
this._networkId = networkId;
diff --git a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts
index 29c63564e..17bda5085 100644
--- a/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/erc20_token_wrapper.ts
@@ -347,6 +347,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
* @param indexFilterValues An object where the keys are indexed args returned by the event and
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
* @param callback Callback that gets called when a log is added/removed
+ * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
* @return Subscription token used later to unsubscribe
*/
public subscribe<ArgsType extends ERC20TokenEventArgs>(
@@ -354,6 +355,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
eventName: ERC20TokenEvents,
indexFilterValues: IndexedFilterValues,
callback: EventCallback<ArgsType>,
+ isVerbose: boolean = false,
): string {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.doesBelongToStringEnum('eventName', eventName, ERC20TokenEvents);
@@ -366,6 +368,7 @@ export class ERC20TokenWrapper extends ContractWrapper {
indexFilterValues,
artifacts.ERC20Token.compilerOutput.abi,
callback,
+ isVerbose,
);
return subscriptionToken;
}
diff --git a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts
index b7e5519c4..3d24702b3 100644
--- a/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/erc721_token_wrapper.ts
@@ -372,6 +372,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
* @param indexFilterValues An object where the keys are indexed args returned by the event and
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
* @param callback Callback that gets called when a log is added/removed
+ * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
* @return Subscription token used later to unsubscribe
*/
public subscribe<ArgsType extends ERC721TokenEventArgs>(
@@ -379,6 +380,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
eventName: ERC721TokenEvents,
indexFilterValues: IndexedFilterValues,
callback: EventCallback<ArgsType>,
+ isVerbose: boolean = false,
): string {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.doesBelongToStringEnum('eventName', eventName, ERC721TokenEvents);
@@ -391,6 +393,7 @@ export class ERC721TokenWrapper extends ContractWrapper {
indexFilterValues,
artifacts.ERC721Token.compilerOutput.abi,
callback,
+ isVerbose,
);
return subscriptionToken;
}
diff --git a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts
index 01440a5e1..5046d3667 100644
--- a/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/ether_token_wrapper.ts
@@ -146,6 +146,7 @@ export class EtherTokenWrapper extends ContractWrapper {
* @param indexFilterValues An object where the keys are indexed args returned by the event and
* the value is the value you are interested in. E.g `{_owner: aUserAddressHex}`
* @param callback Callback that gets called when a log is added/removed
+ * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
* @return Subscription token used later to unsubscribe
*/
public subscribe<ArgsType extends WETH9EventArgs>(
@@ -153,6 +154,7 @@ export class EtherTokenWrapper extends ContractWrapper {
eventName: WETH9Events,
indexFilterValues: IndexedFilterValues,
callback: EventCallback<ArgsType>,
+ isVerbose: boolean = false,
): string {
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
@@ -165,6 +167,7 @@ export class EtherTokenWrapper extends ContractWrapper {
indexFilterValues,
artifacts.EtherToken.compilerOutput.abi,
callback,
+ isVerbose,
);
return subscriptionToken;
}
diff --git a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
index 8b7148aed..0791c62f5 100644
--- a/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
+++ b/packages/contract-wrappers/src/contract_wrappers/exchange_wrapper.ts
@@ -988,12 +988,14 @@ export class ExchangeWrapper extends ContractWrapper {
* @param indexFilterValues An object where the keys are indexed args returned by the event and
* the value is the value you are interested in. E.g `{maker: aUserAddressHex}`
* @param callback Callback that gets called when a log is added/removed
+ * @param isVerbose Enable verbose subscription warnings (e.g recoverable network issues encountered)
* @return Subscription token used later to unsubscribe
*/
public subscribe<ArgsType extends ExchangeEventArgs>(
eventName: ExchangeEvents,
indexFilterValues: IndexedFilterValues,
callback: EventCallback<ArgsType>,
+ isVerbose: boolean = false,
): string {
assert.doesBelongToStringEnum('eventName', eventName, ExchangeEvents);
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
@@ -1005,6 +1007,7 @@ export class ExchangeWrapper extends ContractWrapper {
indexFilterValues,
artifacts.Exchange.compilerOutput.abi,
callback,
+ isVerbose,
);
return subscriptionToken;
}
diff --git a/packages/contract-wrappers/test/subscription_test.ts b/packages/contract-wrappers/test/subscription_test.ts
index adda4ab78..80d17576f 100644
--- a/packages/contract-wrappers/test/subscription_test.ts
+++ b/packages/contract-wrappers/test/subscription_test.ts
@@ -49,44 +49,6 @@ describe('SubscriptionTest', () => {
_.each(stubs, s => s.restore());
stubs = [];
});
- it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => {
- (async () => {
- const errMsg = 'Error fetching block';
- const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
- stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))];
- contractWrappers.erc20Token.subscribe(
- tokenAddress,
- ERC20TokenEvents.Approval,
- indexFilterValues,
- callback,
- );
- await contractWrappers.erc20Token.setAllowanceAsync(
- tokenAddress,
- coinbase,
- addressWithoutFunds,
- allowanceAmount,
- );
- })().catch(done);
- });
- it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => {
- (async () => {
- const errMsg = 'Error fetching logs';
- const callback = callbackErrorReporter.assertNodeCallbackError(done, errMsg);
- stubs = [Sinon.stub((contractWrappers as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))];
- contractWrappers.erc20Token.subscribe(
- tokenAddress,
- ERC20TokenEvents.Approval,
- indexFilterValues,
- callback,
- );
- await contractWrappers.erc20Token.setAllowanceAsync(
- tokenAddress,
- coinbase,
- addressWithoutFunds,
- allowanceAmount,
- );
- })().catch(done);
- });
it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => {
(async () => {
const callback = (err: Error | null, _logEvent?: DecodedLogEvent<ERC20TokenApprovalEventArgs>) =>
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol
index ec84b1e19..6f435892b 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinExchangeCore.sol
@@ -154,6 +154,9 @@ contract MixinExchangeCore is
// Compute the order hash
orderInfo.orderHash = getOrderHash(order);
+ // Fetch filled amount
+ orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];
+
// If order.makerAssetAmount is zero, we also reject the order.
// While the Exchange contract handles them correctly, they create
// edge cases in the supporting infrastructure because they have
@@ -172,6 +175,12 @@ contract MixinExchangeCore is
return orderInfo;
}
+ // Validate order availability
+ if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {
+ orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);
+ return orderInfo;
+ }
+
// Validate order expiration
// solhint-disable-next-line not-rely-on-time
if (block.timestamp >= order.expirationTimeSeconds) {
@@ -189,13 +198,6 @@ contract MixinExchangeCore is
return orderInfo;
}
- // Fetch filled amount and validate order availability
- orderInfo.orderTakerAssetFilledAmount = filled[orderInfo.orderHash];
- if (orderInfo.orderTakerAssetFilledAmount >= order.takerAssetAmount) {
- orderInfo.orderStatus = uint8(OrderStatus.FULLY_FILLED);
- return orderInfo;
- }
-
// All other statuses are ruled out: order is Fillable
orderInfo.orderStatus = uint8(OrderStatus.FILLABLE);
return orderInfo;
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol
index a16d2f897..d420f7e85 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/MixinWrapperFunctions.sol
@@ -529,4 +529,20 @@ contract MixinWrapperFunctions is
cancelOrder(orders[i]);
}
}
+
+ /// @dev Fetches information for all passed in orders.
+ /// @param orders Array of order specifications.
+ /// @return Array of OrderInfo instances that correspond to each order.
+ function getOrdersInfo(LibOrder.Order[] memory orders)
+ public
+ view
+ returns (LibOrder.OrderInfo[] memory)
+ {
+ uint256 length = orders.length;
+ LibOrder.OrderInfo[] memory ordersInfo = new LibOrder.OrderInfo[](length);
+ for (uint256 i = 0; i < length; i++) {
+ ordersInfo[i] = getOrderInfo(orders[i]);
+ }
+ return ordersInfo;
+ }
}
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol
index ad7a56a06..56a533646 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/interfaces/IWrapperFunctions.sol
@@ -149,4 +149,12 @@ contract IWrapperFunctions {
/// @param orders Array of order specifications.
function batchCancelOrders(LibOrder.Order[] memory orders)
public;
+
+ /// @dev Fetches information for all passed in orders
+ /// @param orders Array of order specifications.
+ /// @return Array of OrderInfo instances that correspond to each order.
+ function getOrdersInfo(LibOrder.Order[] memory orders)
+ public
+ view
+ returns (LibOrder.OrderInfo[] memory);
}
diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts
index d9f3851d1..1eb6f2a5c 100644
--- a/packages/contracts/test/exchange/core.ts
+++ b/packages/contracts/test/exchange/core.ts
@@ -15,13 +15,14 @@ import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_pr
import { ExchangeCancelEventArgs, ExchangeContract } from '../../generated_contract_wrappers/exchange';
import { artifacts } from '../utils/artifacts';
import { expectTransactionFailedAsync } from '../utils/assertions';
+import { getLatestBlockTimestampAsync, increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants';
import { ERC20Wrapper } from '../utils/erc20_wrapper';
import { ERC721Wrapper } from '../utils/erc721_wrapper';
import { ExchangeWrapper } from '../utils/exchange_wrapper';
import { OrderFactory } from '../utils/order_factory';
-import { ERC20BalancesByOwner } from '../utils/types';
+import { ERC20BalancesByOwner, OrderStatus } from '../utils/types';
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
chaiSetup.configure();
@@ -129,11 +130,11 @@ describe('Exchange core', () => {
describe('fillOrder', () => {
beforeEach(async () => {
erc20Balances = await erc20Wrapper.getBalancesAsync();
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
});
it('should throw if signature is invalid', async () => {
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
});
@@ -151,7 +152,7 @@ describe('Exchange core', () => {
});
it('should throw if no value is filled', async () => {
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
return expectTransactionFailedAsync(
exchangeWrapper.fillOrderAsync(signedOrder, takerAddress),
@@ -163,7 +164,7 @@ describe('Exchange core', () => {
describe('cancelOrder', () => {
beforeEach(async () => {
erc20Balances = await erc20Wrapper.getBalancesAsync();
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
});
it('should throw if not sent by maker', async () => {
@@ -174,7 +175,7 @@ describe('Exchange core', () => {
});
it('should throw if makerAssetAmount is 0', async () => {
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(0),
});
@@ -185,7 +186,7 @@ describe('Exchange core', () => {
});
it('should throw if takerAssetAmount is 0', async () => {
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
takerAssetAmount: new BigNumber(0),
});
@@ -229,8 +230,9 @@ describe('Exchange core', () => {
});
it('should throw if order is expired', async () => {
- signedOrder = orderFactory.newSignedOrder({
- expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ signedOrder = await orderFactory.newSignedOrderAsync({
+ expirationTimeSeconds: new BigNumber(currentTimestamp).sub(10),
});
return expectTransactionFailedAsync(
exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress),
@@ -239,7 +241,7 @@ describe('Exchange core', () => {
});
it('should throw if rounding error is greater than 0.1%', async () => {
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1001),
takerAssetAmount: new BigNumber(3),
});
@@ -288,22 +290,22 @@ describe('Exchange core', () => {
// Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed
erc20Balances = await erc20Wrapper.getBalancesAsync();
const signedOrders = [
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(9), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(9), 18),
salt: new BigNumber(0),
}),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(79), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(79), 18),
salt: new BigNumber(1),
}),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(979), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(979), 18),
salt: new BigNumber(2),
}),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(7979), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(7979), 18),
salt: new BigNumber(3),
@@ -350,7 +352,7 @@ describe('Exchange core', () => {
// Construct Exchange parameters
const makerAssetId = erc721TakerAssetIds[0];
const takerAssetId = erc721TakerAssetIds[1];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -373,7 +375,7 @@ describe('Exchange core', () => {
// Construct Exchange parameters
const makerAssetId = erc721MakerAssetIds[0];
const takerAssetId = erc721MakerAssetIds[1];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -396,7 +398,7 @@ describe('Exchange core', () => {
// Construct Exchange parameters
const makerAssetId = erc721MakerAssetIds[0];
const takerAssetId = erc721TakerAssetIds[0];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(2),
takerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -419,7 +421,7 @@ describe('Exchange core', () => {
// Construct Exchange parameters
const makerAssetId = erc721MakerAssetIds[0];
const takerAssetId = erc721TakerAssetIds[0];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerAssetAmount: new BigNumber(500),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -441,7 +443,7 @@ describe('Exchange core', () => {
it('should throw on partial fill', async () => {
// Construct Exchange parameters
const makerAssetId = erc721MakerAssetIds[0];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -462,7 +464,7 @@ describe('Exchange core', () => {
const makerAssetData = assetProxyUtils
.encodeERC721AssetData(erc721Token.address, makerAssetId)
.slice(0, -2);
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerAssetAmount: new BigNumber(1),
makerAssetData,
@@ -481,6 +483,124 @@ describe('Exchange core', () => {
);
});
});
+
+ describe('getOrderInfo', () => {
+ beforeEach(async () => {
+ signedOrder = await orderFactory.newSignedOrderAsync();
+ });
+ it('should return the correct orderInfo for an unfilled valid order', async () => {
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.FILLABLE;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for a fully filled order', async () => {
+ await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
+ const expectedOrderStatus = OrderStatus.FULLY_FILLED;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for a partially filled order', async () => {
+ const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
+ await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = takerAssetFillAmount;
+ const expectedOrderStatus = OrderStatus.FILLABLE;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for a cancelled and unfilled order', async () => {
+ await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.CANCELLED;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for a cancelled and partially filled order', async () => {
+ const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
+ await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
+ await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = takerAssetFillAmount;
+ const expectedOrderStatus = OrderStatus.CANCELLED;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for an expired and unfilled order', async () => {
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
+ await increaseTimeAndMineBlockAsync(timeUntilExpiration);
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.EXPIRED;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for an expired and partially filled order', async () => {
+ const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
+ await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
+ await increaseTimeAndMineBlockAsync(timeUntilExpiration);
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = takerAssetFillAmount;
+ const expectedOrderStatus = OrderStatus.EXPIRED;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for an expired and fully filled order', async () => {
+ await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
+ await increaseTimeAndMineBlockAsync(timeUntilExpiration);
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
+ // FULLY_FILLED takes precedence over EXPIRED
+ const expectedOrderStatus = OrderStatus.FULLY_FILLED;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for an order with a makerAssetAmount of 0', async () => {
+ signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(0) });
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.INVALID_MAKER_ASSET_AMOUNT;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ it('should return the correct orderInfo for an order with a takerAssetAmount of 0', async () => {
+ signedOrder = await orderFactory.newSignedOrderAsync({ takerAssetAmount: new BigNumber(0) });
+ const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.INVALID_TAKER_ASSET_AMOUNT;
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
});
// tslint:disable:max-file-line-count
// tslint:enable:no-unnecessary-type-assertion
diff --git a/packages/contracts/test/exchange/libs.ts b/packages/contracts/test/exchange/libs.ts
index 6ded6329c..af595fedd 100644
--- a/packages/contracts/test/exchange/libs.ts
+++ b/packages/contracts/test/exchange/libs.ts
@@ -71,7 +71,7 @@ describe('Exchange libs', () => {
});
describe('getOrderHash', () => {
it('should output the correct orderHash', async () => {
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
const orderHashHex = await libs.publicGetOrderHash.callAsync(signedOrder);
expect(orderHashUtils.getOrderHashHex(signedOrder)).to.be.equal(orderHashHex);
});
diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts
index 16041e968..6975aa115 100644
--- a/packages/contracts/test/exchange/match_orders.ts
+++ b/packages/contracts/test/exchange/match_orders.ts
@@ -150,13 +150,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts when orders completely fill each other', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -182,13 +182,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts when orders completely fill each other and taker doesnt take a profit', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -225,13 +225,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts when left order is completely filled and right order is partially filled', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -257,13 +257,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts when right order is completely filled and left order is partially filled', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -289,13 +289,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts when consecutive calls are used to completely fill the left order', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -326,7 +326,7 @@ describe('matchOrders', () => {
// Note: This order needs makerAssetAmount=90/takerAssetAmount=[anything <= 45] to fully fill the right order.
// However, we use 100/50 to ensure a partial fill as we want to go down the "left fill"
// branch in the contract twice for this test.
- const signedOrderRight2 = orderFactoryRight.newSignedOrder({
+ const signedOrderRight2 = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -356,14 +356,14 @@ describe('matchOrders', () => {
it('should transfer the correct amounts when consecutive calls are used to completely fill the right order', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(2), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -394,7 +394,7 @@ describe('matchOrders', () => {
// Note: This order needs makerAssetAmount=96/takerAssetAmount=48 to fully fill the right order.
// However, we use 100/50 to ensure a partial fill as we want to go down the "right fill"
// branch in the contract twice for this test.
- const signedOrderLeft2 = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft2 = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), 18),
@@ -425,13 +425,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts if fee recipient is the same across both matched orders', async () => {
const feeRecipientAddress = feeRecipientAddressLeft;
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -451,13 +451,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts if taker is also the left order maker', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -478,13 +478,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts if taker is also the right order maker', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -505,13 +505,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts if taker is also the left fee recipient', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -532,13 +532,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts if taker is also the right fee recipient', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -559,13 +559,13 @@ describe('matchOrders', () => {
it('should transfer the correct amounts if left maker is the left fee recipient and right maker is the right fee recipient', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: makerAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -585,13 +585,13 @@ describe('matchOrders', () => {
it('Should throw if left order is not fillable', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -610,13 +610,13 @@ describe('matchOrders', () => {
it('Should throw if right order is not fillable', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -635,13 +635,13 @@ describe('matchOrders', () => {
it('should throw if there is not a positive spread', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -658,13 +658,13 @@ describe('matchOrders', () => {
it('should throw if the left maker asset is not equal to the right taker asset ', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(5), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
@@ -685,7 +685,7 @@ describe('matchOrders', () => {
it('should throw if the right maker asset is not equal to the left taker asset', async () => {
// Create orders to match
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -693,7 +693,7 @@ describe('matchOrders', () => {
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
@@ -711,7 +711,7 @@ describe('matchOrders', () => {
it('should transfer correct amounts when left order maker asset is an ERC721 token', async () => {
// Create orders to match
const erc721TokenToTransfer = erc721LeftMakerAssetIds[0];
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
@@ -719,7 +719,7 @@ describe('matchOrders', () => {
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), 18),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
@@ -746,7 +746,7 @@ describe('matchOrders', () => {
it('should transfer correct amounts when right order maker asset is an ERC721 token', async () => {
// Create orders to match
const erc721TokenToTransfer = erc721RightMakerAssetIds[0];
- const signedOrderLeft = orderFactoryLeft.newSignedOrder({
+ const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({
makerAddress: makerAddressLeft,
makerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
takerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
@@ -754,7 +754,7 @@ describe('matchOrders', () => {
takerAssetAmount: new BigNumber(1),
feeRecipientAddress: feeRecipientAddressLeft,
});
- const signedOrderRight = orderFactoryRight.newSignedOrder({
+ const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({
makerAddress: makerAddressRight,
makerAssetData: assetProxyUtils.encodeERC721AssetData(defaultERC721AssetAddress, erc721TokenToTransfer),
takerAssetData: assetProxyUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress),
diff --git a/packages/contracts/test/exchange/signature_validator.ts b/packages/contracts/test/exchange/signature_validator.ts
index 8cd6409a5..2f4a9055d 100644
--- a/packages/contracts/test/exchange/signature_validator.ts
+++ b/packages/contracts/test/exchange/signature_validator.ts
@@ -95,7 +95,7 @@ describe('MixinSignatureValidator', () => {
describe('isValidSignature', () => {
beforeEach(async () => {
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
});
it('should revert when signature is empty', async () => {
diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts
index 0d66b11b8..831576cd2 100644
--- a/packages/contracts/test/exchange/transactions.ts
+++ b/packages/contracts/test/exchange/transactions.ts
@@ -121,7 +121,7 @@ describe('Exchange transactions', () => {
let takerAssetFillAmount: BigNumber;
beforeEach(async () => {
erc20Balances = await erc20Wrapper.getBalancesAsync();
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
orderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(signedOrder);
takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
@@ -226,7 +226,7 @@ describe('Exchange transactions', () => {
it("should cancel an order if called from the order's sender", async () => {
const orderSalt = new BigNumber(0);
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
senderAddress: exchangeWrapperContract.address,
salt: orderSalt,
});
@@ -265,7 +265,7 @@ describe('Exchange transactions', () => {
it("should not cancel an order if not called from the order's sender", async () => {
const orderSalt = new BigNumber(0);
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
senderAddress: exchangeWrapperContract.address,
salt: orderSalt,
});
@@ -356,7 +356,7 @@ describe('Exchange transactions', () => {
});
beforeEach(async () => {
- signedOrder = whitelistOrderFactory.newSignedOrder();
+ signedOrder = await whitelistOrderFactory.newSignedOrderAsync();
erc20Balances = await erc20Wrapper.getBalancesAsync();
});
diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts
index 655d55b83..abcb8364a 100644
--- a/packages/contracts/test/exchange/wrapper.ts
+++ b/packages/contracts/test/exchange/wrapper.ts
@@ -1,5 +1,5 @@
import { BlockchainLifecycle } from '@0xproject/dev-utils';
-import { assetProxyUtils } from '@0xproject/order-utils';
+import { assetProxyUtils, orderHashUtils } from '@0xproject/order-utils';
import { RevertReason, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
@@ -13,13 +13,14 @@ import { ERC721ProxyContract } from '../../generated_contract_wrappers/erc721_pr
import { ExchangeContract } from '../../generated_contract_wrappers/exchange';
import { artifacts } from '../utils/artifacts';
import { expectTransactionFailedAsync } from '../utils/assertions';
+import { getLatestBlockTimestampAsync, increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants';
import { ERC20Wrapper } from '../utils/erc20_wrapper';
import { ERC721Wrapper } from '../utils/erc721_wrapper';
import { ExchangeWrapper } from '../utils/exchange_wrapper';
import { OrderFactory } from '../utils/order_factory';
-import { ERC20BalancesByOwner } from '../utils/types';
+import { ERC20BalancesByOwner, OrderStatus } from '../utils/types';
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
chaiSetup.configure();
@@ -126,7 +127,7 @@ describe('Exchange wrappers', () => {
});
describe('fillOrKillOrder', () => {
it('should transfer the correct amounts', async () => {
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
});
@@ -170,8 +171,9 @@ describe('Exchange wrappers', () => {
});
it('should throw if a signedOrder is expired', async () => {
- const signedOrder = orderFactory.newSignedOrder({
- expirationTimeSeconds: new BigNumber(Math.floor((Date.now() - 10000) / 1000)),
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const signedOrder = await orderFactory.newSignedOrderAsync({
+ expirationTimeSeconds: new BigNumber(currentTimestamp).sub(10),
});
return expectTransactionFailedAsync(
@@ -181,7 +183,7 @@ describe('Exchange wrappers', () => {
});
it('should throw if entire takerAssetFillAmount not filled', async () => {
- const signedOrder = orderFactory.newSignedOrder();
+ const signedOrder = await orderFactory.newSignedOrderAsync();
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
@@ -196,7 +198,7 @@ describe('Exchange wrappers', () => {
describe('fillOrderNoThrow', () => {
it('should transfer the correct amounts', async () => {
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18),
});
@@ -245,7 +247,7 @@ describe('Exchange wrappers', () => {
});
it('should not change erc20Balances if maker erc20Balances are too low to fill order', async () => {
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
});
@@ -255,7 +257,7 @@ describe('Exchange wrappers', () => {
});
it('should not change erc20Balances if taker erc20Balances are too low to fill order', async () => {
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18),
});
@@ -265,7 +267,7 @@ describe('Exchange wrappers', () => {
});
it('should not change erc20Balances if maker allowances are too low to fill order', async () => {
- const signedOrder = orderFactory.newSignedOrder();
+ const signedOrder = await orderFactory.newSignedOrderAsync();
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20TokenA.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
from: makerAddress,
@@ -285,7 +287,7 @@ describe('Exchange wrappers', () => {
});
it('should not change erc20Balances if taker allowances are too low to fill order', async () => {
- const signedOrder = orderFactory.newSignedOrder();
+ const signedOrder = await orderFactory.newSignedOrderAsync();
await web3Wrapper.awaitTransactionSuccessAsync(
await erc20TokenB.approve.sendTransactionAsync(erc20Proxy.address, new BigNumber(0), {
from: takerAddress,
@@ -306,7 +308,7 @@ describe('Exchange wrappers', () => {
it('should not change erc20Balances if makerAssetAddress is ZRX, makerAssetAmount + makerFee > maker balance', async () => {
const makerZRXBalance = new BigNumber(erc20Balances[makerAddress][zrxToken.address]);
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: makerZRXBalance,
makerFee: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
@@ -318,7 +320,7 @@ describe('Exchange wrappers', () => {
it('should not change erc20Balances if makerAssetAddress is ZRX, makerAssetAmount + makerFee > maker allowance', async () => {
const makerZRXAllowance = await zrxToken.allowance.callAsync(makerAddress, erc20Proxy.address);
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(makerZRXAllowance),
makerFee: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
@@ -330,7 +332,7 @@ describe('Exchange wrappers', () => {
it('should not change erc20Balances if takerAssetAddress is ZRX, takerAssetAmount + takerFee > taker balance', async () => {
const takerZRXBalance = new BigNumber(erc20Balances[takerAddress][zrxToken.address]);
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
takerAssetAmount: takerZRXBalance,
takerFee: new BigNumber(1),
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
@@ -342,7 +344,7 @@ describe('Exchange wrappers', () => {
it('should not change erc20Balances if takerAssetAddress is ZRX, takerAssetAmount + takerFee > taker allowance', async () => {
const takerZRXAllowance = await zrxToken.allowance.callAsync(takerAddress, erc20Proxy.address);
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
takerAssetAmount: new BigNumber(takerZRXAllowance),
takerFee: new BigNumber(1),
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
@@ -356,7 +358,7 @@ describe('Exchange wrappers', () => {
// Construct Exchange parameters
const makerAssetId = erc721MakerAssetId;
const takerAssetId = erc721TakerAssetId;
- const signedOrder = orderFactory.newSignedOrder({
+ const signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -388,9 +390,9 @@ describe('Exchange wrappers', () => {
let signedOrders: SignedOrder[];
beforeEach(async () => {
signedOrders = [
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder(),
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync(),
];
});
@@ -696,11 +698,11 @@ describe('Exchange wrappers', () => {
it('should throw when a signedOrder does not use the same takerAssetAddress', async () => {
signedOrders = [
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync({
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
}),
- orderFactory.newSignedOrder(),
+ await orderFactory.newSignedOrderAsync(),
];
return expectTransactionFailedAsync(
@@ -796,9 +798,9 @@ describe('Exchange wrappers', () => {
it('should not fill a signedOrder that does not use the same takerAssetAddress', async () => {
signedOrders = [
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync({
takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
}),
];
@@ -914,11 +916,11 @@ describe('Exchange wrappers', () => {
it('should throw when a signedOrder does not use the same makerAssetAddress', async () => {
signedOrders = [
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
}),
- orderFactory.newSignedOrder(),
+ await orderFactory.newSignedOrderAsync(),
];
return expectTransactionFailedAsync(
@@ -1012,9 +1014,9 @@ describe('Exchange wrappers', () => {
it('should not fill a signedOrder that does not use the same makerAssetAddress', async () => {
signedOrders = [
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder(),
- orderFactory.newSignedOrder({
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
}),
];
@@ -1069,5 +1071,189 @@ describe('Exchange wrappers', () => {
expect(erc20Balances).to.be.deep.equal(newBalances);
});
});
+
+ describe('getOrdersInfo', () => {
+ beforeEach(async () => {
+ signedOrders = [
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync(),
+ await orderFactory.newSignedOrderAsync(),
+ ];
+ });
+ it('should get the correct information for multiple unfilled orders', async () => {
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.FILLABLE;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for multiple partially filled orders', async () => {
+ const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
+ await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
+ const expectedOrderStatus = OrderStatus.FILLABLE;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for multiple fully filled orders', async () => {
+ await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress);
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
+ const expectedOrderStatus = OrderStatus.FULLY_FILLED;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for multiple cancelled and unfilled orders', async () => {
+ await exchangeWrapper.batchCancelOrdersAsync(signedOrders, makerAddress);
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.CANCELLED;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for multiple cancelled and partially filled orders', async () => {
+ const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
+ await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
+ await exchangeWrapper.batchCancelOrdersAsync(signedOrders, makerAddress);
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
+ const expectedOrderStatus = OrderStatus.CANCELLED;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for multiple expired and unfilled orders', async () => {
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const timeUntilExpiration = signedOrders[0].expirationTimeSeconds.minus(currentTimestamp).toNumber();
+ await increaseTimeAndMineBlockAsync(timeUntilExpiration);
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = new BigNumber(0);
+ const expectedOrderStatus = OrderStatus.EXPIRED;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for multiple expired and partially filled orders', async () => {
+ const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
+ await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const timeUntilExpiration = signedOrders[0].expirationTimeSeconds.minus(currentTimestamp).toNumber();
+ await increaseTimeAndMineBlockAsync(timeUntilExpiration);
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(3);
+ _.forEach(signedOrders, (signedOrder, index) => {
+ const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
+ const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
+ const expectedOrderStatus = OrderStatus.EXPIRED;
+ const orderInfo = ordersInfo[index];
+ expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
+ expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
+ expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
+ });
+ });
+ it('should get the correct information for a mix of unfilled, partially filled, fully filled, cancelled, and expired orders', async () => {
+ const unfilledOrder = await orderFactory.newSignedOrderAsync();
+ const partiallyFilledOrder = await orderFactory.newSignedOrderAsync();
+ await exchangeWrapper.fillOrderAsync(partiallyFilledOrder, takerAddress, {
+ takerAssetFillAmount: partiallyFilledOrder.takerAssetAmount.div(2),
+ });
+ const fullyFilledOrder = await orderFactory.newSignedOrderAsync();
+ await exchangeWrapper.fillOrderAsync(fullyFilledOrder, takerAddress);
+ const cancelledOrder = await orderFactory.newSignedOrderAsync();
+ await exchangeWrapper.cancelOrderAsync(cancelledOrder, makerAddress);
+ const currentTimestamp = await getLatestBlockTimestampAsync();
+ const expiredOrder = await orderFactory.newSignedOrderAsync({
+ expirationTimeSeconds: new BigNumber(currentTimestamp),
+ });
+ signedOrders = [unfilledOrder, partiallyFilledOrder, fullyFilledOrder, cancelledOrder, expiredOrder];
+ const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
+ expect(ordersInfo.length).to.be.equal(5);
+
+ const expectedUnfilledOrderHash = orderHashUtils.getOrderHashHex(unfilledOrder);
+ const expectedUnfilledTakerAssetFilledAmount = new BigNumber(0);
+ const expectedUnfilledOrderStatus = OrderStatus.FILLABLE;
+ const unfilledOrderInfo = ordersInfo[0];
+ expect(unfilledOrderInfo.orderHash).to.be.equal(expectedUnfilledOrderHash);
+ expect(unfilledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
+ expectedUnfilledTakerAssetFilledAmount,
+ );
+ expect(unfilledOrderInfo.orderStatus).to.be.equal(expectedUnfilledOrderStatus);
+
+ const expectedPartialOrderHash = orderHashUtils.getOrderHashHex(partiallyFilledOrder);
+ const expectedPartialTakerAssetFilledAmount = partiallyFilledOrder.takerAssetAmount.div(2);
+ const expectedPartialOrderStatus = OrderStatus.FILLABLE;
+ const partialOrderInfo = ordersInfo[1];
+ expect(partialOrderInfo.orderHash).to.be.equal(expectedPartialOrderHash);
+ expect(partialOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
+ expectedPartialTakerAssetFilledAmount,
+ );
+ expect(partialOrderInfo.orderStatus).to.be.equal(expectedPartialOrderStatus);
+
+ const expectedFilledOrderHash = orderHashUtils.getOrderHashHex(fullyFilledOrder);
+ const expectedFilledTakerAssetFilledAmount = fullyFilledOrder.takerAssetAmount;
+ const expectedFilledOrderStatus = OrderStatus.FULLY_FILLED;
+ const filledOrderInfo = ordersInfo[2];
+ expect(filledOrderInfo.orderHash).to.be.equal(expectedFilledOrderHash);
+ expect(filledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
+ expectedFilledTakerAssetFilledAmount,
+ );
+ expect(filledOrderInfo.orderStatus).to.be.equal(expectedFilledOrderStatus);
+
+ const expectedCancelledOrderHash = orderHashUtils.getOrderHashHex(cancelledOrder);
+ const expectedCancelledTakerAssetFilledAmount = new BigNumber(0);
+ const expectedCancelledOrderStatus = OrderStatus.CANCELLED;
+ const cancelledOrderInfo = ordersInfo[3];
+ expect(cancelledOrderInfo.orderHash).to.be.equal(expectedCancelledOrderHash);
+ expect(cancelledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
+ expectedCancelledTakerAssetFilledAmount,
+ );
+ expect(cancelledOrderInfo.orderStatus).to.be.equal(expectedCancelledOrderStatus);
+
+ const expectedExpiredOrderHash = orderHashUtils.getOrderHashHex(expiredOrder);
+ const expectedExpiredTakerAssetFilledAmount = new BigNumber(0);
+ const expectedExpiredOrderStatus = OrderStatus.EXPIRED;
+ const expiredOrderInfo = ordersInfo[4];
+ expect(expiredOrderInfo.orderHash).to.be.equal(expectedExpiredOrderHash);
+ expect(expiredOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
+ expectedExpiredTakerAssetFilledAmount,
+ );
+ expect(expiredOrderInfo.orderStatus).to.be.equal(expectedExpiredOrderStatus);
+ });
+ });
});
}); // tslint:disable-line:max-file-line-count
diff --git a/packages/contracts/test/forwarder/forwarder.ts b/packages/contracts/test/forwarder/forwarder.ts
index f0bf6ac03..4075fccad 100644
--- a/packages/contracts/test/forwarder/forwarder.ts
+++ b/packages/contracts/test/forwarder/forwarder.ts
@@ -148,14 +148,14 @@ describe(ContractName.Forwarder, () => {
await blockchainLifecycle.startAsync();
feeProportion = 0;
erc20Balances = await erc20Wrapper.getBalancesAsync();
- signedOrder = orderFactory.newSignedOrder();
+ signedOrder = await orderFactory.newSignedOrderAsync();
signedOrders = [signedOrder];
- feeOrder = orderFactory.newSignedOrder({
+ feeOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
});
feeOrders = [feeOrder];
- orderWithFee = orderFactory.newSignedOrder({
+ orderWithFee = await orderFactory.newSignedOrderAsync({
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
});
signedOrdersWithFee = [orderWithFee];
@@ -238,7 +238,7 @@ describe(ContractName.Forwarder, () => {
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0));
});
it('should fill the order when token is ZRX with fees', async () => {
- orderWithFee = orderFactory.newSignedOrder({
+ orderWithFee = await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
});
@@ -260,7 +260,7 @@ describe(ContractName.Forwarder, () => {
expect(newBalances[forwarderContract.address][weth.address]).to.be.bignumber.equal(new BigNumber(0));
});
it('should fail if sent an ETH amount too high', async () => {
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
});
@@ -274,11 +274,11 @@ describe(ContractName.Forwarder, () => {
);
});
it('should fail if fee abstraction amount is too high', async () => {
- orderWithFee = orderFactory.newSignedOrder({
+ orderWithFee = await orderFactory.newSignedOrderAsync({
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(50), DECIMALS_DEFAULT),
});
signedOrdersWithFee = [orderWithFee];
- feeOrder = orderFactory.newSignedOrder({
+ feeOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
});
@@ -294,11 +294,11 @@ describe(ContractName.Forwarder, () => {
});
it('throws when mixed ERC721 and ERC20 assets with ERC20 first', async () => {
const makerAssetId = erc721MakerAssetIds[0];
- const erc721SignedOrder = orderFactory.newSignedOrder({
+ const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
});
- const erc20SignedOrder = orderFactory.newSignedOrder();
+ const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
signedOrders = [erc20SignedOrder, erc721SignedOrder];
const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
return expectTransactionFailedAsync(
@@ -418,7 +418,7 @@ describe(ContractName.Forwarder, () => {
expect(takerBalanceAfter).to.be.bignumber.eq(takerBalanceBefore.plus(makerAssetAmount));
});
it('should buy the exact amount of assets when buying zrx with fee abstraction', async () => {
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
});
@@ -447,7 +447,7 @@ describe(ContractName.Forwarder, () => {
expect(takerWeiBalanceAfter).to.be.bignumber.equal(takerWeiBalanceBefore.minus(expectedCostAfterGas));
});
it('throws if fees are higher than 5% when buying zrx', async () => {
- const highFeeZRXOrder = orderFactory.newSignedOrder({
+ const highFeeZRXOrder = await orderFactory.newSignedOrderAsync({
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
makerAssetAmount: signedOrder.makerAssetAmount,
takerFee: signedOrder.makerAssetAmount.times(0.06),
@@ -470,7 +470,7 @@ describe(ContractName.Forwarder, () => {
);
});
it('throws if fees are higher than 5% when buying erc20', async () => {
- const highFeeERC20Order = orderFactory.newSignedOrder({
+ const highFeeERC20Order = await orderFactory.newSignedOrderAsync({
takerFee: signedOrder.makerAssetAmount.times(0.06),
});
signedOrdersWithFee = [highFeeERC20Order];
@@ -544,7 +544,7 @@ describe(ContractName.Forwarder, () => {
describe('marketBuyTokensWithEth - ERC721', async () => {
it('buys ERC721 assets', async () => {
const makerAssetId = erc721MakerAssetIds[0];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
});
@@ -566,7 +566,7 @@ describe(ContractName.Forwarder, () => {
});
it('buys ERC721 assets with fee abstraction', async () => {
const makerAssetId = erc721MakerAssetIds[0];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -588,7 +588,7 @@ describe(ContractName.Forwarder, () => {
});
it('buys ERC721 assets with fee abstraction and pays fee to fee recipient', async () => {
const makerAssetId = erc721MakerAssetIds[0];
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
@@ -630,12 +630,12 @@ describe(ContractName.Forwarder, () => {
it('buys multiple ERC721 assets with fee abstraction and pays fee to fee recipient', async () => {
const makerAssetId1 = erc721MakerAssetIds[0];
const makerAssetId2 = erc721MakerAssetIds[1];
- const signedOrder1 = orderFactory.newSignedOrder({
+ const signedOrder1 = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(3), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId1),
});
- const signedOrder2 = orderFactory.newSignedOrder({
+ const signedOrder2 = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(4), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId2),
@@ -665,20 +665,20 @@ describe(ContractName.Forwarder, () => {
// There are two fee orders, but the first fee order is partially filled while
// the Forwarding contract tx is in the mempool.
const erc721MakerAssetAmount = new BigNumber(1);
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: erc721MakerAssetAmount,
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(6), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
});
signedOrders = [signedOrder];
- const firstFeeOrder = orderFactory.newSignedOrder({
+ const firstFeeOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
});
- const secondFeeOrder = orderFactory.newSignedOrder({
+ const secondFeeOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT),
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.12), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
@@ -729,7 +729,7 @@ describe(ContractName.Forwarder, () => {
// There are two fee orders, but the first fee order is partially filled while
// the Forwarding contract tx is in the mempool.
const erc721MakerAssetAmount = new BigNumber(1);
- signedOrder = orderFactory.newSignedOrder({
+ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: erc721MakerAssetAmount,
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(10), DECIMALS_DEFAULT),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(6), DECIMALS_DEFAULT),
@@ -737,13 +737,13 @@ describe(ContractName.Forwarder, () => {
});
const zrxMakerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(8), DECIMALS_DEFAULT);
signedOrders = [signedOrder];
- const firstFeeOrder = orderFactory.newSignedOrder({
+ const firstFeeOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: zrxMakerAssetAmount,
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.1), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
takerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(0), DECIMALS_DEFAULT),
});
- const secondFeeOrder = orderFactory.newSignedOrder({
+ const secondFeeOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: zrxMakerAssetAmount,
takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(0.12), DECIMALS_DEFAULT),
makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address),
@@ -778,11 +778,11 @@ describe(ContractName.Forwarder, () => {
});
it('throws when mixed ERC721 and ERC20 assets', async () => {
const makerAssetId = erc721MakerAssetIds[0];
- const erc721SignedOrder = orderFactory.newSignedOrder({
+ const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
});
- const erc20SignedOrder = orderFactory.newSignedOrder();
+ const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
signedOrders = [erc721SignedOrder, erc20SignedOrder];
const makerAssetAmount = new BigNumber(signedOrders.length);
const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
@@ -796,11 +796,11 @@ describe(ContractName.Forwarder, () => {
});
it('throws when mixed ERC721 and ERC20 assets with ERC20 first', async () => {
const makerAssetId = erc721MakerAssetIds[0];
- const erc721SignedOrder = orderFactory.newSignedOrder({
+ const erc721SignedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(1),
makerAssetData: assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerAssetId),
});
- const erc20SignedOrder = orderFactory.newSignedOrder();
+ const erc20SignedOrder = await orderFactory.newSignedOrderAsync();
signedOrders = [erc20SignedOrder, erc721SignedOrder];
const makerAssetAmount = new BigNumber(signedOrders.length);
const fillAmountWei = erc20SignedOrder.takerAssetAmount.plus(erc721SignedOrder.takerAssetAmount);
diff --git a/packages/contracts/test/multisig/asset_proxy_owner.ts b/packages/contracts/test/multisig/asset_proxy_owner.ts
index 6a9843153..6b98605d3 100644
--- a/packages/contracts/test/multisig/asset_proxy_owner.ts
+++ b/packages/contracts/test/multisig/asset_proxy_owner.ts
@@ -18,9 +18,9 @@ import {
expectContractCreationFailedWithoutReason,
expectTransactionFailedWithoutReasonAsync,
} from '../utils/assertions';
+import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants';
-import { increaseTimeAndMineBlockAsync } from '../utils/increase_time';
import { MultiSigWrapper } from '../utils/multi_sig_wrapper';
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
diff --git a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts
index a8e9243a9..8eeeeca6b 100644
--- a/packages/contracts/test/multisig/multi_sig_with_time_lock.ts
+++ b/packages/contracts/test/multisig/multi_sig_with_time_lock.ts
@@ -9,9 +9,9 @@ import {
} from '../../generated_contract_wrappers/multi_sig_wallet_with_time_lock';
import { artifacts } from '../utils/artifacts';
import { expectTransactionFailedWithoutReasonAsync } from '../utils/assertions';
+import { increaseTimeAndMineBlockAsync } from '../utils/block_timestamp';
import { chaiSetup } from '../utils/chai_setup';
import { constants } from '../utils/constants';
-import { increaseTimeAndMineBlockAsync } from '../utils/increase_time';
import { MultiSigWrapper } from '../utils/multi_sig_wrapper';
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
diff --git a/packages/contracts/test/utils/increase_time.ts b/packages/contracts/test/utils/block_timestamp.ts
index 4565d8dbc..1159792c4 100644
--- a/packages/contracts/test/utils/increase_time.ts
+++ b/packages/contracts/test/utils/block_timestamp.ts
@@ -29,3 +29,12 @@ export async function increaseTimeAndMineBlockAsync(seconds: number): Promise<nu
return offset;
}
+
+/**
+ * Returns the timestamp of the latest block in seconds since the Unix epoch.
+ * @returns a new Promise which will resolve with the timestamp in seconds.
+ */
+export async function getLatestBlockTimestampAsync(): Promise<number> {
+ const currentBlock = await web3Wrapper.getBlockAsync('latest');
+ return currentBlock.timestamp;
+}
diff --git a/packages/contracts/test/utils/exchange_wrapper.ts b/packages/contracts/test/utils/exchange_wrapper.ts
index be0b32c62..490ea959b 100644
--- a/packages/contracts/test/utils/exchange_wrapper.ts
+++ b/packages/contracts/test/utils/exchange_wrapper.ts
@@ -223,6 +223,10 @@ export class ExchangeWrapper {
const orderInfo = (await this._exchange.getOrderInfo.callAsync(signedOrder)) as OrderInfo;
return orderInfo;
}
+ public async getOrdersInfoAsync(signedOrders: SignedOrder[]): Promise<OrderInfo[]> {
+ const ordersInfo = (await this._exchange.getOrdersInfo.callAsync(signedOrders)) as OrderInfo[];
+ return ordersInfo;
+ }
public async matchOrdersAsync(
signedOrderLeft: SignedOrder,
signedOrderRight: SignedOrder,
diff --git a/packages/contracts/test/utils/order_factory.ts b/packages/contracts/test/utils/order_factory.ts
index da418fa0f..63a893695 100644
--- a/packages/contracts/test/utils/order_factory.ts
+++ b/packages/contracts/test/utils/order_factory.ts
@@ -2,6 +2,7 @@ import { generatePseudoRandomSalt, orderHashUtils } from '@0xproject/order-utils
import { Order, SignatureType, SignedOrder } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
+import { getLatestBlockTimestampAsync } from './block_timestamp';
import { constants } from './constants';
import { signingUtils } from './signing_utils';
@@ -12,15 +13,15 @@ export class OrderFactory {
this._defaultOrderParams = defaultOrderParams;
this._privateKey = privateKey;
}
- public newSignedOrder(
+ public async newSignedOrderAsync(
customOrderParams: Partial<Order> = {},
signatureType: SignatureType = SignatureType.EthSign,
- ): SignedOrder {
- const tenMinutes = 10 * 60 * 1000;
- const randomExpiration = new BigNumber(Date.now() + tenMinutes);
+ ): Promise<SignedOrder> {
+ const tenMinutesInSeconds = 10 * 60;
+ const currentBlockTimestamp = await getLatestBlockTimestampAsync();
const order = ({
senderAddress: constants.NULL_ADDRESS,
- expirationTimeSeconds: randomExpiration,
+ expirationTimeSeconds: new BigNumber(currentBlockTimestamp).add(tenMinutesInSeconds),
salt: generatePseudoRandomSalt(),
takerAddress: constants.NULL_ADDRESS,
...this._defaultOrderParams,
diff --git a/packages/dev-utils/src/blockchain_lifecycle.ts b/packages/dev-utils/src/blockchain_lifecycle.ts
index 73e2a58c9..a48cb0856 100644
--- a/packages/dev-utils/src/blockchain_lifecycle.ts
+++ b/packages/dev-utils/src/blockchain_lifecycle.ts
@@ -34,6 +34,12 @@ export class BlockchainLifecycle {
blockNumber = await this._web3Wrapper.getBlockNumberAsync();
}
this._snapshotIdsStack.push(blockNumber);
+ // HACK(albrow) It's possible that we applied a time offset but
+ // the transaction we mined to put that time offset into the
+ // blockchain was reverted. As a workaround, we mine a new dummy
+ // block so that the latest block timestamp accounts for any
+ // possible time offsets.
+ await this._mineDummyBlockAsync();
break;
default:
throw new Error(`Unknown node type: ${nodeType}`);
@@ -59,22 +65,9 @@ export class BlockchainLifecycle {
}
private async _mineMinimumBlocksAsync(): Promise<void> {
logUtils.warn('WARNING: minimum block number for tests not met. Mining additional blocks...');
- if (this._addresses.length === 0) {
- this._addresses = await this._web3Wrapper.getAvailableAddressesAsync();
- if (this._addresses.length === 0) {
- throw new Error('No accounts found');
- }
- }
while ((await this._web3Wrapper.getBlockNumberAsync()) < MINIMUM_BLOCKS) {
logUtils.warn('Mining block...');
- await this._web3Wrapper.awaitTransactionMinedAsync(
- await this._web3Wrapper.sendTransactionAsync({
- from: this._addresses[0],
- to: this._addresses[0],
- value: '0',
- }),
- 0,
- );
+ await this._mineDummyBlockAsync();
}
logUtils.warn('Done mining the minimum number of blocks.');
}
@@ -84,4 +77,22 @@ export class BlockchainLifecycle {
}
return this._nodeType;
}
+ // Sends a transaction that has no real effect on the state and waits for it
+ // to be mined.
+ private async _mineDummyBlockAsync(): Promise<void> {
+ if (this._addresses.length === 0) {
+ this._addresses = await this._web3Wrapper.getAvailableAddressesAsync();
+ if (this._addresses.length === 0) {
+ throw new Error('No accounts found');
+ }
+ }
+ await this._web3Wrapper.awaitTransactionMinedAsync(
+ await this._web3Wrapper.sendTransactionAsync({
+ from: this._addresses[0],
+ to: this._addresses[0],
+ value: '0',
+ }),
+ 0,
+ );
+ }
}
diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json
index a66db6eec..e747a2129 100644
--- a/packages/order-watcher/CHANGELOG.json
+++ b/packages/order-watcher/CHANGELOG.json
@@ -9,6 +9,14 @@
{
"note": "Do not stop subscription if error is encountered",
"pr": 825
+ },
+ {
+ "note": "Fixed a bug that caused the incorrect block to be fetched via JSON-RPC within Blockstream",
+ "pr": 875
+ },
+ {
+ "note": "Remove stateLayer config from OrderWatcher. It now always operates on the latest block",
+ "pr": 875
}
],
"timestamp": 1531149657
diff --git a/packages/order-watcher/src/order_watcher/event_watcher.ts b/packages/order-watcher/src/order_watcher/event_watcher.ts
index b45e2c8c0..8ad52989b 100644
--- a/packages/order-watcher/src/order_watcher/event_watcher.ts
+++ b/packages/order-watcher/src/order_watcher/event_watcher.ts
@@ -30,7 +30,7 @@ export class EventWatcher {
constructor(
web3Wrapper: Web3Wrapper,
pollingIntervalIfExistsMs: undefined | number,
- stateLayer: BlockParamLiteral = BlockParamLiteral.Latest,
+ stateLayer: BlockParamLiteral,
isVerbose: boolean,
) {
this._isVerbose = isVerbose;
@@ -61,13 +61,9 @@ export class EventWatcher {
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
throw new Error(OrderWatcherError.SubscriptionAlreadyPresent);
}
- const eventFilter = {
- fromBlock: this._stateLayer,
- toBlock: this._stateLayer,
- };
this._blockAndLogStreamerIfExists = new BlockAndLogStreamer(
- this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper, this._stateLayer),
- this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper, eventFilter),
+ this._web3Wrapper.getBlockAsync.bind(this._web3Wrapper),
+ this._web3Wrapper.getLogsAsync.bind(this._web3Wrapper),
this._onBlockAndLogStreamerError.bind(this),
);
const catchAllLogFilter = {};
@@ -104,7 +100,7 @@ export class EventWatcher {
await this._emitDifferencesAsync(log, isRemoved ? LogEventState.Removed : LogEventState.Added, callback);
}
private async _reconcileBlockAsync(): Promise<void> {
- const latestBlock = await this._web3Wrapper.getBlockAsync(BlockParamLiteral.Latest);
+ const latestBlock = await this._web3Wrapper.getBlockAsync(this._stateLayer);
// We need to coerce to Block type cause Web3.Block includes types for mempool blocks
if (!_.isUndefined(this._blockAndLogStreamerIfExists)) {
// If we clear the interval while fetching the block - this._blockAndLogStreamer will be undefined
diff --git a/packages/order-watcher/src/order_watcher/order_watcher.ts b/packages/order-watcher/src/order_watcher/order_watcher.ts
index b32354687..765747e35 100644
--- a/packages/order-watcher/src/order_watcher/order_watcher.ts
+++ b/packages/order-watcher/src/order_watcher/order_watcher.ts
@@ -61,6 +61,7 @@ interface OrderStateByOrderHash {
// tslint:disable-next-line:custom-no-magic-numbers
const DEFAULT_CLEANUP_JOB_INTERVAL_MS = 1000 * 60 * 60; // 1h
+const STATE_LAYER = BlockParamLiteral.Latest;
/**
* This class includes all the functionality related to watching a set of orders
@@ -91,17 +92,15 @@ export class OrderWatcher {
});
this._contractWrappers = new ContractWrappers(provider, { networkId });
const pollingIntervalIfExistsMs = _.isUndefined(config) ? undefined : config.eventPollingIntervalMs;
- const stateLayer =
- _.isUndefined(config) || _.isUndefined(config.stateLayer) ? BlockParamLiteral.Latest : config.stateLayer;
const isVerbose = !_.isUndefined(config) && !_.isUndefined(config.isVerbose) ? config.isVerbose : false;
- this._eventWatcher = new EventWatcher(this._web3Wrapper, pollingIntervalIfExistsMs, stateLayer, isVerbose);
+ this._eventWatcher = new EventWatcher(this._web3Wrapper, pollingIntervalIfExistsMs, STATE_LAYER, isVerbose);
this._balanceAndProxyAllowanceLazyStore = new BalanceAndProxyAllowanceLazyStore(
this._contractWrappers.token,
- stateLayer,
+ STATE_LAYER,
);
this._orderFilledCancelledLazyStore = new OrderFilledCancelledLazyStore(
this._contractWrappers.exchange,
- stateLayer,
+ STATE_LAYER,
);
this._orderStateUtils = new OrderStateUtils(
this._balanceAndProxyAllowanceLazyStore,
diff --git a/packages/order-watcher/src/types.ts b/packages/order-watcher/src/types.ts
index 63e4e7848..fd71267a2 100644
--- a/packages/order-watcher/src/types.ts
+++ b/packages/order-watcher/src/types.ts
@@ -1,4 +1,4 @@
-import { BlockParamLiteral, LogEntryEvent, OrderState } from '@0xproject/types';
+import { LogEntryEvent, OrderState } from '@0xproject/types';
export enum OrderWatcherError {
SubscriptionAlreadyPresent = 'SUBSCRIPTION_ALREADY_PRESENT',
@@ -13,10 +13,8 @@ export type EventWatcherCallback = (err: null | Error, log?: LogEntryEvent) => v
* expirationMarginMs: Amount of time before order expiry that you'd like to be notified
* of an orders expiration. Default=0.
* cleanupJobIntervalMs: How often to run a cleanup job which revalidates all the orders. Default=1hr.
- * stateLayer: Optional blockchain state layer OrderWatcher will monitor for new events. Default=latest.
*/
export interface OrderWatcherConfig {
- stateLayer: BlockParamLiteral;
orderExpirationCheckingIntervalMs?: number;
eventPollingIntervalMs?: number;
expirationMarginMs?: number;
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx
index be4a67cb3..33581c938 100644
--- a/packages/website/ts/pages/about/about.tsx
+++ b/packages/website/ts/pages/about/about.tsx
@@ -181,14 +181,14 @@ const teamRow6: ProfileInfo[] = [
image: 'images/team/peter.jpg',
linkedIn: 'https://www.linkedin.com/in/peter-z-7b9595163/',
},
- // {
- // name: 'Chris Kalani',
- // title: 'Director of Design',
- // description: `Previously founded Wake (acquired by InVision). Early Facebook product designer.`,
- // image: 'images/team/chris.png',
- // linkedIn: 'https://www.linkedin.com/in/chriskalani/',
- // github: 'https://github.com/chriskalani',
- // },
+ {
+ name: 'Chris Kalani',
+ title: 'Director of Design',
+ description: `Previously founded Wake (acquired by InVision). Early Facebook product designer.`,
+ image: 'images/team/chris.png',
+ linkedIn: 'https://www.linkedin.com/in/chriskalani/',
+ github: 'https://github.com/chriskalani',
+ },
];
const advisors: ProfileInfo[] = [
diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts
index e43f541bf..20441cd75 100644
--- a/packages/website/ts/utils/constants.ts
+++ b/packages/website/ts/utils/constants.ts
@@ -58,7 +58,7 @@ export const constants = {
PROJECT_URL_MAKER: 'https://makerdao.com',
PROJECT_URL_ARAGON: 'https://aragon.one',
PROJECT_URL_BLOCKNET: 'https://blocknet.co',
- PROJECT_URL_0CEAN: 'http://the0cean.com',
+ PROJECT_URL_0CEAN: 'https://theocean.trade',
PROJECT_URL_IMTOKEN: 'https://tokenlon.token.im/',
PROJECT_URL_AUGUR: 'https://augur.net',
PROJECT_URL_AUCTUS: 'https://auctus.org',