Refactor integrations directory structure; move core.ts, balance stores, and FillOrderWrapper to integrations

This commit is contained in:
Michael Zhu 2019-11-12 17:10:08 -08:00
parent bdca84fe72
commit 7f4cbba076
50 changed files with 387 additions and 446 deletions

View File

@ -1,37 +0,0 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.5;
pragma experimental ABIEncoderV2;
import "@0x/contracts-exchange-libs/contracts/src/LibEIP712ExchangeDomain.sol";
import "../src/MixinSignatureValidator.sol";
import "../src/MixinTransactions.sol";
contract TestSignatureValidator is
LibEIP712ExchangeDomain,
MixinSignatureValidator
{
// solhint-disable no-empty-blocks
constructor (uint256 chainId)
public
LibEIP712ExchangeDomain(chainId, address(0))
{}
}

View File

@ -1,6 +1,4 @@
export * from './artifacts'; export * from './artifacts';
export * from './wrappers'; export * from './wrappers';
export import ExchangeRevertErrors = require('./revert_errors'); export import ExchangeRevertErrors = require('./revert_errors');
export { BlockchainBalanceStore } from './balance_stores/blockchain_balance_store';
export { LocalBalanceStore } from './balance_stores/local_balance_store';
export { exchangeDataEncoder } from './exchange_data_encoder'; export { exchangeDataEncoder } from './exchange_data_encoder';

View File

@ -37,7 +37,6 @@ import * as TestLibExchangeRichErrorDecoder from '../test/generated-artifacts/Te
import * as TestProtocolFeeCollector from '../test/generated-artifacts/TestProtocolFeeCollector.json'; import * as TestProtocolFeeCollector from '../test/generated-artifacts/TestProtocolFeeCollector.json';
import * as TestProtocolFees from '../test/generated-artifacts/TestProtocolFees.json'; import * as TestProtocolFees from '../test/generated-artifacts/TestProtocolFees.json';
import * as TestProtocolFeesReceiver from '../test/generated-artifacts/TestProtocolFeesReceiver.json'; import * as TestProtocolFeesReceiver from '../test/generated-artifacts/TestProtocolFeesReceiver.json';
import * as TestSignatureValidator from '../test/generated-artifacts/TestSignatureValidator.json';
import * as TestTransactions from '../test/generated-artifacts/TestTransactions.json'; import * as TestTransactions from '../test/generated-artifacts/TestTransactions.json';
import * as TestValidatorWallet from '../test/generated-artifacts/TestValidatorWallet.json'; import * as TestValidatorWallet from '../test/generated-artifacts/TestValidatorWallet.json';
import * as TestWrapperFunctions from '../test/generated-artifacts/TestWrapperFunctions.json'; import * as TestWrapperFunctions from '../test/generated-artifacts/TestWrapperFunctions.json';
@ -74,7 +73,6 @@ export const artifacts = {
TestProtocolFeeCollector: TestProtocolFeeCollector as ContractArtifact, TestProtocolFeeCollector: TestProtocolFeeCollector as ContractArtifact,
TestProtocolFees: TestProtocolFees as ContractArtifact, TestProtocolFees: TestProtocolFees as ContractArtifact,
TestProtocolFeesReceiver: TestProtocolFeesReceiver as ContractArtifact, TestProtocolFeesReceiver: TestProtocolFeesReceiver as ContractArtifact,
TestSignatureValidator: TestSignatureValidator as ContractArtifact,
TestTransactions: TestTransactions as ContractArtifact, TestTransactions: TestTransactions as ContractArtifact,
TestValidatorWallet: TestValidatorWallet as ContractArtifact, TestValidatorWallet: TestValidatorWallet as ContractArtifact,
TestWrapperFunctions: TestWrapperFunctions as ContractArtifact, TestWrapperFunctions: TestWrapperFunctions as ContractArtifact,

View File

@ -1,4 +1,6 @@
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import { import {
blockchainTests, blockchainTests,
constants, constants,
@ -12,6 +14,7 @@ import {
randomAddress, randomAddress,
TransactionFactory, TransactionFactory,
transactionHashUtils, transactionHashUtils,
ValidatorWalletAction,
} from '@0x/contracts-test-utils'; } from '@0x/contracts-test-utils';
import { SignatureType, SignedOrder, SignedZeroExTransaction } from '@0x/types'; import { SignatureType, SignedOrder, SignedZeroExTransaction } from '@0x/types';
import { BigNumber, StringRevertError } from '@0x/utils'; import { BigNumber, StringRevertError } from '@0x/utils';
@ -22,33 +25,35 @@ import ExchangeRevertErrors = require('../src/revert_errors');
import { artifacts } from './artifacts'; import { artifacts } from './artifacts';
import { import {
ExchangeContract,
ExchangeSignatureValidatorApprovalEventArgs,
IEIP1271DataContract, IEIP1271DataContract,
TestSignatureValidatorContract,
TestSignatureValidatorSignatureValidatorApprovalEventArgs,
TestValidatorWalletContract, TestValidatorWalletContract,
} from './wrappers'; } from './wrappers';
import { ValidatorWalletAction } from './utils/constants';
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
blockchainTests.resets('MixinSignatureValidator', env => { blockchainTests.resets('MixinSignatureValidator', env => {
let chainId: number; let chainId: number;
let signatureValidator: TestSignatureValidatorContract; let exchange: ExchangeContract;
let validatorWallet: TestValidatorWalletContract; let validatorWallet: TestValidatorWalletContract;
let validatorWalletRevertReason: string; let validatorWalletRevertReason: string;
let signerAddress: string; let signerAddress: string;
let signerPrivateKey: Buffer; let signerPrivateKey: Buffer;
let notSignerAddress: string; let notSignerAddress: string;
let accounts: string[];
let owner: string;
let makerAddress: string;
let takerAddress: string;
let feeRecipientAddress: string;
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, env.provider, env.txDefaults); const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, env.provider, env.txDefaults);
const eip1271Data = new IEIP1271DataContract(constants.NULL_ADDRESS, env.provider, env.txDefaults); const eip1271Data = new IEIP1271DataContract(constants.NULL_ADDRESS, env.provider, env.txDefaults);
before(async () => { before(async () => {
chainId = await env.getChainIdAsync(); chainId = await env.getChainIdAsync();
const accounts = await env.getAccountAddressesAsync(); accounts = await env.getAccountAddressesAsync();
signerAddress = accounts[0]; [owner, signerAddress, notSignerAddress, makerAddress, takerAddress, feeRecipientAddress] = accounts;
notSignerAddress = accounts[1]; exchange = await ExchangeContract.deployFrom0xArtifactAsync(
signatureValidator = await TestSignatureValidatorContract.deployFrom0xArtifactAsync( artifacts.Exchange,
artifacts.TestSignatureValidator,
env.provider, env.provider,
env.txDefaults, env.txDefaults,
{}, {},
@ -59,14 +64,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
env.provider, env.provider,
env.txDefaults, env.txDefaults,
{}, {},
signatureValidator.address, exchange.address,
); );
validatorWalletRevertReason = await validatorWallet.REVERT_REASON().callAsync(); validatorWalletRevertReason = await validatorWallet.REVERT_REASON().callAsync();
// Approve the validator for both signers. // Approve the validator for both signers.
await Promise.all( await Promise.all(
[signerAddress, notSignerAddress].map(async (addr: string) => { [signerAddress, notSignerAddress].map(async (addr: string) => {
return signatureValidator return exchange
.setSignatureValidatorApproval(validatorWallet.address, true) .setSignatureValidatorApproval(validatorWallet.address, true)
.awaitTransactionSuccessAsync({ from: addr }); .awaitTransactionSuccessAsync({ from: addr });
}), }),
@ -300,7 +305,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
it('should return true when SignatureType=Presigned and signer has presigned hash', async () => { it('should return true when SignatureType=Presigned and signer has presigned hash', async () => {
const hashHex = getCurrentHashHex(); const hashHex = getCurrentHashHex();
// Presign the hash // Presign the hash
await signatureValidator.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress }); await exchange.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress });
// Validate presigned signature // Validate presigned signature
const signatureHex = hexConcat(SignatureType.PreSigned); const signatureHex = hexConcat(SignatureType.PreSigned);
const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex); const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex);
@ -338,7 +343,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
.prepare(_hashHex, validatorAction, expectedSignatureHashHex) .prepare(_hashHex, validatorAction, expectedSignatureHashHex)
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
} }
return signatureValidator.isValidHashSignature(_hashHex, _signerAddress, signatureHex).callAsync(); return exchange.isValidHashSignature(_hashHex, _signerAddress, signatureHex).callAsync();
}; };
it('should revert when signerAddress == 0', async () => { it('should revert when signerAddress == 0', async () => {
@ -387,9 +392,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`); const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`);
const signature = Buffer.concat([v, r, s, trezorSignatureType]); const signature = Buffer.concat([v, r, s, trezorSignatureType]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const isValidSignature = await signatureValidator const isValidSignature = await exchange.isValidHashSignature(messageHash, signer, signatureHex).callAsync();
.isValidHashSignature(messageHash, signer, signatureHex)
.callAsync();
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
@ -403,9 +406,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`); const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`);
const signature = Buffer.concat([v, r, s, trezorSignatureType]); const signature = Buffer.concat([v, r, s, trezorSignatureType]);
const signatureHex = ethUtil.bufferToHex(signature); const signatureHex = ethUtil.bufferToHex(signature);
const isValidSignature = await signatureValidator const isValidSignature = await exchange.isValidHashSignature(messageHash, signer, signatureHex).callAsync();
.isValidHashSignature(messageHash, signer, signatureHex)
.callAsync();
expect(isValidSignature).to.be.true(); expect(isValidSignature).to.be.true();
}); });
@ -417,10 +418,9 @@ blockchainTests.resets('MixinSignatureValidator', env => {
let signedOrder: SignedOrder; let signedOrder: SignedOrder;
before(async () => { before(async () => {
const makerAddress = signerAddress;
const defaultOrderParams = { const defaultOrderParams = {
...constants.STATIC_ORDER_PARAMS, ...constants.STATIC_ORDER_PARAMS,
makerAddress, makerAddress: signerAddress,
feeRecipientAddress: randomAddress(), feeRecipientAddress: randomAddress(),
makerAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(), makerAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(),
takerAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(), takerAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(),
@ -428,7 +428,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
takerFeeAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(), takerFeeAssetData: await devUtils.encodeERC20AssetData(randomAddress()).callAsync(),
makerFee: constants.ZERO_AMOUNT, makerFee: constants.ZERO_AMOUNT,
takerFee: constants.ZERO_AMOUNT, takerFee: constants.ZERO_AMOUNT,
exchangeAddress: signatureValidator.address, exchangeAddress: exchange.address,
chainId, chainId,
}; };
orderFactory = new OrderFactory(signerPrivateKey, defaultOrderParams); orderFactory = new OrderFactory(signerPrivateKey, defaultOrderParams);
@ -454,7 +454,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
.prepare(orderHashHex, validatorAction, expectedSignatureHashHex) .prepare(orderHashHex, validatorAction, expectedSignatureHashHex)
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
} }
return signatureValidator.isValidOrderSignature(order, signatureHex).callAsync(); return exchange.isValidOrderSignature(order, signatureHex).callAsync();
}; };
it('should revert when signerAddress == 0', async () => { it('should revert when signerAddress == 0', async () => {
@ -470,7 +470,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
signatureHex, signatureHex,
); );
const tx = signatureValidator.isValidOrderSignature(nullMakerOrder, signatureHex).callAsync(); const tx = exchange.isValidOrderSignature(nullMakerOrder, signatureHex).callAsync();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -566,7 +566,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
it('should revert when SignatureType=Validator and signature is shorter than 21 bytes', async () => { it('should revert when SignatureType=Validator and signature is shorter than 21 bytes', async () => {
// Set approval of signature validator to false // Set approval of signature validator to false
await signatureValidator await exchange
.setSignatureValidatorApproval(validatorWallet.address, false) .setSignatureValidatorApproval(validatorWallet.address, false)
.awaitTransactionSuccessAsync({ from: signedOrder.makerAddress }); .awaitTransactionSuccessAsync({ from: signedOrder.makerAddress });
// Doesn't have to contain a real signature since our wallet contract // Doesn't have to contain a real signature since our wallet contract
@ -585,7 +585,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
it('should revert when SignatureType=Validator, signature is valid and validator is not approved', async () => { it('should revert when SignatureType=Validator, signature is valid and validator is not approved', async () => {
// Set approval of signature validator to false // Set approval of signature validator to false
await signatureValidator await exchange
.setSignatureValidatorApproval(validatorWallet.address, false) .setSignatureValidatorApproval(validatorWallet.address, false)
.awaitTransactionSuccessAsync({ from: signedOrder.makerAddress }); .awaitTransactionSuccessAsync({ from: signedOrder.makerAddress });
// Doesn't have to contain a real signature since our wallet contract // Doesn't have to contain a real signature since our wallet contract
@ -706,7 +706,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
signatureHex, signatureHex,
constants.NULL_BYTES, constants.NULL_BYTES,
); );
const tx = signatureValidator.isValidOrderSignature(signedOrder, signatureHex).callAsync(); const tx = exchange.isValidOrderSignature(signedOrder, signatureHex).callAsync();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -721,16 +721,16 @@ blockchainTests.resets('MixinSignatureValidator', env => {
constants.NULL_BYTES, constants.NULL_BYTES,
); );
// Register an EOA as a validator. // Register an EOA as a validator.
await signatureValidator await exchange
.setSignatureValidatorApproval(notSignerAddress, true) .setSignatureValidatorApproval(notSignerAddress, true)
.awaitTransactionSuccessAsync({ from: signerAddress }); .awaitTransactionSuccessAsync({ from: signerAddress });
const tx = signatureValidator.isValidOrderSignature(signedOrder, signatureHex).callAsync(); const tx = exchange.isValidOrderSignature(signedOrder, signatureHex).callAsync();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
// Run hash-only signature type tests as well. // Run hash-only signature type tests as well.
const validateOrderHashAsync = async ( const validateOrderHashAsync = async (
hashHex: string, _hashHex: string,
_signerAddress: string, _signerAddress: string,
signatureHex: string, signatureHex: string,
validatorAction?: ValidatorWalletAction, validatorAction?: ValidatorWalletAction,
@ -751,7 +751,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
const TRANSACTION_DATA_LENGTH = 100; const TRANSACTION_DATA_LENGTH = 100;
before(async () => { before(async () => {
transactionFactory = new TransactionFactory(signerPrivateKey, signatureValidator.address, chainId); transactionFactory = new TransactionFactory(signerPrivateKey, exchange.address, chainId);
}); });
beforeEach(async () => { beforeEach(async () => {
@ -778,7 +778,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
.prepare(transactionHashHex, validatorAction, expectedSignatureHashHex) .prepare(transactionHashHex, validatorAction, expectedSignatureHashHex)
.awaitTransactionSuccessAsync(); .awaitTransactionSuccessAsync();
} }
return signatureValidator.isValidTransactionSignature(transaction, signatureHex).callAsync(); return exchange.isValidTransactionSignature(transaction, signatureHex).callAsync();
}; };
it('should revert when signerAddress == 0', async () => { it('should revert when signerAddress == 0', async () => {
@ -794,7 +794,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
signatureHex, signatureHex,
); );
const tx = signatureValidator.isValidTransactionSignature(nullSignerTransaction, signatureHex).callAsync(); const tx = exchange.isValidTransactionSignature(nullSignerTransaction, signatureHex).callAsync();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -841,7 +841,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
it('should revert when SignatureType=Validator and signature is shorter than 21 bytes', async () => { it('should revert when SignatureType=Validator and signature is shorter than 21 bytes', async () => {
// Set approval of signature validator to false // Set approval of signature validator to false
await signatureValidator await exchange
.setSignatureValidatorApproval(validatorWallet.address, false) .setSignatureValidatorApproval(validatorWallet.address, false)
.awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress }); .awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress });
// Doesn't have to contain a real signature since our wallet contract // Doesn't have to contain a real signature since our wallet contract
@ -920,7 +920,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
it('should revert when SignatureType=Validator, signature is valid and validator is not approved', async () => { it('should revert when SignatureType=Validator, signature is valid and validator is not approved', async () => {
// Set approval of signature validator to false // Set approval of signature validator to false
await signatureValidator await exchange
.setSignatureValidatorApproval(validatorWallet.address, false) .setSignatureValidatorApproval(validatorWallet.address, false)
.awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress }); .awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress });
// Doesn't have to contain a real signature since our wallet contract // Doesn't have to contain a real signature since our wallet contract
@ -1055,7 +1055,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
signatureHex, signatureHex,
constants.NULL_BYTES, constants.NULL_BYTES,
); );
const tx = signatureValidator.isValidTransactionSignature(signedTransaction, signatureHex).callAsync(); const tx = exchange.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -1072,16 +1072,16 @@ blockchainTests.resets('MixinSignatureValidator', env => {
constants.NULL_BYTES, constants.NULL_BYTES,
); );
// Register an EOA as a validator. // Register an EOA as a validator.
await signatureValidator await exchange
.setSignatureValidatorApproval(notSignerAddress, true) .setSignatureValidatorApproval(notSignerAddress, true)
.awaitTransactionSuccessAsync({ from: signerAddress }); .awaitTransactionSuccessAsync({ from: signerAddress });
const tx = signatureValidator.isValidTransactionSignature(signedTransaction, signatureHex).callAsync(); const tx = exchange.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
// Run hash-only signature type tests as well. // Run hash-only signature type tests as well.
const validateOrderHashAsync = async ( const validateOrderHashAsync = async (
hashHex: string, _hashHex: string,
_signerAddress: string, _signerAddress: string,
signatureHex: string, signatureHex: string,
validatorAction?: ValidatorWalletAction, validatorAction?: ValidatorWalletAction,
@ -1105,14 +1105,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
it('should emit a SignatureValidatorApprovalSet with correct args when a validator is approved', async () => { it('should emit a SignatureValidatorApprovalSet with correct args when a validator is approved', async () => {
const approval = true; const approval = true;
const res = await signatureValidator const res = await exchange
.setSignatureValidatorApproval(validatorWallet.address, approval) .setSignatureValidatorApproval(validatorWallet.address, approval)
.awaitTransactionSuccessAsync({ .awaitTransactionSuccessAsync({
from: signerAddress, from: signerAddress,
}); });
expect(res.logs.length).to.equal(1); expect(res.logs.length).to.equal(1);
const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs< const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
TestSignatureValidatorSignatureValidatorApprovalEventArgs ExchangeSignatureValidatorApprovalEventArgs
>; >;
const logArgs = log.args; const logArgs = log.args;
expect(logArgs.signerAddress).to.equal(signerAddress); expect(logArgs.signerAddress).to.equal(signerAddress);
@ -1121,14 +1121,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
}); });
it('should emit a SignatureValidatorApprovalSet with correct args when a validator is disapproved', async () => { it('should emit a SignatureValidatorApprovalSet with correct args when a validator is disapproved', async () => {
const approval = false; const approval = false;
const res = await signatureValidator const res = await exchange
.setSignatureValidatorApproval(validatorWallet.address, approval) .setSignatureValidatorApproval(validatorWallet.address, approval)
.awaitTransactionSuccessAsync({ .awaitTransactionSuccessAsync({
from: signerAddress, from: signerAddress,
}); });
expect(res.logs.length).to.equal(1); expect(res.logs.length).to.equal(1);
const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs< const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
TestSignatureValidatorSignatureValidatorApprovalEventArgs ExchangeSignatureValidatorApprovalEventArgs
>; >;
const logArgs = log.args; const logArgs = log.args;
expect(logArgs.signerAddress).to.equal(signerAddress); expect(logArgs.signerAddress).to.equal(signerAddress);
@ -1136,6 +1136,153 @@ blockchainTests.resets('MixinSignatureValidator', env => {
expect(logArgs.isApproved).to.equal(approval); expect(logArgs.isApproved).to.equal(approval);
}); });
}); });
describe('fillOrder integration tests', () => {
let erc20Wrapper: ERC20Wrapper;
let erc20Proxy: ERC20ProxyContract;
let erc20TokenA: DummyERC20TokenContract;
let erc20TokenB: DummyERC20TokenContract;
let feeToken: DummyERC20TokenContract;
let orderFactory: OrderFactory;
let signedOrder: SignedOrder;
before(async () => {
// Deploy ERC20 proxy and tokens
erc20Wrapper = new ERC20Wrapper(env.provider, accounts, owner);
erc20Proxy = await erc20Wrapper.deployProxyAsync();
const numDummyErc20ToDeploy = 3;
[erc20TokenA, erc20TokenB, feeToken] = await erc20Wrapper.deployDummyTokensAsync(
numDummyErc20ToDeploy,
constants.DUMMY_TOKEN_DECIMALS,
);
await erc20Wrapper.setBalancesAndAllowancesAsync();
// Configure ERC20 proxy and exchange
await erc20Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner });
await exchange.registerAssetProxy(erc20Proxy.address).awaitTransactionSuccessAsync({ from: owner });
// Configure order defaults
const defaultMakerAssetAddress = erc20TokenA.address;
const defaultTakerAssetAddress = erc20TokenB.address;
const defaultFeeAssetAddress = feeToken.address;
const defaultOrderParams = {
...constants.STATIC_ORDER_PARAMS,
makerAddress,
feeRecipientAddress,
makerAssetData: await devUtils.encodeERC20AssetData(defaultMakerAssetAddress).callAsync(),
takerAssetData: await devUtils.encodeERC20AssetData(defaultTakerAssetAddress).callAsync(),
makerFeeAssetData: await devUtils.encodeERC20AssetData(defaultFeeAssetAddress).callAsync(),
takerFeeAssetData: await devUtils.encodeERC20AssetData(defaultFeeAssetAddress).callAsync(),
exchangeAddress: exchange.address,
chainId,
};
const privateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddress)];
orderFactory = new OrderFactory(privateKey, defaultOrderParams);
// Approve the ERC20 proxy with the test validator wallet.
await validatorWallet
.approveERC20(erc20TokenA.address, erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE)
.awaitTransactionSuccessAsync();
// Mint some ERC20 tokens to the test validator wallet.
await erc20TokenA
.setBalance(validatorWallet.address, constants.INITIAL_ERC20_BALANCE)
.awaitTransactionSuccessAsync();
// Approve the validator.
await exchange.setSignatureValidatorApproval(validatorWallet.address, true).awaitTransactionSuccessAsync({
from: makerAddress,
});
signedOrder = await orderFactory.newSignedOrderAsync({
makerFee: constants.ZERO_AMOUNT,
takerFee: constants.ZERO_AMOUNT,
});
});
it('should revert if `Validator` signature type rejects during a second fill', async () => {
const signatureHex = hexConcat(validatorWallet.address, SignatureType.Validator);
signedOrder.signature = signatureHex;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
from: takerAddress,
});
// Reject the signature check for the second fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const tx = exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
from: takerAddress,
});
const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
orderHashHex,
signedOrder.makerAddress,
signedOrder.signature,
);
return expect(tx).to.revertWith(expectedError);
});
it('should revert if `Wallet` signature type rejects during a second fill', async () => {
const signatureHex = hexConcat(SignatureType.Wallet);
signedOrder.makerAddress = validatorWallet.address;
signedOrder.signature = signatureHex;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
from: takerAddress,
});
// Reject the signature check for the second fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const tx = exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
from: takerAddress,
});
const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
orderHashHex,
signedOrder.makerAddress,
signedOrder.signature,
);
return expect(tx).to.revertWith(expectedError);
});
it('should revert if `EIP1271Wallet` signature type rejects during a second fill', async () => {
const signatureHex = hexConcat(SignatureType.EIP1271Wallet);
signedOrder.makerAddress = validatorWallet.address;
signedOrder.signature = signatureHex;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
from: takerAddress,
});
// Reject the signature check for the second fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const tx = exchange.fillOrder(signedOrder, fillAmount, signedOrder.signature).awaitTransactionSuccessAsync({
from: takerAddress,
});
const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
orderHashHex,
signedOrder.makerAddress,
signedOrder.signature,
);
return expect(tx).to.revertWith(expectedError);
});
});
}); });
// tslint:disable:max-file-line-count // tslint:disable:max-file-line-count
// tslint:enable:no-unnecessary-type-assertion // tslint:enable:no-unnecessary-type-assertion

View File

@ -14,14 +14,3 @@ export const constants = {
ExchangeFunctionName.DetachProtocolFeeCollector, ExchangeFunctionName.DetachProtocolFeeCollector,
], ],
}; };
export enum ValidatorWalletAction {
Reject = 0,
Accept = 1,
Revert = 2,
UpdateState = 3,
MatchSignatureHash = 4,
ReturnTrue = 5,
ReturnNothing = 6,
NTypes = 7,
}

View File

@ -35,7 +35,6 @@ export * from '../test/generated-wrappers/test_lib_exchange_rich_error_decoder';
export * from '../test/generated-wrappers/test_protocol_fee_collector'; export * from '../test/generated-wrappers/test_protocol_fee_collector';
export * from '../test/generated-wrappers/test_protocol_fees'; export * from '../test/generated-wrappers/test_protocol_fees';
export * from '../test/generated-wrappers/test_protocol_fees_receiver'; export * from '../test/generated-wrappers/test_protocol_fees_receiver';
export * from '../test/generated-wrappers/test_signature_validator';
export * from '../test/generated-wrappers/test_transactions'; export * from '../test/generated-wrappers/test_transactions';
export * from '../test/generated-wrappers/test_validator_wallet'; export * from '../test/generated-wrappers/test_validator_wallet';
export * from '../test/generated-wrappers/test_wrapper_functions'; export * from '../test/generated-wrappers/test_wrapper_functions';

View File

@ -37,7 +37,6 @@
"test/generated-artifacts/TestProtocolFeeCollector.json", "test/generated-artifacts/TestProtocolFeeCollector.json",
"test/generated-artifacts/TestProtocolFees.json", "test/generated-artifacts/TestProtocolFees.json",
"test/generated-artifacts/TestProtocolFeesReceiver.json", "test/generated-artifacts/TestProtocolFeesReceiver.json",
"test/generated-artifacts/TestSignatureValidator.json",
"test/generated-artifacts/TestTransactions.json", "test/generated-artifacts/TestTransactions.json",
"test/generated-artifacts/TestValidatorWallet.json", "test/generated-artifacts/TestValidatorWallet.json",
"test/generated-artifacts/TestWrapperFunctions.json" "test/generated-artifacts/TestWrapperFunctions.json"

View File

@ -70,6 +70,7 @@
"chai-as-promised": "^7.1.0", "chai-as-promised": "^7.1.0",
"chai-bignumber": "^3.0.0", "chai-bignumber": "^3.0.0",
"dirty-chai": "^2.0.1", "dirty-chai": "^2.0.1",
"js-combinatorics": "^0.5.3",
"make-promises-safe": "^1.1.0", "make-promises-safe": "^1.1.0",
"mocha": "^6.2.0", "mocha": "^6.2.0",
"npm-run-all": "^4.1.2", "npm-run-all": "^4.1.2",

View File

@ -1,3 +1,2 @@
export * from './artifacts'; export * from './artifacts';
export * from './wrappers'; export * from './wrappers';
export * from './function_assertions';

View File

@ -1,9 +0,0 @@
export { Actor } from './base';
export { Maker } from './maker';
export { PoolOperator } from './pool_operator';
export { FeeRecipient } from './fee_recipient';
export { Staker } from './staker';
export { Keeper } from './keeper';
export { Taker } from './taker';
export * from './hybrids';
export * from './utils';

View File

@ -1,13 +1,11 @@
import { CoordinatorContract, CoordinatorRevertErrors, SignedCoordinatorApproval } from '@0x/contracts-coordinator'; import { CoordinatorContract, CoordinatorRevertErrors, SignedCoordinatorApproval } from '@0x/contracts-coordinator';
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { import {
BlockchainBalanceStore,
ExchangeCancelEventArgs, ExchangeCancelEventArgs,
ExchangeCancelUpToEventArgs, ExchangeCancelUpToEventArgs,
exchangeDataEncoder, exchangeDataEncoder,
ExchangeEvents, ExchangeEvents,
ExchangeFillEventArgs, ExchangeFillEventArgs,
LocalBalanceStore,
} from '@0x/contracts-exchange'; } from '@0x/contracts-exchange';
import { import {
blockchainTests, blockchainTests,
@ -25,8 +23,13 @@ import { SignedOrder, SignedZeroExTransaction } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors'; import { Actor } from '../framework/actors/base';
import { DeploymentManager } from '../deployment_manager'; import { FeeRecipient } from '../framework/actors/fee_recipient';
import { Maker } from '../framework/actors/maker';
import { actorAddressesByName } from '../framework/actors/utils';
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
import { deployCoordinatorAsync } from './deploy_coordinator'; import { deployCoordinatorAsync } from './deploy_coordinator';

View File

@ -3,7 +3,7 @@ import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils'; import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../framework/deployment_manager';
/** /**
* Deploys a Coordinator contract configured to work alongside the provided `deployment`. * Deploys a Coordinator contract configured to work alongside the provided `deployment`.

View File

@ -33,7 +33,7 @@ import { AssetProxyId } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { TxData } from 'ethereum-types'; import { TxData } from 'ethereum-types';
import { AssetProxyDispatcher, Authorizable, Ownable } from '../wrapper_interfaces'; import { AssetProxyDispatcher, Authorizable, Ownable } from './framework/wrapper_interfaces';
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
blockchainTests('Deployment and Configuration End to End Tests', env => { blockchainTests('Deployment and Configuration End to End Tests', env => {

View File

@ -18,6 +18,7 @@ import {
DummyNoReturnERC20TokenContract, DummyNoReturnERC20TokenContract,
} from '@0x/contracts-erc20'; } from '@0x/contracts-erc20';
import { DummyERC721TokenContract } from '@0x/contracts-erc721'; import { DummyERC721TokenContract } from '@0x/contracts-erc721';
import { artifacts, ExchangeCancelEventArgs, ExchangeContract, ExchangeRevertErrors } from '@0x/contracts-exchange';
import { LibMathRevertErrors } from '@0x/contracts-exchange-libs'; import { LibMathRevertErrors } from '@0x/contracts-exchange-libs';
import { import {
blockchainTests, blockchainTests,
@ -26,7 +27,6 @@ import {
ERC20BalancesByOwner, ERC20BalancesByOwner,
expect, expect,
getLatestBlockTimestampAsync, getLatestBlockTimestampAsync,
hexConcat,
increaseTimeAndMineBlockAsync, increaseTimeAndMineBlockAsync,
OrderFactory, OrderFactory,
orderHashUtils, orderHashUtils,
@ -35,20 +35,13 @@ import {
txDefaults, txDefaults,
web3Wrapper, web3Wrapper,
} from '@0x/contracts-test-utils'; } from '@0x/contracts-test-utils';
import { RevertReason, SignatureType, SignedOrder } from '@0x/types'; import { RevertReason, SignedOrder } from '@0x/types';
import { BigNumber, providerUtils, StringRevertError } from '@0x/utils'; import { BigNumber, providerUtils, StringRevertError } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper'; import { Web3Wrapper } from '@0x/web3-wrapper';
import { LogWithDecodedArgs } from 'ethereum-types'; import { LogWithDecodedArgs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import ExchangeRevertErrors = require('../src/revert_errors'); import { FillOrderWrapper } from './fill_order_wrapper';
import { ValidatorWalletAction } from './utils/constants';
import { ExchangeWrapper } from './utils/exchange_wrapper';
import { artifacts } from './artifacts';
import { FillOrderWrapper } from './assertion_wrappers/fill_order_wrapper';
import { ExchangeCancelEventArgs, ExchangeContract, TestValidatorWalletContract } from './wrappers';
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
blockchainTests.resets('Exchange core', () => { blockchainTests.resets('Exchange core', () => {
@ -69,14 +62,12 @@ blockchainTests.resets('Exchange core', () => {
let erc721Proxy: ERC721ProxyContract; let erc721Proxy: ERC721ProxyContract;
let erc1155Proxy: ERC1155ProxyContract; let erc1155Proxy: ERC1155ProxyContract;
let multiAssetProxy: MultiAssetProxyContract; let multiAssetProxy: MultiAssetProxyContract;
let validatorWallet: TestValidatorWalletContract;
let erc1155Contract: ERC1155MintableContract; let erc1155Contract: ERC1155MintableContract;
let staticCallProxy: StaticCallProxyContract; let staticCallProxy: StaticCallProxyContract;
let staticCallTarget: TestStaticCallTargetContract; let staticCallTarget: TestStaticCallTargetContract;
let signedOrder: SignedOrder; let signedOrder: SignedOrder;
let erc20Balances: ERC20BalancesByOwner; let erc20Balances: ERC20BalancesByOwner;
let exchangeWrapper: ExchangeWrapper;
let erc20Wrapper: ERC20Wrapper; let erc20Wrapper: ERC20Wrapper;
let erc721Wrapper: ERC721Wrapper; let erc721Wrapper: ERC721Wrapper;
let erc1155Wrapper: Erc1155Wrapper; let erc1155Wrapper: Erc1155Wrapper;
@ -147,13 +138,6 @@ blockchainTests.resets('Exchange core', () => {
{}, {},
new BigNumber(chainId), new BigNumber(chainId),
); );
validatorWallet = await TestValidatorWalletContract.deployFrom0xArtifactAsync(
artifacts.TestValidatorWallet,
provider,
txDefaults,
{},
exchange.address,
);
// Configure ERC20Proxy // Configure ERC20Proxy
await erc20Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner }); await erc20Proxy.addAuthorizedAddress(exchange.address).awaitTransactionSuccessAsync({ from: owner });
await erc20Proxy.addAuthorizedAddress(multiAssetProxy.address).awaitTransactionSuccessAsync({ from: owner }); await erc20Proxy.addAuthorizedAddress(multiAssetProxy.address).awaitTransactionSuccessAsync({ from: owner });
@ -173,12 +157,9 @@ blockchainTests.resets('Exchange core', () => {
await multiAssetProxy.registerAssetProxy(staticCallProxy.address).awaitTransactionSuccessAsync({ from: owner }); await multiAssetProxy.registerAssetProxy(staticCallProxy.address).awaitTransactionSuccessAsync({ from: owner });
// Configure Exchange // Configure Exchange
exchangeWrapper = new ExchangeWrapper(exchange); for (const proxy of [erc20Proxy, erc721Proxy, erc1155Proxy, multiAssetProxy, staticCallProxy]) {
await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner); await exchange.registerAssetProxy(proxy.address).awaitTransactionSuccessAsync({ from: owner });
await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner); }
await exchangeWrapper.registerAssetProxyAsync(erc1155Proxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(multiAssetProxy.address, owner);
await exchangeWrapper.registerAssetProxyAsync(staticCallProxy.address, owner);
// Configure ERC20 tokens // Configure ERC20 tokens
await erc20Wrapper.setBalancesAndAllowancesAsync(); await erc20Wrapper.setBalancesAndAllowancesAsync();
@ -252,115 +233,16 @@ blockchainTests.resets('Exchange core', () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await orderFactory.newSignedOrderAsync();
}); });
describe('callback signature types', () => {
beforeEach(async () => {
// Approve the ERC20 proxy with the test validator wallet.
await validatorWallet
.approveERC20(erc20TokenA.address, erc20Proxy.address, constants.INITIAL_ERC20_ALLOWANCE)
.awaitTransactionSuccessAsync();
// Mint some ERC20 tokens to the test validator wallet.
await erc20TokenA
.setBalance(validatorWallet.address, constants.INITIAL_ERC20_BALANCE)
.awaitTransactionSuccessAsync();
// Approve the validator.
await exchange
.setSignatureValidatorApproval(validatorWallet.address, true)
.awaitTransactionSuccessAsync({
from: makerAddress,
});
signedOrder = await orderFactory.newSignedOrderAsync({
makerFee: constants.ZERO_AMOUNT,
takerFee: constants.ZERO_AMOUNT,
});
});
it('should revert if `Validator` signature type rejects during a second fill', async () => {
const signatureHex = hexConcat(validatorWallet.address, SignatureType.Validator);
signedOrder.signature = signatureHex;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
// Reject the signature check for the second fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: fillAmount,
});
const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
orderHashHex,
signedOrder.makerAddress,
signedOrder.signature,
);
return expect(tx).to.revertWith(expectedError);
});
it('should revert if `Wallet` signature type rejects during a second fill', async () => {
const signatureHex = hexConcat(SignatureType.Wallet);
signedOrder.makerAddress = validatorWallet.address;
signedOrder.signature = signatureHex;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
// Reject the signature check for the second fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: fillAmount,
});
const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
orderHashHex,
signedOrder.makerAddress,
signedOrder.signature,
);
return expect(tx).to.revertWith(expectedError);
});
it('should revert if `EIP1271Wallet` signature type rejects during a second fill', async () => {
const signatureHex = hexConcat(SignatureType.EIP1271Wallet);
signedOrder.makerAddress = validatorWallet.address;
signedOrder.signature = signatureHex;
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
// Allow the signature check for the first fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Accept, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const fillAmount = signedOrder.takerAssetAmount.div(10);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount: fillAmount });
// Reject the signature check for the second fill.
await validatorWallet
.prepare(orderHashHex, ValidatorWalletAction.Reject, constants.NULL_BYTES)
.awaitTransactionSuccessAsync();
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
takerAssetFillAmount: fillAmount,
});
const expectedError = new ExchangeRevertErrors.SignatureError(
ExchangeRevertErrors.SignatureErrorCode.BadOrderSignature,
orderHashHex,
signedOrder.makerAddress,
signedOrder.signature,
);
return expect(tx).to.revertWith(expectedError);
});
});
it('should revert if fully filled', async () => { it('should revert if fully filled', async () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await orderFactory.newSignedOrderAsync();
const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); await exchange
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHashHex, OrderStatus.FullyFilled); const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHashHex, OrderStatus.FullyFilled);
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); const tx = exchange
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -375,7 +257,9 @@ blockchainTests.resets('Exchange core', () => {
}); });
const orderHash = orderHashUtils.getOrderHashHex(signedOrder); const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Expired); const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Expired);
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); const tx = exchange
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -386,9 +270,9 @@ blockchainTests.resets('Exchange core', () => {
}); });
const fillTakerAssetAmount1 = new BigNumber(2); const fillTakerAssetAmount1 = new BigNumber(2);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { await exchange
takerAssetFillAmount: fillTakerAssetAmount1, .fillOrder(signedOrder, fillTakerAssetAmount1, signedOrder.signature)
}); .awaitTransactionSuccessAsync({ from: takerAddress });
const fillTakerAssetAmount2 = new BigNumber(1); const fillTakerAssetAmount2 = new BigNumber(1);
const expectedError = new LibMathRevertErrors.RoundingError( const expectedError = new LibMathRevertErrors.RoundingError(
@ -396,9 +280,9 @@ blockchainTests.resets('Exchange core', () => {
new BigNumber(3), new BigNumber(3),
new BigNumber(1001), new BigNumber(1001),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { const tx = exchange
takerAssetFillAmount: fillTakerAssetAmount2, .fillOrder(signedOrder, fillTakerAssetAmount2, signedOrder.signature)
}); .awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
}); });
@ -500,7 +384,7 @@ blockchainTests.resets('Exchange core', () => {
orderHash, orderHash,
takerAddress, takerAddress,
); );
const tx = exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress); const tx = exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -508,7 +392,7 @@ blockchainTests.resets('Exchange core', () => {
signedOrder = await orderFactory.newSignedOrderAsync({ signedOrder = await orderFactory.newSignedOrderAsync({
makerAssetAmount: new BigNumber(0), makerAssetAmount: new BigNumber(0),
}); });
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
expect(tx.logs.length).to.equal(0); expect(tx.logs.length).to.equal(0);
}); });
@ -516,22 +400,22 @@ blockchainTests.resets('Exchange core', () => {
signedOrder = await orderFactory.newSignedOrderAsync({ signedOrder = await orderFactory.newSignedOrderAsync({
takerAssetAmount: new BigNumber(0), takerAssetAmount: new BigNumber(0),
}); });
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
expect(tx.logs.length).to.equal(0); expect(tx.logs.length).to.equal(0);
}); });
it('should be able to cancel an order', async () => { it('should be able to cancel an order', async () => {
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
const orderHash = orderHashUtils.getOrderHashHex(signedOrder); const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Cancelled); const expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Cancelled);
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { const tx = exchange
takerAssetFillAmount: signedOrder.takerAssetAmount.div(2), .fillOrder(signedOrder, signedOrder.takerAssetAmount.div(2), signedOrder.signature)
}); .awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should log 1 event with correct arguments if cancelled successfully', async () => { it('should log 1 event with correct arguments if cancelled successfully', async () => {
const res = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); const res = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
expect(res.logs).to.have.length(1); expect(res.logs).to.have.length(1);
const log = res.logs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>; const log = res.logs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>;
@ -546,8 +430,8 @@ blockchainTests.resets('Exchange core', () => {
}); });
it('should noop if already cancelled', async () => { it('should noop if already cancelled', async () => {
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
expect(tx.logs.length).to.equal(0); expect(tx.logs.length).to.equal(0);
}); });
@ -556,7 +440,7 @@ blockchainTests.resets('Exchange core', () => {
signedOrder = await orderFactory.newSignedOrderAsync({ signedOrder = await orderFactory.newSignedOrderAsync({
expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10), expirationTimeSeconds: new BigNumber(currentTimestamp).minus(10),
}); });
const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
expect(tx.logs.length).to.equal(0); expect(tx.logs.length).to.equal(0);
}); });
}); });
@ -564,33 +448,33 @@ blockchainTests.resets('Exchange core', () => {
describe('cancelOrdersUpTo', () => { describe('cancelOrdersUpTo', () => {
it('should fail to set orderEpoch less than current orderEpoch', async () => { it('should fail to set orderEpoch less than current orderEpoch', async () => {
const orderEpoch = new BigNumber(1); const orderEpoch = new BigNumber(1);
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress); await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
const lesserOrderEpoch = new BigNumber(0); const lesserOrderEpoch = new BigNumber(0);
const expectedError = new ExchangeRevertErrors.OrderEpochError( const expectedError = new ExchangeRevertErrors.OrderEpochError(
makerAddress, makerAddress,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
orderEpoch.plus(1), orderEpoch.plus(1),
); );
const tx = exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress); const tx = exchange.cancelOrdersUpTo(lesserOrderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should fail to set orderEpoch equal to existing orderEpoch', async () => { it('should fail to set orderEpoch equal to existing orderEpoch', async () => {
const orderEpoch = new BigNumber(1); const orderEpoch = new BigNumber(1);
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress); await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
const expectedError = new ExchangeRevertErrors.OrderEpochError( const expectedError = new ExchangeRevertErrors.OrderEpochError(
makerAddress, makerAddress,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
orderEpoch.plus(1), orderEpoch.plus(1),
); );
const tx = exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress); const tx = exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should cancel only orders with a orderEpoch less than existing orderEpoch', async () => { it('should cancel only orders with a orderEpoch less than existing orderEpoch', async () => {
// Cancel all transactions with a orderEpoch less than 2 // Cancel all transactions with a orderEpoch less than 2
const orderEpoch = new BigNumber(1); const orderEpoch = new BigNumber(1);
await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress); await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
// Create 4 orders with orderEpoch values: 0,1,2,3 // Create 4 orders with orderEpoch values: 0,1,2,3
// Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed // Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed
@ -617,8 +501,13 @@ blockchainTests.resets('Exchange core', () => {
salt: new BigNumber(3), salt: new BigNumber(3),
}), }),
]; ];
await exchangeWrapper.batchFillOrdersNoThrowAsync(signedOrders, takerAddress); await exchange
.batchFillOrdersNoThrow(
signedOrders,
signedOrders.map(order => order.takerAssetAmount),
signedOrders.map(order => order.signature),
)
.awaitTransactionSuccessAsync({ from: takerAddress });
const newBalances = await erc20Wrapper.getBalancesAsync(); const newBalances = await erc20Wrapper.getBalancesAsync();
const fillMakerAssetAmount = signedOrders[2].makerAssetAmount.plus(signedOrders[3].makerAssetAmount); const fillMakerAssetAmount = signedOrders[2].makerAssetAmount.plus(signedOrders[3].makerAssetAmount);
const fillTakerAssetAmount = signedOrders[2].takerAssetAmount.plus(signedOrders[3].takerAssetAmount); const fillTakerAssetAmount = signedOrders[2].takerAssetAmount.plus(signedOrders[3].takerAssetAmount);
@ -672,7 +561,9 @@ blockchainTests.resets('Exchange core', () => {
signedOrder.makerAssetData, signedOrder.makerAssetData,
new StringRevertError(RevertReason.TransferFailed).encode(), new StringRevertError(RevertReason.TransferFailed).encode(),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); const tx = exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -699,7 +590,9 @@ blockchainTests.resets('Exchange core', () => {
signedOrder.takerAssetData, signedOrder.takerAssetData,
new StringRevertError(RevertReason.TransferFailed).encode(), new StringRevertError(RevertReason.TransferFailed).encode(),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); const tx = exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -726,7 +619,9 @@ blockchainTests.resets('Exchange core', () => {
signedOrder.makerAssetData, signedOrder.makerAssetData,
new StringRevertError(RevertReason.InvalidAmount).encode(), new StringRevertError(RevertReason.InvalidAmount).encode(),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); const tx = exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -753,7 +648,9 @@ blockchainTests.resets('Exchange core', () => {
signedOrder.takerAssetData, signedOrder.takerAssetData,
new StringRevertError(RevertReason.InvalidAmount).encode(), new StringRevertError(RevertReason.InvalidAmount).encode(),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); const tx = exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -773,7 +670,9 @@ blockchainTests.resets('Exchange core', () => {
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); const tx = exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
}); });
@ -1102,7 +1001,9 @@ blockchainTests.resets('Exchange core', () => {
assetData, assetData,
new StringRevertError(RevertReason.TargetNotEven).encode(), new StringRevertError(RevertReason.TargetNotEven).encode(),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); const tx = exchange
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should fill the order if the staticcall is successful', async () => { it('should fill the order if the staticcall is successful', async () => {
@ -1133,7 +1034,9 @@ blockchainTests.resets('Exchange core', () => {
assetData, assetData,
new StringRevertError(RevertReason.TargetNotEven).encode(), new StringRevertError(RevertReason.TargetNotEven).encode(),
); );
const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); const tx = exchange
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('should fill the order is the staticcall is successful using the MultiAssetProxy', async () => { it('should fill the order is the staticcall is successful using the MultiAssetProxy', async () => {
@ -1159,7 +1062,7 @@ blockchainTests.resets('Exchange core', () => {
signedOrder = await orderFactory.newSignedOrderAsync(); signedOrder = await orderFactory.newSignedOrderAsync();
}); });
it('should return the correct orderInfo for an unfilled valid order', async () => { it('should return the correct orderInfo for an unfilled valid order', async () => {
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = new BigNumber(0); const expectedTakerAssetFilledAmount = new BigNumber(0);
const expectedOrderStatus = OrderStatus.Fillable; const expectedOrderStatus = OrderStatus.Fillable;
@ -1175,8 +1078,8 @@ blockchainTests.resets('Exchange core', () => {
await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress, { takerAssetFillAmount }); await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress, { takerAssetFillAmount });
}); });
it('should return the correct orderInfo for a cancelled and unfilled order', async () => { it('should return the correct orderInfo for a cancelled and unfilled order', async () => {
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = new BigNumber(0); const expectedTakerAssetFilledAmount = new BigNumber(0);
const expectedOrderStatus = OrderStatus.Cancelled; const expectedOrderStatus = OrderStatus.Cancelled;
@ -1186,9 +1089,11 @@ blockchainTests.resets('Exchange core', () => {
}); });
it('should return the correct orderInfo for a cancelled and partially filled order', async () => { it('should return the correct orderInfo for a cancelled and partially filled order', async () => {
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2); const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); await exchange
await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress); .fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); .awaitTransactionSuccessAsync({ from: takerAddress });
await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = takerAssetFillAmount; const expectedTakerAssetFilledAmount = takerAssetFillAmount;
const expectedOrderStatus = OrderStatus.Cancelled; const expectedOrderStatus = OrderStatus.Cancelled;
@ -1200,7 +1105,7 @@ blockchainTests.resets('Exchange core', () => {
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber(); const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
await increaseTimeAndMineBlockAsync(timeUntilExpiration); await increaseTimeAndMineBlockAsync(timeUntilExpiration);
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = new BigNumber(0); const expectedTakerAssetFilledAmount = new BigNumber(0);
const expectedOrderStatus = OrderStatus.Expired; const expectedOrderStatus = OrderStatus.Expired;
@ -1210,11 +1115,13 @@ blockchainTests.resets('Exchange core', () => {
}); });
it('should return the correct orderInfo for an expired and partially filled order', async () => { it('should return the correct orderInfo for an expired and partially filled order', async () => {
const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2); const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount }); await exchange
.fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber(); const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
await increaseTimeAndMineBlockAsync(timeUntilExpiration); await increaseTimeAndMineBlockAsync(timeUntilExpiration);
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = takerAssetFillAmount; const expectedTakerAssetFilledAmount = takerAssetFillAmount;
const expectedOrderStatus = OrderStatus.Expired; const expectedOrderStatus = OrderStatus.Expired;
@ -1223,11 +1130,13 @@ blockchainTests.resets('Exchange core', () => {
expect(orderInfo.orderStatus).to.equal(expectedOrderStatus); expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
}); });
it('should return the correct orderInfo for an expired and fully filled order', async () => { it('should return the correct orderInfo for an expired and fully filled order', async () => {
await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress); await exchange
.fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
.awaitTransactionSuccessAsync({ from: takerAddress });
const currentTimestamp = await getLatestBlockTimestampAsync(); const currentTimestamp = await getLatestBlockTimestampAsync();
const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber(); const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
await increaseTimeAndMineBlockAsync(timeUntilExpiration); await increaseTimeAndMineBlockAsync(timeUntilExpiration);
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount; const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
// FULLY_FILLED takes precedence over EXPIRED // FULLY_FILLED takes precedence over EXPIRED
@ -1238,7 +1147,7 @@ blockchainTests.resets('Exchange core', () => {
}); });
it('should return the correct orderInfo for an order with a makerAssetAmount of 0', async () => { it('should return the correct orderInfo for an order with a makerAssetAmount of 0', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(0) }); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(0) });
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = new BigNumber(0); const expectedTakerAssetFilledAmount = new BigNumber(0);
const expectedOrderStatus = OrderStatus.InvalidMakerAssetAmount; const expectedOrderStatus = OrderStatus.InvalidMakerAssetAmount;
@ -1248,7 +1157,7 @@ blockchainTests.resets('Exchange core', () => {
}); });
it('should return the correct orderInfo for an order with a takerAssetAmount of 0', async () => { it('should return the correct orderInfo for an order with a takerAssetAmount of 0', async () => {
signedOrder = await orderFactory.newSignedOrderAsync({ takerAssetAmount: new BigNumber(0) }); signedOrder = await orderFactory.newSignedOrderAsync({ takerAssetAmount: new BigNumber(0) });
const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder); const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder); const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
const expectedTakerAssetFilledAmount = new BigNumber(0); const expectedTakerAssetFilledAmount = new BigNumber(0);
const expectedOrderStatus = OrderStatus.InvalidTakerAssetAmount; const expectedOrderStatus = OrderStatus.InvalidTakerAssetAmount;

View File

@ -1,12 +1,6 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20'; import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
import { import { ExchangeRevertErrors, IExchangeEvents, IExchangeFillEventArgs } from '@0x/contracts-exchange';
BlockchainBalanceStore,
ExchangeRevertErrors,
IExchangeEvents,
IExchangeFillEventArgs,
LocalBalanceStore,
} from '@0x/contracts-exchange';
import { ReferenceFunctions } from '@0x/contracts-exchange-libs'; import { ReferenceFunctions } from '@0x/contracts-exchange-libs';
import { import {
blockchainTests, blockchainTests,
@ -25,9 +19,11 @@ import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { Actor } from '../actors/base'; import { Actor } from '../framework/actors/base';
import { Maker } from '../actors/maker'; import { Maker } from '../framework/actors/maker';
import { DeploymentManager } from '../deployment_manager'; import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
const { addFillResults, safeGetPartialAmountFloor } = ReferenceFunctions; const { addFillResults, safeGetPartialAmountFloor } = ReferenceFunctions;

View File

@ -1,4 +1,5 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { ExchangeContract } from '@0x/contracts-exchange';
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs'; import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs';
import { import {
constants, constants,
@ -14,12 +15,10 @@ import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { ExchangeContract } from '../wrappers'; import { BalanceStore } from '../framework/balances/balance_store';
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { BalanceStore } from '../../src/balance_stores/balance_store'; import { LocalBalanceStore } from '../framework/balances/local_balance_store';
import { BlockchainBalanceStore } from '../../src/balance_stores/blockchain_balance_store'; import { TokenContractsByName, TokenIds, TokenOwnersByName } from '../framework/balances/types';
import { LocalBalanceStore } from '../../src/balance_stores/local_balance_store';
import { TokenContractsByName, TokenIds, TokenOwnersByName } from '../../src/balance_stores/types';
export class FillOrderWrapper { export class FillOrderWrapper {
private readonly _blockchainBalanceStore: BlockchainBalanceStore; private readonly _blockchainBalanceStore: BlockchainBalanceStore;

View File

@ -1,11 +1,6 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20'; import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
import { import { ExchangeEvents, ExchangeFillEventArgs } from '@0x/contracts-exchange';
BlockchainBalanceStore,
ExchangeEvents,
ExchangeFillEventArgs,
LocalBalanceStore,
} from '@0x/contracts-exchange';
import { ReferenceFunctions } from '@0x/contracts-exchange-libs'; import { ReferenceFunctions } from '@0x/contracts-exchange-libs';
import { import {
constants as stakingConstants, constants as stakingConstants,
@ -28,8 +23,14 @@ import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import { actorAddressesByName, FeeRecipient, Maker, OperatorStakerMaker, StakerKeeper, Taker } from '../actors'; import { FeeRecipient } from '../framework/actors/fee_recipient';
import { DeploymentManager } from '../deployment_manager'; import { OperatorStakerMaker, StakerKeeper } from '../framework/actors/hybrids';
import { Maker } from '../framework/actors/maker';
import { Taker } from '../framework/actors/taker';
import { actorAddressesByName } from '../framework/actors/utils';
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider);
blockchainTests.resets('fillOrder integration tests', env => { blockchainTests.resets('fillOrder integration tests', env => {

View File

@ -3,7 +3,7 @@ import { artifacts, ForwarderContract } from '@0x/contracts-exchange-forwarder';
import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils'; import { BlockchainTestsEnvironment } from '@0x/contracts-test-utils';
import { assetDataUtils } from '@0x/order-utils'; import { assetDataUtils } from '@0x/order-utils';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../framework/deployment_manager';
/** /**
* Deploys a Forwarder contract configured to work alongside the provided `deployment`. * Deploys a Forwarder contract configured to work alongside the provided `deployment`.

View File

@ -1,12 +1,7 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { DummyERC20TokenContract } from '@0x/contracts-erc20';
import { DummyERC721TokenContract } from '@0x/contracts-erc721'; import { DummyERC721TokenContract } from '@0x/contracts-erc721';
import { import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange';
artifacts as exchangeArtifacts,
BlockchainBalanceStore,
ExchangeContract,
LocalBalanceStore,
} from '@0x/contracts-exchange';
import { artifacts, ForwarderContract, ForwarderRevertErrors } from '@0x/contracts-exchange-forwarder'; import { artifacts, ForwarderContract, ForwarderRevertErrors } from '@0x/contracts-exchange-forwarder';
import { import {
blockchainTests, blockchainTests,
@ -19,8 +14,13 @@ import {
} from '@0x/contracts-test-utils'; } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors'; import { FeeRecipient } from '../framework/actors/fee_recipient';
import { DeploymentManager } from '../deployment_manager'; import { Maker } from '../framework/actors/maker';
import { Taker } from '../framework/actors/taker';
import { actorAddressesByName } from '../framework/actors/utils';
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
import { deployForwarderAsync } from './deploy_forwarder'; import { deployForwarderAsync } from './deploy_forwarder';
import { ForwarderTestFactory } from './forwarder_test_factory'; import { ForwarderTestFactory } from './forwarder_test_factory';
@ -42,7 +42,7 @@ blockchainTests('Forwarder integration tests', env => {
let makerAssetData: string; let makerAssetData: string;
let maker: Maker; let maker: Maker;
let taker: Actor; let taker: Taker;
let orderFeeRecipient: FeeRecipient; let orderFeeRecipient: FeeRecipient;
let forwarderFeeRecipient: FeeRecipient; let forwarderFeeRecipient: FeeRecipient;
@ -59,7 +59,7 @@ blockchainTests('Forwarder integration tests', env => {
wethAssetData = await devUtils.encodeERC20AssetData(deployment.tokens.weth.address).callAsync(); wethAssetData = await devUtils.encodeERC20AssetData(deployment.tokens.weth.address).callAsync();
makerAssetData = await devUtils.encodeERC20AssetData(makerToken.address).callAsync(); makerAssetData = await devUtils.encodeERC20AssetData(makerToken.address).callAsync();
taker = new Actor({ name: 'Taker', deployment }); taker = new Taker({ name: 'Taker', deployment });
orderFeeRecipient = new FeeRecipient({ orderFeeRecipient = new FeeRecipient({
name: 'Order fee recipient', name: 'Order fee recipient',
deployment, deployment,
@ -560,14 +560,24 @@ blockchainTests('Forwarder integration tests', env => {
// Compute expected balances // Compute expected balances
const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore); const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore);
expectedBalances.transferAssetAsync(maker.address, taker.address, makerAssetFillAmount, makerAssetData); await expectedBalances.transferAssetAsync(
maker.address,
taker.address,
makerAssetFillAmount,
makerAssetData,
);
expectedBalances.wrapEth( expectedBalances.wrapEth(
taker.address, taker.address,
deployment.tokens.weth.address, deployment.tokens.weth.address,
takerAssetFillAmount.plus(DeploymentManager.protocolFee), takerAssetFillAmount.plus(DeploymentManager.protocolFee),
); );
expectedBalances.transferAssetAsync(taker.address, maker.address, takerAssetFillAmount, wethAssetData); await expectedBalances.transferAssetAsync(
expectedBalances.transferAssetAsync( taker.address,
maker.address,
takerAssetFillAmount,
wethAssetData,
);
await expectedBalances.transferAssetAsync(
taker.address, taker.address,
deployment.staking.stakingProxy.address, deployment.staking.stakingProxy.address,
DeploymentManager.protocolFee, DeploymentManager.protocolFee,

View File

@ -1,13 +1,16 @@
import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DevUtilsContract } from '@0x/contracts-dev-utils';
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
import { ForwarderContract } from '@0x/contracts-exchange-forwarder'; import { ForwarderContract } from '@0x/contracts-exchange-forwarder';
import { constants, expect, getPercentageOfValue, OrderStatus } from '@0x/contracts-test-utils'; import { constants, expect, getPercentageOfValue, OrderStatus } from '@0x/contracts-test-utils';
import { OrderInfo, SignedOrder } from '@0x/types'; import { OrderInfo, SignedOrder } from '@0x/types';
import { BigNumber, RevertError } from '@0x/utils'; import { BigNumber, RevertError } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import { Actor, FeeRecipient, Maker } from '../actors'; import { FeeRecipient } from '../framework/actors/fee_recipient';
import { DeploymentManager } from '../deployment_manager'; import { Maker } from '../framework/actors/maker';
import { Taker } from '../framework/actors/taker';
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
// Necessary bookkeeping to validate Forwarder results // Necessary bookkeeping to validate Forwarder results
interface ForwarderFillState { interface ForwarderFillState {
@ -31,7 +34,7 @@ export class ForwarderTestFactory {
private readonly _deployment: DeploymentManager, private readonly _deployment: DeploymentManager,
private readonly _balanceStore: BlockchainBalanceStore, private readonly _balanceStore: BlockchainBalanceStore,
private readonly _maker: Maker, private readonly _maker: Maker,
private readonly _taker: Actor, private readonly _taker: Taker,
private readonly _orderFeeRecipient: FeeRecipient, private readonly _orderFeeRecipient: FeeRecipient,
private readonly _forwarderFeeRecipient: FeeRecipient, private readonly _forwarderFeeRecipient: FeeRecipient,
private readonly _devUtils: DevUtilsContract, private readonly _devUtils: DevUtilsContract,

View File

@ -5,9 +5,9 @@ import { SignatureType, SignedZeroExTransaction, ZeroExTransaction } from '@0x/t
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { AssertionResult } from '../../src/function_assertions'; import { AssertionResult } from '../assertions/function_assertion';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../deployment_manager';
import { SimulationEnvironment } from '../simulation/simulation'; import { SimulationEnvironment } from '../simulation';
export type Constructor<T = {}> = new (...args: any[]) => T; export type Constructor<T = {}> = new (...args: any[]) => T;

View File

@ -4,11 +4,9 @@ import '@azure/core-asynciterator-polyfill';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { AssertionResult } from '../../src/function_assertions'; import { validCreateStakingPoolAssertion } from '../assertions/createStakingPool';
import { import { validDecreaseStakingPoolOperatorShareAssertion } from '../assertions/decreaseStakingPoolOperatorShare';
validCreateStakingPoolAssertion, import { AssertionResult } from '../assertions/function_assertion';
validDecreaseStakingPoolOperatorShareAssertion,
} from '../function-assertions';
import { Actor, Constructor } from './base'; import { Actor, Constructor } from './base';

View File

@ -4,8 +4,10 @@ import { BigNumber } from '@0x/utils';
import '@azure/core-asynciterator-polyfill'; import '@azure/core-asynciterator-polyfill';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { AssertionResult } from '../../src/function_assertions'; import { AssertionResult } from '../assertions/function_assertion';
import { validMoveStakeAssertion, validStakeAssertion, validUnstakeAssertion } from '../function-assertions'; import { validMoveStakeAssertion } from '../assertions/moveStake';
import { validStakeAssertion } from '../assertions/stake';
import { validUnstakeAssertion } from '../assertions/unstake';
import { Actor, Constructor } from './base'; import { Actor, Constructor } from './base';

View File

@ -3,9 +3,10 @@ import { expect } from '@0x/contracts-test-utils';
import { BigNumber, logUtils } from '@0x/utils'; import { BigNumber, logUtils } from '@0x/utils';
import { TxData } from 'ethereum-types'; import { TxData } from 'ethereum-types';
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../deployment_manager';
import { FunctionAssertion, FunctionResult } from './function_assertion';
// tslint:disable:no-unnecessary-type-assertion // tslint:disable:no-unnecessary-type-assertion
/** /**

View File

@ -2,9 +2,10 @@ import { StakingPoolById } from '@0x/contracts-staking';
import { expect } from '@0x/contracts-test-utils'; import { expect } from '@0x/contracts-test-utils';
import { logUtils } from '@0x/utils'; import { logUtils } from '@0x/utils';
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../deployment_manager';
import { FunctionAssertion, FunctionResult } from './function_assertion';
/** /**
* Returns a FunctionAssertion for `decreaseStakingPoolOperatorShare` which assumes valid input is * Returns a FunctionAssertion for `decreaseStakingPoolOperatorShare` which assumes valid input is
* provided. The FunctionAssertion checks that the operator share actually gets updated. * provided. The FunctionAssertion checks that the operator share actually gets updated.

View File

@ -106,79 +106,3 @@ export class FunctionAssertion<TBefore, ReturnDataType> implements Assertion {
}; };
} }
} }
export type IndexGenerator = () => number;
export type InputGenerator = () => Promise<any[]>;
export interface AssertionGenerator {
assertion: Assertion;
generator: InputGenerator;
}
/**
* This class is an abstract way to represent collections of function assertions.
* Using this, we can use closures to build up many useful collections with different
* properties. Notably, this abstraction supports function assertion collections
* that can be run continuously and also those that terminate in a finite number
* of steps.
*/
class MetaAssertion implements Assertion {
constructor(
protected readonly assertionGenerators: AssertionGenerator[],
protected readonly indexGenerator: IndexGenerator,
) {}
public async executeAsync(): Promise<void> {
let idx = this.indexGenerator();
while (idx > 0) {
const args = await this.assertionGenerators[idx].generator();
await this.assertionGenerators[idx].assertion.executeAsync(...args);
idx = this.indexGenerator();
}
}
}
/**
* Returns a class that can execute a set of function assertions in sequence.
* @param assertionGenerators A set of assertion generators to run in sequence.
*/
export function FunctionAssertionSequence(assertionGenerators: AssertionGenerator[]): MetaAssertion {
let idx = 0;
return new MetaAssertion(assertionGenerators, () => {
if (idx < assertionGenerators.length) {
return idx++;
} else {
idx = 0;
return -1;
}
});
}
export interface WeightedAssertionGenerator extends AssertionGenerator {
weight?: number;
}
/**
* Returns a class that can execute a set of function assertions at random continuously.
* This will not terminate unless the process that called `runAsync` terminates.
* @param weightedAssertionGenerators A set of function assertions that have been
* assigned weights.
*/
export function ContinuousFunctionAssertionSet(
weightedAssertionGenerators: WeightedAssertionGenerator[],
): MetaAssertion {
// Construct an array of assertion generators that allows random sampling from a
// uniform distribution to correctly bias assertion selection.
let assertionGenerators: AssertionGenerator[] = [];
for (const { assertion, generator, weight } of weightedAssertionGenerators) {
const weightedAssertions: AssertionGenerator[] = [];
_.fill(weightedAssertions, { assertion, generator }, 0, weight || 1);
assertionGenerators = assertionGenerators.concat(weightedAssertions);
}
// The index generator simply needs to sample from a uniform distribution.
const indexGenerator = () => Math.round(Math.random() * (assertionGenerators.length - 1));
return new MetaAssertion(assertionGenerators, indexGenerator);
}

View File

@ -11,9 +11,10 @@ import { BigNumber, logUtils } from '@0x/utils';
import { TxData } from 'ethereum-types'; import { TxData } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { FunctionAssertion } from '../../src/function_assertions';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../deployment_manager';
import { FunctionAssertion } from './function_assertion';
function incrementNextEpochBalance(stakeBalance: StoredBalance, amount: BigNumber): void { function incrementNextEpochBalance(stakeBalance: StoredBalance, amount: BigNumber): void {
_.update(stakeBalance, ['nextEpochBalance'], balance => (balance || constants.ZERO_AMOUNT).plus(amount)); _.update(stakeBalance, ['nextEpochBalance'], balance => (balance || constants.ZERO_AMOUNT).plus(amount));
} }

View File

@ -1,12 +1,14 @@
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking'; import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking';
import { expect } from '@0x/contracts-test-utils'; import { expect } from '@0x/contracts-test-utils';
import { BigNumber, logUtils } from '@0x/utils'; import { BigNumber, logUtils } from '@0x/utils';
import { TxData } from 'ethereum-types'; import { TxData } from 'ethereum-types';
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions'; import { BlockchainBalanceStore } from '../balances/blockchain_balance_store';
import { LocalBalanceStore } from '../balances/local_balance_store';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../deployment_manager';
import { FunctionAssertion, FunctionResult } from './function_assertion';
function expectedUndelegatedStake( function expectedUndelegatedStake(
initStake: OwnerStakeByStatus | GlobalStakeByStatus, initStake: OwnerStakeByStatus | GlobalStakeByStatus,
amount: BigNumber, amount: BigNumber,

View File

@ -1,12 +1,14 @@
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking'; import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking';
import { expect } from '@0x/contracts-test-utils'; import { expect } from '@0x/contracts-test-utils';
import { BigNumber, logUtils } from '@0x/utils'; import { BigNumber, logUtils } from '@0x/utils';
import { TxData } from 'ethereum-types'; import { TxData } from 'ethereum-types';
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions'; import { BlockchainBalanceStore } from '../balances/blockchain_balance_store';
import { LocalBalanceStore } from '../balances/local_balance_store';
import { DeploymentManager } from '../deployment_manager'; import { DeploymentManager } from '../deployment_manager';
import { FunctionAssertion, FunctionResult } from './function_assertion';
function expectedUndelegatedStake( function expectedUndelegatedStake(
initStake: OwnerStakeByStatus | GlobalStakeByStatus, initStake: OwnerStakeByStatus | GlobalStakeByStatus,
amount: BigNumber, amount: BigNumber,

View File

@ -1,9 +1,9 @@
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
import { GlobalStakeByStatus, StakeStatus, StakingPoolById, StoredBalance } from '@0x/contracts-staking'; import { GlobalStakeByStatus, StakeStatus, StakingPoolById, StoredBalance } from '@0x/contracts-staking';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { AssertionResult } from '../../src/function_assertions'; import { AssertionResult } from './assertions/function_assertion';
import { DeploymentManager } from '../deployment_manager'; import { BlockchainBalanceStore } from './balances/blockchain_balance_store';
import { DeploymentManager } from './deployment_manager';
// tslint:disable:max-classes-per-file // tslint:disable:max-classes-per-file

View File

@ -2,10 +2,9 @@ import { blockchainTests, constants, expect, filterLogsToArguments, getRandomInt
import { BigNumber, StringRevertError } from '@0x/utils'; import { BigNumber, StringRevertError } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions'; import { artifacts } from '../../artifacts';
import { TestFrameworkContract, TestFrameworkEventEventArgs, TestFrameworkEvents } from '../../wrappers';
import { artifacts } from '../artifacts'; import { FunctionAssertion, FunctionResult } from '../assertions/function_assertion';
import { TestFrameworkContract, TestFrameworkEventEventArgs, TestFrameworkEvents } from '../wrappers';
const { ZERO_AMOUNT, MAX_UINT256 } = constants; const { ZERO_AMOUNT, MAX_UINT256 } = constants;

View File

@ -1,5 +0,0 @@
export * from './stake';
export * from './unstake';
export * from './createStakingPool';
export * from './decreaseStakingPoolOperatorShare';
export * from './moveStake';

View File

@ -1,12 +1,11 @@
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
import { blockchainTests } from '@0x/contracts-test-utils'; import { blockchainTests } from '@0x/contracts-test-utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { AssertionResult } from '../../src/function_assertions'; import { PoolOperator } from '../framework/actors/pool_operator';
import { PoolOperator } from '../actors'; import { AssertionResult } from '../framework/assertions/function_assertion';
import { DeploymentManager } from '../deployment_manager'; import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
import { Simulation, SimulationEnvironment } from './simulation'; import { Simulation, SimulationEnvironment } from '../framework/simulation';
export class PoolManagementSimulation extends Simulation { export class PoolManagementSimulation extends Simulation {
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> { protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {

View File

@ -1,13 +1,13 @@
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
import { blockchainTests } from '@0x/contracts-test-utils'; import { blockchainTests } from '@0x/contracts-test-utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { AssertionResult } from '../../src/function_assertions'; import { Staker } from '../framework/actors/staker';
import { Staker } from '../actors'; import { AssertionResult } from '../framework/assertions/function_assertion';
import { DeploymentManager } from '../deployment_manager'; import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
import { DeploymentManager } from '../framework/deployment_manager';
import { Simulation, SimulationEnvironment } from '../framework/simulation';
import { PoolManagementSimulation } from './pool_management_test'; import { PoolManagementSimulation } from './pool_management_test';
import { Simulation, SimulationEnvironment } from './simulation';
export class StakeManagementSimulation extends Simulation { export class StakeManagementSimulation extends Simulation {
protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> { protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {

View File

@ -57,6 +57,7 @@ export {
TokenBalances, TokenBalances,
TransactionDataParams, TransactionDataParams,
ExchangeFunctionName, ExchangeFunctionName,
ValidatorWalletAction,
} from './types'; } from './types';
export { blockchainTests, BlockchainTestsEnvironment, describe } from './mocha_blockchain'; export { blockchainTests, BlockchainTestsEnvironment, describe } from './mocha_blockchain';
export { chaiSetup, expect } from './chai_setup'; export { chaiSetup, expect } from './chai_setup';

View File

@ -201,3 +201,14 @@ export enum ExchangeFunctionName {
SetProtocolFeeCollectorAddress = 'setProtocolFeeCollectorAddress', SetProtocolFeeCollectorAddress = 'setProtocolFeeCollectorAddress',
DetachProtocolFeeCollector = 'detachProtocolFeeCollector', DetachProtocolFeeCollector = 'detachProtocolFeeCollector',
} }
export enum ValidatorWalletAction {
Reject = 0,
Accept = 1,
Revert = 2,
UpdateState = 3,
MatchSignatureHash = 4,
ReturnTrue = 5,
ReturnNothing = 6,
NTypes = 7,
}