Refactor integrations directory structure; move core.ts, balance stores, and FillOrderWrapper to integrations
This commit is contained in:
		@@ -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))
 | 
			
		||||
    {}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,4 @@
 | 
			
		||||
export * from './artifacts';
 | 
			
		||||
export * from './wrappers';
 | 
			
		||||
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';
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@ import * as TestLibExchangeRichErrorDecoder from '../test/generated-artifacts/Te
 | 
			
		||||
import * as TestProtocolFeeCollector from '../test/generated-artifacts/TestProtocolFeeCollector.json';
 | 
			
		||||
import * as TestProtocolFees from '../test/generated-artifacts/TestProtocolFees.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 TestValidatorWallet from '../test/generated-artifacts/TestValidatorWallet.json';
 | 
			
		||||
import * as TestWrapperFunctions from '../test/generated-artifacts/TestWrapperFunctions.json';
 | 
			
		||||
@@ -74,7 +73,6 @@ export const artifacts = {
 | 
			
		||||
    TestProtocolFeeCollector: TestProtocolFeeCollector as ContractArtifact,
 | 
			
		||||
    TestProtocolFees: TestProtocolFees as ContractArtifact,
 | 
			
		||||
    TestProtocolFeesReceiver: TestProtocolFeesReceiver as ContractArtifact,
 | 
			
		||||
    TestSignatureValidator: TestSignatureValidator as ContractArtifact,
 | 
			
		||||
    TestTransactions: TestTransactions as ContractArtifact,
 | 
			
		||||
    TestValidatorWallet: TestValidatorWallet as ContractArtifact,
 | 
			
		||||
    TestWrapperFunctions: TestWrapperFunctions as ContractArtifact,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy';
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
 | 
			
		||||
import {
 | 
			
		||||
    blockchainTests,
 | 
			
		||||
    constants,
 | 
			
		||||
@@ -12,6 +14,7 @@ import {
 | 
			
		||||
    randomAddress,
 | 
			
		||||
    TransactionFactory,
 | 
			
		||||
    transactionHashUtils,
 | 
			
		||||
    ValidatorWalletAction,
 | 
			
		||||
} from '@0x/contracts-test-utils';
 | 
			
		||||
import { SignatureType, SignedOrder, SignedZeroExTransaction } from '@0x/types';
 | 
			
		||||
import { BigNumber, StringRevertError } from '@0x/utils';
 | 
			
		||||
@@ -22,33 +25,35 @@ import ExchangeRevertErrors = require('../src/revert_errors');
 | 
			
		||||
 | 
			
		||||
import { artifacts } from './artifacts';
 | 
			
		||||
import {
 | 
			
		||||
    ExchangeContract,
 | 
			
		||||
    ExchangeSignatureValidatorApprovalEventArgs,
 | 
			
		||||
    IEIP1271DataContract,
 | 
			
		||||
    TestSignatureValidatorContract,
 | 
			
		||||
    TestSignatureValidatorSignatureValidatorApprovalEventArgs,
 | 
			
		||||
    TestValidatorWalletContract,
 | 
			
		||||
} from './wrappers';
 | 
			
		||||
 | 
			
		||||
import { ValidatorWalletAction } from './utils/constants';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:no-unnecessary-type-assertion
 | 
			
		||||
blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
    let chainId: number;
 | 
			
		||||
    let signatureValidator: TestSignatureValidatorContract;
 | 
			
		||||
    let exchange: ExchangeContract;
 | 
			
		||||
    let validatorWallet: TestValidatorWalletContract;
 | 
			
		||||
    let validatorWalletRevertReason: string;
 | 
			
		||||
    let signerAddress: string;
 | 
			
		||||
    let signerPrivateKey: Buffer;
 | 
			
		||||
    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 eip1271Data = new IEIP1271DataContract(constants.NULL_ADDRESS, env.provider, env.txDefaults);
 | 
			
		||||
    before(async () => {
 | 
			
		||||
        chainId = await env.getChainIdAsync();
 | 
			
		||||
        const accounts = await env.getAccountAddressesAsync();
 | 
			
		||||
        signerAddress = accounts[0];
 | 
			
		||||
        notSignerAddress = accounts[1];
 | 
			
		||||
        signatureValidator = await TestSignatureValidatorContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.TestSignatureValidator,
 | 
			
		||||
        accounts = await env.getAccountAddressesAsync();
 | 
			
		||||
        [owner, signerAddress, notSignerAddress, makerAddress, takerAddress, feeRecipientAddress] = accounts;
 | 
			
		||||
        exchange = await ExchangeContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.Exchange,
 | 
			
		||||
            env.provider,
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            {},
 | 
			
		||||
@@ -59,14 +64,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
            env.provider,
 | 
			
		||||
            env.txDefaults,
 | 
			
		||||
            {},
 | 
			
		||||
            signatureValidator.address,
 | 
			
		||||
            exchange.address,
 | 
			
		||||
        );
 | 
			
		||||
        validatorWalletRevertReason = await validatorWallet.REVERT_REASON().callAsync();
 | 
			
		||||
 | 
			
		||||
        // Approve the validator for both signers.
 | 
			
		||||
        await Promise.all(
 | 
			
		||||
            [signerAddress, notSignerAddress].map(async (addr: string) => {
 | 
			
		||||
                return signatureValidator
 | 
			
		||||
                return exchange
 | 
			
		||||
                    .setSignatureValidatorApproval(validatorWallet.address, true)
 | 
			
		||||
                    .awaitTransactionSuccessAsync({ from: addr });
 | 
			
		||||
            }),
 | 
			
		||||
@@ -300,7 +305,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
        it('should return true when SignatureType=Presigned and signer has presigned hash', async () => {
 | 
			
		||||
            const hashHex = getCurrentHashHex();
 | 
			
		||||
            // Presign the hash
 | 
			
		||||
            await signatureValidator.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress });
 | 
			
		||||
            await exchange.preSign(hashHex).awaitTransactionSuccessAsync({ from: signerAddress });
 | 
			
		||||
            // Validate presigned signature
 | 
			
		||||
            const signatureHex = hexConcat(SignatureType.PreSigned);
 | 
			
		||||
            const isValidSignature = await validateAsync(hashHex, signerAddress, signatureHex);
 | 
			
		||||
@@ -338,7 +343,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                    .prepare(_hashHex, validatorAction, expectedSignatureHashHex)
 | 
			
		||||
                    .awaitTransactionSuccessAsync();
 | 
			
		||||
            }
 | 
			
		||||
            return signatureValidator.isValidHashSignature(_hashHex, _signerAddress, signatureHex).callAsync();
 | 
			
		||||
            return exchange.isValidHashSignature(_hashHex, _signerAddress, signatureHex).callAsync();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        it('should revert when signerAddress == 0', async () => {
 | 
			
		||||
@@ -387,9 +392,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
            const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`);
 | 
			
		||||
            const signature = Buffer.concat([v, r, s, trezorSignatureType]);
 | 
			
		||||
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
			
		||||
            const isValidSignature = await signatureValidator
 | 
			
		||||
                .isValidHashSignature(messageHash, signer, signatureHex)
 | 
			
		||||
                .callAsync();
 | 
			
		||||
            const isValidSignature = await exchange.isValidHashSignature(messageHash, signer, signatureHex).callAsync();
 | 
			
		||||
            expect(isValidSignature).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -403,9 +406,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
            const trezorSignatureType = ethUtil.toBuffer(`0x${SignatureType.EthSign}`);
 | 
			
		||||
            const signature = Buffer.concat([v, r, s, trezorSignatureType]);
 | 
			
		||||
            const signatureHex = ethUtil.bufferToHex(signature);
 | 
			
		||||
            const isValidSignature = await signatureValidator
 | 
			
		||||
                .isValidHashSignature(messageHash, signer, signatureHex)
 | 
			
		||||
                .callAsync();
 | 
			
		||||
            const isValidSignature = await exchange.isValidHashSignature(messageHash, signer, signatureHex).callAsync();
 | 
			
		||||
            expect(isValidSignature).to.be.true();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -417,10 +418,9 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
        let signedOrder: SignedOrder;
 | 
			
		||||
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            const makerAddress = signerAddress;
 | 
			
		||||
            const defaultOrderParams = {
 | 
			
		||||
                ...constants.STATIC_ORDER_PARAMS,
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                makerAddress: signerAddress,
 | 
			
		||||
                feeRecipientAddress: randomAddress(),
 | 
			
		||||
                makerAssetData: 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(),
 | 
			
		||||
                makerFee: constants.ZERO_AMOUNT,
 | 
			
		||||
                takerFee: constants.ZERO_AMOUNT,
 | 
			
		||||
                exchangeAddress: signatureValidator.address,
 | 
			
		||||
                exchangeAddress: exchange.address,
 | 
			
		||||
                chainId,
 | 
			
		||||
            };
 | 
			
		||||
            orderFactory = new OrderFactory(signerPrivateKey, defaultOrderParams);
 | 
			
		||||
@@ -454,7 +454,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                    .prepare(orderHashHex, validatorAction, expectedSignatureHashHex)
 | 
			
		||||
                    .awaitTransactionSuccessAsync();
 | 
			
		||||
            }
 | 
			
		||||
            return signatureValidator.isValidOrderSignature(order, signatureHex).callAsync();
 | 
			
		||||
            return exchange.isValidOrderSignature(order, signatureHex).callAsync();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        it('should revert when signerAddress == 0', async () => {
 | 
			
		||||
@@ -470,7 +470,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
                signatureHex,
 | 
			
		||||
            );
 | 
			
		||||
            const tx = signatureValidator.isValidOrderSignature(nullMakerOrder, signatureHex).callAsync();
 | 
			
		||||
            const tx = exchange.isValidOrderSignature(nullMakerOrder, signatureHex).callAsync();
 | 
			
		||||
            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 () => {
 | 
			
		||||
            // Set approval of signature validator to false
 | 
			
		||||
            await signatureValidator
 | 
			
		||||
            await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(validatorWallet.address, false)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: signedOrder.makerAddress });
 | 
			
		||||
            // 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 () => {
 | 
			
		||||
            // Set approval of signature validator to false
 | 
			
		||||
            await signatureValidator
 | 
			
		||||
            await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(validatorWallet.address, false)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: signedOrder.makerAddress });
 | 
			
		||||
            // Doesn't have to contain a real signature since our wallet contract
 | 
			
		||||
@@ -706,7 +706,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                signatureHex,
 | 
			
		||||
                constants.NULL_BYTES,
 | 
			
		||||
            );
 | 
			
		||||
            const tx = signatureValidator.isValidOrderSignature(signedOrder, signatureHex).callAsync();
 | 
			
		||||
            const tx = exchange.isValidOrderSignature(signedOrder, signatureHex).callAsync();
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -721,16 +721,16 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                constants.NULL_BYTES,
 | 
			
		||||
            );
 | 
			
		||||
            // Register an EOA as a validator.
 | 
			
		||||
            await signatureValidator
 | 
			
		||||
            await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(notSignerAddress, true)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: signerAddress });
 | 
			
		||||
            const tx = signatureValidator.isValidOrderSignature(signedOrder, signatureHex).callAsync();
 | 
			
		||||
            const tx = exchange.isValidOrderSignature(signedOrder, signatureHex).callAsync();
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Run hash-only signature type tests as well.
 | 
			
		||||
        const validateOrderHashAsync = async (
 | 
			
		||||
            hashHex: string,
 | 
			
		||||
            _hashHex: string,
 | 
			
		||||
            _signerAddress: string,
 | 
			
		||||
            signatureHex: string,
 | 
			
		||||
            validatorAction?: ValidatorWalletAction,
 | 
			
		||||
@@ -751,7 +751,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
        const TRANSACTION_DATA_LENGTH = 100;
 | 
			
		||||
 | 
			
		||||
        before(async () => {
 | 
			
		||||
            transactionFactory = new TransactionFactory(signerPrivateKey, signatureValidator.address, chainId);
 | 
			
		||||
            transactionFactory = new TransactionFactory(signerPrivateKey, exchange.address, chainId);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        beforeEach(async () => {
 | 
			
		||||
@@ -778,7 +778,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                    .prepare(transactionHashHex, validatorAction, expectedSignatureHashHex)
 | 
			
		||||
                    .awaitTransactionSuccessAsync();
 | 
			
		||||
            }
 | 
			
		||||
            return signatureValidator.isValidTransactionSignature(transaction, signatureHex).callAsync();
 | 
			
		||||
            return exchange.isValidTransactionSignature(transaction, signatureHex).callAsync();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        it('should revert when signerAddress == 0', async () => {
 | 
			
		||||
@@ -794,7 +794,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
                signatureHex,
 | 
			
		||||
            );
 | 
			
		||||
            const tx = signatureValidator.isValidTransactionSignature(nullSignerTransaction, signatureHex).callAsync();
 | 
			
		||||
            const tx = exchange.isValidTransactionSignature(nullSignerTransaction, signatureHex).callAsync();
 | 
			
		||||
            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 () => {
 | 
			
		||||
            // Set approval of signature validator to false
 | 
			
		||||
            await signatureValidator
 | 
			
		||||
            await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(validatorWallet.address, false)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress });
 | 
			
		||||
            // 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 () => {
 | 
			
		||||
            // Set approval of signature validator to false
 | 
			
		||||
            await signatureValidator
 | 
			
		||||
            await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(validatorWallet.address, false)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: signedTransaction.signerAddress });
 | 
			
		||||
            // Doesn't have to contain a real signature since our wallet contract
 | 
			
		||||
@@ -1055,7 +1055,7 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                signatureHex,
 | 
			
		||||
                constants.NULL_BYTES,
 | 
			
		||||
            );
 | 
			
		||||
            const tx = signatureValidator.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
 | 
			
		||||
            const tx = exchange.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -1072,16 +1072,16 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
                constants.NULL_BYTES,
 | 
			
		||||
            );
 | 
			
		||||
            // Register an EOA as a validator.
 | 
			
		||||
            await signatureValidator
 | 
			
		||||
            await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(notSignerAddress, true)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: signerAddress });
 | 
			
		||||
            const tx = signatureValidator.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
 | 
			
		||||
            const tx = exchange.isValidTransactionSignature(signedTransaction, signatureHex).callAsync();
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Run hash-only signature type tests as well.
 | 
			
		||||
        const validateOrderHashAsync = async (
 | 
			
		||||
            hashHex: string,
 | 
			
		||||
            _hashHex: string,
 | 
			
		||||
            _signerAddress: string,
 | 
			
		||||
            signatureHex: string,
 | 
			
		||||
            validatorAction?: ValidatorWalletAction,
 | 
			
		||||
@@ -1105,14 +1105,14 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
 | 
			
		||||
        it('should emit a SignatureValidatorApprovalSet with correct args when a validator is approved', async () => {
 | 
			
		||||
            const approval = true;
 | 
			
		||||
            const res = await signatureValidator
 | 
			
		||||
            const res = await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(validatorWallet.address, approval)
 | 
			
		||||
                .awaitTransactionSuccessAsync({
 | 
			
		||||
                    from: signerAddress,
 | 
			
		||||
                });
 | 
			
		||||
            expect(res.logs.length).to.equal(1);
 | 
			
		||||
            const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
 | 
			
		||||
                TestSignatureValidatorSignatureValidatorApprovalEventArgs
 | 
			
		||||
                ExchangeSignatureValidatorApprovalEventArgs
 | 
			
		||||
            >;
 | 
			
		||||
            const logArgs = log.args;
 | 
			
		||||
            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 () => {
 | 
			
		||||
            const approval = false;
 | 
			
		||||
            const res = await signatureValidator
 | 
			
		||||
            const res = await exchange
 | 
			
		||||
                .setSignatureValidatorApproval(validatorWallet.address, approval)
 | 
			
		||||
                .awaitTransactionSuccessAsync({
 | 
			
		||||
                    from: signerAddress,
 | 
			
		||||
                });
 | 
			
		||||
            expect(res.logs.length).to.equal(1);
 | 
			
		||||
            const log = signatureValidatorLogDecoder.decodeLogOrThrow(res.logs[0]) as LogWithDecodedArgs<
 | 
			
		||||
                TestSignatureValidatorSignatureValidatorApprovalEventArgs
 | 
			
		||||
                ExchangeSignatureValidatorApprovalEventArgs
 | 
			
		||||
            >;
 | 
			
		||||
            const logArgs = log.args;
 | 
			
		||||
            expect(logArgs.signerAddress).to.equal(signerAddress);
 | 
			
		||||
@@ -1136,6 +1136,153 @@ blockchainTests.resets('MixinSignatureValidator', env => {
 | 
			
		||||
            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:enable:no-unnecessary-type-assertion
 | 
			
		||||
 
 | 
			
		||||
@@ -14,14 +14,3 @@ export const constants = {
 | 
			
		||||
        ExchangeFunctionName.DetachProtocolFeeCollector,
 | 
			
		||||
    ],
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export enum ValidatorWalletAction {
 | 
			
		||||
    Reject = 0,
 | 
			
		||||
    Accept = 1,
 | 
			
		||||
    Revert = 2,
 | 
			
		||||
    UpdateState = 3,
 | 
			
		||||
    MatchSignatureHash = 4,
 | 
			
		||||
    ReturnTrue = 5,
 | 
			
		||||
    ReturnNothing = 6,
 | 
			
		||||
    NTypes = 7,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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_fees';
 | 
			
		||||
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_validator_wallet';
 | 
			
		||||
export * from '../test/generated-wrappers/test_wrapper_functions';
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@
 | 
			
		||||
        "test/generated-artifacts/TestProtocolFeeCollector.json",
 | 
			
		||||
        "test/generated-artifacts/TestProtocolFees.json",
 | 
			
		||||
        "test/generated-artifacts/TestProtocolFeesReceiver.json",
 | 
			
		||||
        "test/generated-artifacts/TestSignatureValidator.json",
 | 
			
		||||
        "test/generated-artifacts/TestTransactions.json",
 | 
			
		||||
        "test/generated-artifacts/TestValidatorWallet.json",
 | 
			
		||||
        "test/generated-artifacts/TestWrapperFunctions.json"
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,7 @@
 | 
			
		||||
        "chai-as-promised": "^7.1.0",
 | 
			
		||||
        "chai-bignumber": "^3.0.0",
 | 
			
		||||
        "dirty-chai": "^2.0.1",
 | 
			
		||||
        "js-combinatorics": "^0.5.3",
 | 
			
		||||
        "make-promises-safe": "^1.1.0",
 | 
			
		||||
        "mocha": "^6.2.0",
 | 
			
		||||
        "npm-run-all": "^4.1.2",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,2 @@
 | 
			
		||||
export * from './artifacts';
 | 
			
		||||
export * from './wrappers';
 | 
			
		||||
export * from './function_assertions';
 | 
			
		||||
 
 | 
			
		||||
@@ -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';
 | 
			
		||||
@@ -1,13 +1,11 @@
 | 
			
		||||
import { CoordinatorContract, CoordinatorRevertErrors, SignedCoordinatorApproval } from '@0x/contracts-coordinator';
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import {
 | 
			
		||||
    BlockchainBalanceStore,
 | 
			
		||||
    ExchangeCancelEventArgs,
 | 
			
		||||
    ExchangeCancelUpToEventArgs,
 | 
			
		||||
    exchangeDataEncoder,
 | 
			
		||||
    ExchangeEvents,
 | 
			
		||||
    ExchangeFillEventArgs,
 | 
			
		||||
    LocalBalanceStore,
 | 
			
		||||
} from '@0x/contracts-exchange';
 | 
			
		||||
import {
 | 
			
		||||
    blockchainTests,
 | 
			
		||||
@@ -25,8 +23,13 @@ import { SignedOrder, SignedZeroExTransaction } from '@0x/types';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { Actor } from '../framework/actors/base';
 | 
			
		||||
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';
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@ import { artifacts as exchangeArtifacts } from '@0x/contracts-exchange';
 | 
			
		||||
import { BlockchainTestsEnvironment } from '@0x/contracts-test-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`.
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ import { AssetProxyId } from '@0x/types';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
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
 | 
			
		||||
blockchainTests('Deployment and Configuration End to End Tests', env => {
 | 
			
		||||
@@ -18,6 +18,7 @@ import {
 | 
			
		||||
    DummyNoReturnERC20TokenContract,
 | 
			
		||||
} from '@0x/contracts-erc20';
 | 
			
		||||
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
 | 
			
		||||
import { artifacts, ExchangeCancelEventArgs, ExchangeContract, ExchangeRevertErrors } from '@0x/contracts-exchange';
 | 
			
		||||
import { LibMathRevertErrors } from '@0x/contracts-exchange-libs';
 | 
			
		||||
import {
 | 
			
		||||
    blockchainTests,
 | 
			
		||||
@@ -26,7 +27,6 @@ import {
 | 
			
		||||
    ERC20BalancesByOwner,
 | 
			
		||||
    expect,
 | 
			
		||||
    getLatestBlockTimestampAsync,
 | 
			
		||||
    hexConcat,
 | 
			
		||||
    increaseTimeAndMineBlockAsync,
 | 
			
		||||
    OrderFactory,
 | 
			
		||||
    orderHashUtils,
 | 
			
		||||
@@ -35,20 +35,13 @@ import {
 | 
			
		||||
    txDefaults,
 | 
			
		||||
    web3Wrapper,
 | 
			
		||||
} 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 { Web3Wrapper } from '@0x/web3-wrapper';
 | 
			
		||||
import { LogWithDecodedArgs } from 'ethereum-types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import ExchangeRevertErrors = require('../src/revert_errors');
 | 
			
		||||
 | 
			
		||||
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';
 | 
			
		||||
import { FillOrderWrapper } from './fill_order_wrapper';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:no-unnecessary-type-assertion
 | 
			
		||||
blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
@@ -69,14 +62,12 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
    let erc721Proxy: ERC721ProxyContract;
 | 
			
		||||
    let erc1155Proxy: ERC1155ProxyContract;
 | 
			
		||||
    let multiAssetProxy: MultiAssetProxyContract;
 | 
			
		||||
    let validatorWallet: TestValidatorWalletContract;
 | 
			
		||||
    let erc1155Contract: ERC1155MintableContract;
 | 
			
		||||
    let staticCallProxy: StaticCallProxyContract;
 | 
			
		||||
    let staticCallTarget: TestStaticCallTargetContract;
 | 
			
		||||
 | 
			
		||||
    let signedOrder: SignedOrder;
 | 
			
		||||
    let erc20Balances: ERC20BalancesByOwner;
 | 
			
		||||
    let exchangeWrapper: ExchangeWrapper;
 | 
			
		||||
    let erc20Wrapper: ERC20Wrapper;
 | 
			
		||||
    let erc721Wrapper: ERC721Wrapper;
 | 
			
		||||
    let erc1155Wrapper: Erc1155Wrapper;
 | 
			
		||||
@@ -147,13 +138,6 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            {},
 | 
			
		||||
            new BigNumber(chainId),
 | 
			
		||||
        );
 | 
			
		||||
        validatorWallet = await TestValidatorWalletContract.deployFrom0xArtifactAsync(
 | 
			
		||||
            artifacts.TestValidatorWallet,
 | 
			
		||||
            provider,
 | 
			
		||||
            txDefaults,
 | 
			
		||||
            {},
 | 
			
		||||
            exchange.address,
 | 
			
		||||
        );
 | 
			
		||||
        // Configure ERC20Proxy
 | 
			
		||||
        await erc20Proxy.addAuthorizedAddress(exchange.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 });
 | 
			
		||||
 | 
			
		||||
        // Configure Exchange
 | 
			
		||||
        exchangeWrapper = new ExchangeWrapper(exchange);
 | 
			
		||||
        await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, 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);
 | 
			
		||||
        for (const proxy of [erc20Proxy, erc721Proxy, erc1155Proxy, multiAssetProxy, staticCallProxy]) {
 | 
			
		||||
            await exchange.registerAssetProxy(proxy.address).awaitTransactionSuccessAsync({ from: owner });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Configure ERC20 tokens
 | 
			
		||||
        await erc20Wrapper.setBalancesAndAllowancesAsync();
 | 
			
		||||
@@ -252,115 +233,16 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            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 () => {
 | 
			
		||||
            signedOrder = await orderFactory.newSignedOrderAsync();
 | 
			
		||||
            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 tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
 | 
			
		||||
            const tx = exchange
 | 
			
		||||
                .fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -375,7 +257,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
            const orderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -386,9 +270,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            const fillTakerAssetAmount1 = new BigNumber(2);
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
 | 
			
		||||
                takerAssetFillAmount: fillTakerAssetAmount1,
 | 
			
		||||
            });
 | 
			
		||||
            await exchange
 | 
			
		||||
                .fillOrder(signedOrder, fillTakerAssetAmount1, signedOrder.signature)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
 | 
			
		||||
            const fillTakerAssetAmount2 = new BigNumber(1);
 | 
			
		||||
            const expectedError = new LibMathRevertErrors.RoundingError(
 | 
			
		||||
@@ -396,9 +280,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                new BigNumber(3),
 | 
			
		||||
                new BigNumber(1001),
 | 
			
		||||
            );
 | 
			
		||||
            const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
 | 
			
		||||
                takerAssetFillAmount: fillTakerAssetAmount2,
 | 
			
		||||
            });
 | 
			
		||||
            const tx = exchange
 | 
			
		||||
                .fillOrder(signedOrder, fillTakerAssetAmount2, signedOrder.signature)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -500,7 +384,7 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                orderHash,
 | 
			
		||||
                takerAddress,
 | 
			
		||||
            );
 | 
			
		||||
            const tx = exchangeWrapper.cancelOrderAsync(signedOrder, takerAddress);
 | 
			
		||||
            const tx = exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -508,7 +392,7 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            signedOrder = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -516,22 +400,22 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            signedOrder = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        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 expectedError = new ExchangeRevertErrors.OrderStatusError(orderHash, OrderStatus.Cancelled);
 | 
			
		||||
            const tx = exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, {
 | 
			
		||||
                takerAssetFillAmount: signedOrder.takerAssetAmount.div(2),
 | 
			
		||||
            });
 | 
			
		||||
            const tx = exchange
 | 
			
		||||
                .fillOrder(signedOrder, signedOrder.takerAssetAmount.div(2), signedOrder.signature)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        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);
 | 
			
		||||
 | 
			
		||||
            const log = res.logs[0] as LogWithDecodedArgs<ExchangeCancelEventArgs>;
 | 
			
		||||
@@ -546,8 +430,8 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should noop if already cancelled', async () => {
 | 
			
		||||
            await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
 | 
			
		||||
            const tx = await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
 | 
			
		||||
            await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            const tx = await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            expect(tx.logs.length).to.equal(0);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -556,7 +440,7 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            signedOrder = await orderFactory.newSignedOrderAsync({
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -564,33 +448,33 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
    describe('cancelOrdersUpTo', () => {
 | 
			
		||||
        it('should fail to set orderEpoch less than current orderEpoch', async () => {
 | 
			
		||||
            const orderEpoch = new BigNumber(1);
 | 
			
		||||
            await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
 | 
			
		||||
            await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            const lesserOrderEpoch = new BigNumber(0);
 | 
			
		||||
            const expectedError = new ExchangeRevertErrors.OrderEpochError(
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
                orderEpoch.plus(1),
 | 
			
		||||
            );
 | 
			
		||||
            const tx = exchangeWrapper.cancelOrdersUpToAsync(lesserOrderEpoch, makerAddress);
 | 
			
		||||
            const tx = exchange.cancelOrdersUpTo(lesserOrderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should fail to set orderEpoch equal to existing orderEpoch', async () => {
 | 
			
		||||
            const orderEpoch = new BigNumber(1);
 | 
			
		||||
            await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
 | 
			
		||||
            await exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            const expectedError = new ExchangeRevertErrors.OrderEpochError(
 | 
			
		||||
                makerAddress,
 | 
			
		||||
                constants.NULL_ADDRESS,
 | 
			
		||||
                orderEpoch.plus(1),
 | 
			
		||||
            );
 | 
			
		||||
            const tx = exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
 | 
			
		||||
            const tx = exchange.cancelOrdersUpTo(orderEpoch).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            return expect(tx).to.revertWith(expectedError);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        it('should cancel only orders with a orderEpoch less than existing orderEpoch', async () => {
 | 
			
		||||
            // Cancel all transactions with a orderEpoch less than 2
 | 
			
		||||
            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
 | 
			
		||||
            // 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),
 | 
			
		||||
                }),
 | 
			
		||||
            ];
 | 
			
		||||
            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 fillMakerAssetAmount = signedOrders[2].makerAssetAmount.plus(signedOrders[3].makerAssetAmount);
 | 
			
		||||
            const fillTakerAssetAmount = signedOrders[2].takerAssetAmount.plus(signedOrders[3].takerAssetAmount);
 | 
			
		||||
@@ -672,7 +561,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                signedOrder.makerAssetData,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -699,7 +590,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                signedOrder.takerAssetData,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -726,7 +619,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                signedOrder.makerAssetData,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -753,7 +648,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                signedOrder.takerAssetData,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -773,7 +670,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                signedOrder.takerAssetAmount,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
@@ -1102,7 +1001,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                assetData,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
        it('should fill the order if the staticcall is successful', async () => {
 | 
			
		||||
@@ -1133,7 +1034,9 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
                assetData,
 | 
			
		||||
                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);
 | 
			
		||||
        });
 | 
			
		||||
        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();
 | 
			
		||||
        });
 | 
			
		||||
        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 expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Fillable;
 | 
			
		||||
@@ -1175,8 +1078,8 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress, { takerAssetFillAmount });
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for a cancelled and unfilled order', async () => {
 | 
			
		||||
            await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
 | 
			
		||||
            const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
 | 
			
		||||
            await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
 | 
			
		||||
            const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
			
		||||
            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 () => {
 | 
			
		||||
            const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2);
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress, { takerAssetFillAmount });
 | 
			
		||||
            await exchangeWrapper.cancelOrderAsync(signedOrder, makerAddress);
 | 
			
		||||
            const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
 | 
			
		||||
            await exchange
 | 
			
		||||
                .fillOrder(signedOrder, takerAssetFillAmount, signedOrder.signature)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
            await exchange.cancelOrder(signedOrder).awaitTransactionSuccessAsync({ from: makerAddress });
 | 
			
		||||
            const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
 | 
			
		||||
            const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const expectedTakerAssetFilledAmount = takerAssetFillAmount;
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Cancelled;
 | 
			
		||||
@@ -1200,7 +1105,7 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
			
		||||
            const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
 | 
			
		||||
            await increaseTimeAndMineBlockAsync(timeUntilExpiration);
 | 
			
		||||
            const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
 | 
			
		||||
            const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
 | 
			
		||||
            const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
			
		||||
            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 () => {
 | 
			
		||||
            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 timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
 | 
			
		||||
            await increaseTimeAndMineBlockAsync(timeUntilExpiration);
 | 
			
		||||
            const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
 | 
			
		||||
            const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
 | 
			
		||||
            const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const expectedTakerAssetFilledAmount = takerAssetFillAmount;
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.Expired;
 | 
			
		||||
@@ -1223,11 +1130,13 @@ blockchainTests.resets('Exchange core', () => {
 | 
			
		||||
            expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
			
		||||
        });
 | 
			
		||||
        it('should return the correct orderInfo for an expired and fully filled order', async () => {
 | 
			
		||||
            await exchangeWrapper.fillOrderAsync(signedOrder, takerAddress);
 | 
			
		||||
            await exchange
 | 
			
		||||
                .fillOrder(signedOrder, signedOrder.takerAssetAmount, signedOrder.signature)
 | 
			
		||||
                .awaitTransactionSuccessAsync({ from: takerAddress });
 | 
			
		||||
            const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
			
		||||
            const timeUntilExpiration = signedOrder.expirationTimeSeconds.minus(currentTimestamp).toNumber();
 | 
			
		||||
            await increaseTimeAndMineBlockAsync(timeUntilExpiration);
 | 
			
		||||
            const orderInfo = await exchangeWrapper.getOrderInfoAsync(signedOrder);
 | 
			
		||||
            const orderInfo = await exchange.getOrderInfo(signedOrder).callAsync();
 | 
			
		||||
            const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
			
		||||
            const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
 | 
			
		||||
            // 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 () => {
 | 
			
		||||
            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 expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
			
		||||
            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 () => {
 | 
			
		||||
            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 expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
			
		||||
            const expectedOrderStatus = OrderStatus.InvalidTakerAssetAmount;
 | 
			
		||||
@@ -1,12 +1,6 @@
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
 | 
			
		||||
import {
 | 
			
		||||
    BlockchainBalanceStore,
 | 
			
		||||
    ExchangeRevertErrors,
 | 
			
		||||
    IExchangeEvents,
 | 
			
		||||
    IExchangeFillEventArgs,
 | 
			
		||||
    LocalBalanceStore,
 | 
			
		||||
} from '@0x/contracts-exchange';
 | 
			
		||||
import { ExchangeRevertErrors, IExchangeEvents, IExchangeFillEventArgs } from '@0x/contracts-exchange';
 | 
			
		||||
import { ReferenceFunctions } from '@0x/contracts-exchange-libs';
 | 
			
		||||
import {
 | 
			
		||||
    blockchainTests,
 | 
			
		||||
@@ -25,9 +19,11 @@ import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { Actor } from '../actors/base';
 | 
			
		||||
import { Maker } from '../actors/maker';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { Actor } from '../framework/actors/base';
 | 
			
		||||
import { Maker } from '../framework/actors/maker';
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import { ExchangeContract } from '@0x/contracts-exchange';
 | 
			
		||||
import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs';
 | 
			
		||||
import {
 | 
			
		||||
    constants,
 | 
			
		||||
@@ -14,12 +15,10 @@ import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { ExchangeContract } from '../wrappers';
 | 
			
		||||
 | 
			
		||||
import { BalanceStore } from '../../src/balance_stores/balance_store';
 | 
			
		||||
import { BlockchainBalanceStore } from '../../src/balance_stores/blockchain_balance_store';
 | 
			
		||||
import { LocalBalanceStore } from '../../src/balance_stores/local_balance_store';
 | 
			
		||||
import { TokenContractsByName, TokenIds, TokenOwnersByName } from '../../src/balance_stores/types';
 | 
			
		||||
import { BalanceStore } from '../framework/balances/balance_store';
 | 
			
		||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
 | 
			
		||||
import { LocalBalanceStore } from '../framework/balances/local_balance_store';
 | 
			
		||||
import { TokenContractsByName, TokenIds, TokenOwnersByName } from '../framework/balances/types';
 | 
			
		||||
 | 
			
		||||
export class FillOrderWrapper {
 | 
			
		||||
    private readonly _blockchainBalanceStore: BlockchainBalanceStore;
 | 
			
		||||
@@ -1,11 +1,6 @@
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import { ERC20TokenEvents, ERC20TokenTransferEventArgs } from '@0x/contracts-erc20';
 | 
			
		||||
import {
 | 
			
		||||
    BlockchainBalanceStore,
 | 
			
		||||
    ExchangeEvents,
 | 
			
		||||
    ExchangeFillEventArgs,
 | 
			
		||||
    LocalBalanceStore,
 | 
			
		||||
} from '@0x/contracts-exchange';
 | 
			
		||||
import { ExchangeEvents, ExchangeFillEventArgs } from '@0x/contracts-exchange';
 | 
			
		||||
import { ReferenceFunctions } from '@0x/contracts-exchange-libs';
 | 
			
		||||
import {
 | 
			
		||||
    constants as stakingConstants,
 | 
			
		||||
@@ -28,8 +23,14 @@ import { SignedOrder } from '@0x/types';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
import { actorAddressesByName, FeeRecipient, Maker, OperatorStakerMaker, StakerKeeper, Taker } from '../actors';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
 | 
			
		||||
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);
 | 
			
		||||
blockchainTests.resets('fillOrder integration tests', env => {
 | 
			
		||||
@@ -3,7 +3,7 @@ import { artifacts, ForwarderContract } from '@0x/contracts-exchange-forwarder';
 | 
			
		||||
import { BlockchainTestsEnvironment } from '@0x/contracts-test-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`.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,7 @@
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import { DummyERC20TokenContract } from '@0x/contracts-erc20';
 | 
			
		||||
import { DummyERC721TokenContract } from '@0x/contracts-erc721';
 | 
			
		||||
import {
 | 
			
		||||
    artifacts as exchangeArtifacts,
 | 
			
		||||
    BlockchainBalanceStore,
 | 
			
		||||
    ExchangeContract,
 | 
			
		||||
    LocalBalanceStore,
 | 
			
		||||
} from '@0x/contracts-exchange';
 | 
			
		||||
import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange';
 | 
			
		||||
import { artifacts, ForwarderContract, ForwarderRevertErrors } from '@0x/contracts-exchange-forwarder';
 | 
			
		||||
import {
 | 
			
		||||
    blockchainTests,
 | 
			
		||||
@@ -19,8 +14,13 @@ import {
 | 
			
		||||
} from '@0x/contracts-test-utils';
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
 | 
			
		||||
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 { ForwarderTestFactory } from './forwarder_test_factory';
 | 
			
		||||
@@ -42,7 +42,7 @@ blockchainTests('Forwarder integration tests', env => {
 | 
			
		||||
    let makerAssetData: string;
 | 
			
		||||
 | 
			
		||||
    let maker: Maker;
 | 
			
		||||
    let taker: Actor;
 | 
			
		||||
    let taker: Taker;
 | 
			
		||||
    let orderFeeRecipient: FeeRecipient;
 | 
			
		||||
    let forwarderFeeRecipient: FeeRecipient;
 | 
			
		||||
 | 
			
		||||
@@ -59,7 +59,7 @@ blockchainTests('Forwarder integration tests', env => {
 | 
			
		||||
        wethAssetData = await devUtils.encodeERC20AssetData(deployment.tokens.weth.address).callAsync();
 | 
			
		||||
        makerAssetData = await devUtils.encodeERC20AssetData(makerToken.address).callAsync();
 | 
			
		||||
 | 
			
		||||
        taker = new Actor({ name: 'Taker', deployment });
 | 
			
		||||
        taker = new Taker({ name: 'Taker', deployment });
 | 
			
		||||
        orderFeeRecipient = new FeeRecipient({
 | 
			
		||||
            name: 'Order fee recipient',
 | 
			
		||||
            deployment,
 | 
			
		||||
@@ -560,14 +560,24 @@ blockchainTests('Forwarder integration tests', env => {
 | 
			
		||||
 | 
			
		||||
            // Compute expected balances
 | 
			
		||||
            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(
 | 
			
		||||
                taker.address,
 | 
			
		||||
                deployment.tokens.weth.address,
 | 
			
		||||
                takerAssetFillAmount.plus(DeploymentManager.protocolFee),
 | 
			
		||||
            );
 | 
			
		||||
            expectedBalances.transferAssetAsync(taker.address, maker.address, takerAssetFillAmount, wethAssetData);
 | 
			
		||||
            expectedBalances.transferAssetAsync(
 | 
			
		||||
            await expectedBalances.transferAssetAsync(
 | 
			
		||||
                taker.address,
 | 
			
		||||
                maker.address,
 | 
			
		||||
                takerAssetFillAmount,
 | 
			
		||||
                wethAssetData,
 | 
			
		||||
            );
 | 
			
		||||
            await expectedBalances.transferAssetAsync(
 | 
			
		||||
                taker.address,
 | 
			
		||||
                deployment.staking.stakingProxy.address,
 | 
			
		||||
                DeploymentManager.protocolFee,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,16 @@
 | 
			
		||||
import { DevUtilsContract } from '@0x/contracts-dev-utils';
 | 
			
		||||
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
 | 
			
		||||
import { ForwarderContract } from '@0x/contracts-exchange-forwarder';
 | 
			
		||||
import { constants, expect, getPercentageOfValue, OrderStatus } from '@0x/contracts-test-utils';
 | 
			
		||||
import { OrderInfo, SignedOrder } from '@0x/types';
 | 
			
		||||
import { BigNumber, RevertError } from '@0x/utils';
 | 
			
		||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
import { Actor, FeeRecipient, Maker } from '../actors';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { FeeRecipient } from '../framework/actors/fee_recipient';
 | 
			
		||||
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
 | 
			
		||||
interface ForwarderFillState {
 | 
			
		||||
@@ -31,7 +34,7 @@ export class ForwarderTestFactory {
 | 
			
		||||
        private readonly _deployment: DeploymentManager,
 | 
			
		||||
        private readonly _balanceStore: BlockchainBalanceStore,
 | 
			
		||||
        private readonly _maker: Maker,
 | 
			
		||||
        private readonly _taker: Actor,
 | 
			
		||||
        private readonly _taker: Taker,
 | 
			
		||||
        private readonly _orderFeeRecipient: FeeRecipient,
 | 
			
		||||
        private readonly _forwarderFeeRecipient: FeeRecipient,
 | 
			
		||||
        private readonly _devUtils: DevUtilsContract,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,9 @@ import { SignatureType, SignedZeroExTransaction, ZeroExTransaction } from '@0x/t
 | 
			
		||||
import { BigNumber } from '@0x/utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssertionResult } from '../../src/function_assertions';
 | 
			
		||||
import { AssertionResult } from '../assertions/function_assertion';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { SimulationEnvironment } from '../simulation/simulation';
 | 
			
		||||
import { SimulationEnvironment } from '../simulation';
 | 
			
		||||
 | 
			
		||||
export type Constructor<T = {}> = new (...args: any[]) => T;
 | 
			
		||||
 | 
			
		||||
@@ -4,11 +4,9 @@ import '@azure/core-asynciterator-polyfill';
 | 
			
		||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssertionResult } from '../../src/function_assertions';
 | 
			
		||||
import {
 | 
			
		||||
    validCreateStakingPoolAssertion,
 | 
			
		||||
    validDecreaseStakingPoolOperatorShareAssertion,
 | 
			
		||||
} from '../function-assertions';
 | 
			
		||||
import { validCreateStakingPoolAssertion } from '../assertions/createStakingPool';
 | 
			
		||||
import { validDecreaseStakingPoolOperatorShareAssertion } from '../assertions/decreaseStakingPoolOperatorShare';
 | 
			
		||||
import { AssertionResult } from '../assertions/function_assertion';
 | 
			
		||||
 | 
			
		||||
import { Actor, Constructor } from './base';
 | 
			
		||||
 | 
			
		||||
@@ -4,8 +4,10 @@ import { BigNumber } from '@0x/utils';
 | 
			
		||||
import '@azure/core-asynciterator-polyfill';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssertionResult } from '../../src/function_assertions';
 | 
			
		||||
import { validMoveStakeAssertion, validStakeAssertion, validUnstakeAssertion } from '../function-assertions';
 | 
			
		||||
import { AssertionResult } from '../assertions/function_assertion';
 | 
			
		||||
import { validMoveStakeAssertion } from '../assertions/moveStake';
 | 
			
		||||
import { validStakeAssertion } from '../assertions/stake';
 | 
			
		||||
import { validUnstakeAssertion } from '../assertions/unstake';
 | 
			
		||||
 | 
			
		||||
import { Actor, Constructor } from './base';
 | 
			
		||||
 | 
			
		||||
@@ -3,9 +3,10 @@ import { expect } from '@0x/contracts-test-utils';
 | 
			
		||||
import { BigNumber, logUtils } from '@0x/utils';
 | 
			
		||||
import { TxData } from 'ethereum-types';
 | 
			
		||||
 | 
			
		||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
 | 
			
		||||
import { FunctionAssertion, FunctionResult } from './function_assertion';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:no-unnecessary-type-assertion
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -2,9 +2,10 @@ import { StakingPoolById } from '@0x/contracts-staking';
 | 
			
		||||
import { expect } from '@0x/contracts-test-utils';
 | 
			
		||||
import { logUtils } from '@0x/utils';
 | 
			
		||||
 | 
			
		||||
import { FunctionAssertion, FunctionResult } from '../../src/function_assertions';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
 | 
			
		||||
import { FunctionAssertion, FunctionResult } from './function_assertion';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a FunctionAssertion for `decreaseStakingPoolOperatorShare` which assumes valid input is
 | 
			
		||||
 * provided. The FunctionAssertion checks that the operator share actually gets updated.
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
@@ -11,9 +11,10 @@ import { BigNumber, logUtils } from '@0x/utils';
 | 
			
		||||
import { TxData } from 'ethereum-types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { FunctionAssertion } from '../../src/function_assertions';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
 | 
			
		||||
import { FunctionAssertion } from './function_assertion';
 | 
			
		||||
 | 
			
		||||
function incrementNextEpochBalance(stakeBalance: StoredBalance, amount: BigNumber): void {
 | 
			
		||||
    _.update(stakeBalance, ['nextEpochBalance'], balance => (balance || constants.ZERO_AMOUNT).plus(amount));
 | 
			
		||||
}
 | 
			
		||||
@@ -1,12 +1,14 @@
 | 
			
		||||
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
 | 
			
		||||
import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking';
 | 
			
		||||
import { expect } from '@0x/contracts-test-utils';
 | 
			
		||||
import { BigNumber, logUtils } from '@0x/utils';
 | 
			
		||||
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 { FunctionAssertion, FunctionResult } from './function_assertion';
 | 
			
		||||
 | 
			
		||||
function expectedUndelegatedStake(
 | 
			
		||||
    initStake: OwnerStakeByStatus | GlobalStakeByStatus,
 | 
			
		||||
    amount: BigNumber,
 | 
			
		||||
@@ -1,12 +1,14 @@
 | 
			
		||||
import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange';
 | 
			
		||||
import { GlobalStakeByStatus, OwnerStakeByStatus, StakeStatus, StoredBalance } from '@0x/contracts-staking';
 | 
			
		||||
import { expect } from '@0x/contracts-test-utils';
 | 
			
		||||
import { BigNumber, logUtils } from '@0x/utils';
 | 
			
		||||
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 { FunctionAssertion, FunctionResult } from './function_assertion';
 | 
			
		||||
 | 
			
		||||
function expectedUndelegatedStake(
 | 
			
		||||
    initStake: OwnerStakeByStatus | GlobalStakeByStatus,
 | 
			
		||||
    amount: BigNumber,
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
 | 
			
		||||
import { GlobalStakeByStatus, StakeStatus, StakingPoolById, StoredBalance } from '@0x/contracts-staking';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssertionResult } from '../../src/function_assertions';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { AssertionResult } from './assertions/function_assertion';
 | 
			
		||||
import { BlockchainBalanceStore } from './balances/blockchain_balance_store';
 | 
			
		||||
import { DeploymentManager } from './deployment_manager';
 | 
			
		||||
 | 
			
		||||
// tslint:disable:max-classes-per-file
 | 
			
		||||
 | 
			
		||||
@@ -2,10 +2,9 @@ import { blockchainTests, constants, expect, filterLogsToArguments, getRandomInt
 | 
			
		||||
import { BigNumber, StringRevertError } from '@0x/utils';
 | 
			
		||||
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 { TestFrameworkContract, TestFrameworkEventEventArgs, TestFrameworkEvents } from '../../wrappers';
 | 
			
		||||
import { FunctionAssertion, FunctionResult } from '../assertions/function_assertion';
 | 
			
		||||
 | 
			
		||||
const { ZERO_AMOUNT, MAX_UINT256 } = constants;
 | 
			
		||||
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
export * from './stake';
 | 
			
		||||
export * from './unstake';
 | 
			
		||||
export * from './createStakingPool';
 | 
			
		||||
export * from './decreaseStakingPoolOperatorShare';
 | 
			
		||||
export * from './moveStake';
 | 
			
		||||
@@ -1,12 +1,11 @@
 | 
			
		||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
 | 
			
		||||
import { blockchainTests } from '@0x/contracts-test-utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssertionResult } from '../../src/function_assertions';
 | 
			
		||||
import { PoolOperator } from '../actors';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
 | 
			
		||||
import { Simulation, SimulationEnvironment } from './simulation';
 | 
			
		||||
import { PoolOperator } from '../framework/actors/pool_operator';
 | 
			
		||||
import { AssertionResult } from '../framework/assertions/function_assertion';
 | 
			
		||||
import { BlockchainBalanceStore } from '../framework/balances/blockchain_balance_store';
 | 
			
		||||
import { DeploymentManager } from '../framework/deployment_manager';
 | 
			
		||||
import { Simulation, SimulationEnvironment } from '../framework/simulation';
 | 
			
		||||
 | 
			
		||||
export class PoolManagementSimulation extends Simulation {
 | 
			
		||||
    protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {
 | 
			
		||||
@@ -1,13 +1,13 @@
 | 
			
		||||
import { BlockchainBalanceStore } from '@0x/contracts-exchange';
 | 
			
		||||
import { blockchainTests } from '@0x/contracts-test-utils';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import { AssertionResult } from '../../src/function_assertions';
 | 
			
		||||
import { Staker } from '../actors';
 | 
			
		||||
import { DeploymentManager } from '../deployment_manager';
 | 
			
		||||
import { Staker } from '../framework/actors/staker';
 | 
			
		||||
import { AssertionResult } from '../framework/assertions/function_assertion';
 | 
			
		||||
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 { Simulation, SimulationEnvironment } from './simulation';
 | 
			
		||||
 | 
			
		||||
export class StakeManagementSimulation extends Simulation {
 | 
			
		||||
    protected async *_assertionGenerator(): AsyncIterableIterator<AssertionResult | void> {
 | 
			
		||||
@@ -57,6 +57,7 @@ export {
 | 
			
		||||
    TokenBalances,
 | 
			
		||||
    TransactionDataParams,
 | 
			
		||||
    ExchangeFunctionName,
 | 
			
		||||
    ValidatorWalletAction,
 | 
			
		||||
} from './types';
 | 
			
		||||
export { blockchainTests, BlockchainTestsEnvironment, describe } from './mocha_blockchain';
 | 
			
		||||
export { chaiSetup, expect } from './chai_setup';
 | 
			
		||||
 
 | 
			
		||||
@@ -201,3 +201,14 @@ export enum ExchangeFunctionName {
 | 
			
		||||
    SetProtocolFeeCollectorAddress = 'setProtocolFeeCollectorAddress',
 | 
			
		||||
    DetachProtocolFeeCollector = 'detachProtocolFeeCollector',
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum ValidatorWalletAction {
 | 
			
		||||
    Reject = 0,
 | 
			
		||||
    Accept = 1,
 | 
			
		||||
    Revert = 2,
 | 
			
		||||
    UpdateState = 3,
 | 
			
		||||
    MatchSignatureHash = 4,
 | 
			
		||||
    ReturnTrue = 5,
 | 
			
		||||
    ReturnNothing = 6,
 | 
			
		||||
    NTypes = 7,
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user