Wrappers for balance threshold filter + updated some tests to use the wrapper
This commit is contained in:
		@@ -6,6 +6,7 @@ import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
				
			|||||||
import * as chai from 'chai';
 | 
					import * as chai from 'chai';
 | 
				
			||||||
import * as ethUtil from 'ethereumjs-util';
 | 
					import * as ethUtil from 'ethereumjs-util';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { DummyERC20TokenContract } from '../../generated-wrappers/dummy_erc20_token';
 | 
					import { DummyERC20TokenContract } from '../../generated-wrappers/dummy_erc20_token';
 | 
				
			||||||
import { ExchangeContract } from '../../generated-wrappers/exchange';
 | 
					import { ExchangeContract } from '../../generated-wrappers/exchange';
 | 
				
			||||||
@@ -24,6 +25,7 @@ import { ExchangeWrapper } from '../utils/exchange_wrapper';
 | 
				
			|||||||
import { OrderFactory } from '../utils/order_factory';
 | 
					import { OrderFactory } from '../utils/order_factory';
 | 
				
			||||||
import { orderUtils } from '../utils/order_utils';
 | 
					import { orderUtils } from '../utils/order_utils';
 | 
				
			||||||
import { TransactionFactory } from '../utils/transaction_factory';
 | 
					import { TransactionFactory } from '../utils/transaction_factory';
 | 
				
			||||||
 | 
					import { BalanceThresholdWrapper } from '../utils/balance_threshold_wrapper';
 | 
				
			||||||
import { ContractName, ERC20BalancesByOwner, SignedTransaction } from '../utils/types';
 | 
					import { ContractName, ERC20BalancesByOwner, SignedTransaction } from '../utils/types';
 | 
				
			||||||
import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
 | 
					import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,6 +39,10 @@ const expect = chai.expect;
 | 
				
			|||||||
const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
					const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
				
			||||||
const DECIMALS_DEFAULT = 18;
 | 
					const DECIMALS_DEFAULT = 18;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface ValidatedAddressesLog {
 | 
				
			||||||
 | 
					    args: {addresses: string[]}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
					describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
				
			||||||
    let compliantMakerAddress: string;
 | 
					    let compliantMakerAddress: string;
 | 
				
			||||||
    let owner: string;
 | 
					    let owner: string;
 | 
				
			||||||
@@ -53,18 +59,35 @@ describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
				
			|||||||
    let orderFactory: OrderFactory;
 | 
					    let orderFactory: OrderFactory;
 | 
				
			||||||
    let erc20Wrapper: ERC20Wrapper;
 | 
					    let erc20Wrapper: ERC20Wrapper;
 | 
				
			||||||
    let erc20Balances: ERC20BalancesByOwner;
 | 
					    let erc20Balances: ERC20BalancesByOwner;
 | 
				
			||||||
 | 
					    let balanceThresholdWrapper: BalanceThresholdWrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let takerTransactionFactory: TransactionFactory;
 | 
					    let takerTransactionFactory: TransactionFactory;
 | 
				
			||||||
    let compliantSignedOrder: SignedOrder;
 | 
					    let compliantSignedOrder: SignedOrder;
 | 
				
			||||||
    let compliantSignedFillOrderTx: SignedTransaction;
 | 
					    let compliantSignedFillOrderTx: SignedTransaction;
 | 
				
			||||||
    let noncompliantSignedFillOrderTx: SignedTransaction;
 | 
					    let noncompliantSignedFillOrderTx: SignedTransaction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let logDecoder: LogDecoder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const takerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(500), DECIMALS_DEFAULT);
 | 
					    const takerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(500), DECIMALS_DEFAULT);
 | 
				
			||||||
    const makerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), DECIMALS_DEFAULT);
 | 
					    const makerAssetAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), DECIMALS_DEFAULT);
 | 
				
			||||||
    const takerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(250), DECIMALS_DEFAULT);
 | 
					    const takerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(250), DECIMALS_DEFAULT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let compliantForwarderInstance: BalanceThresholdFilterContract;
 | 
					    let compliantForwarderInstance: BalanceThresholdFilterContract;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const assertValidatedAddressesLog = async (txReceipt: TransactionReceiptWithDecodedLogs, expectedValidatedAddresses: string[]) => {
 | 
				
			||||||
 | 
					        expect(txReceipt.logs.length).to.be.gte(1);
 | 
				
			||||||
 | 
					        const validatedAddressesLog = (txReceipt.logs[0] as any) as ValidatedAddressesLog;
 | 
				
			||||||
 | 
					        const validatedAddresses = validatedAddressesLog.args.addresses;
 | 
				
			||||||
 | 
					        // @HACK-hysz: Nested addresses are not translated to lower-case but this will change once
 | 
				
			||||||
 | 
					        //             the new ABI Encoder/Decoder is used by the contract templates.
 | 
				
			||||||
 | 
					        let validatedAddressesNormalized: string[] = [];
 | 
				
			||||||
 | 
					        _.each(validatedAddresses, (address) => {
 | 
				
			||||||
 | 
					            const normalizedAddress = _.toLower(address);
 | 
				
			||||||
 | 
					            validatedAddressesNormalized.push(normalizedAddress);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        expect(validatedAddressesNormalized).to.be.deep.equal(expectedValidatedAddresses);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        // Create accounts
 | 
					        // Create accounts
 | 
				
			||||||
        await blockchainLifecycle.startAsync();
 | 
					        await blockchainLifecycle.startAsync();
 | 
				
			||||||
@@ -190,17 +213,30 @@ describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
				
			|||||||
            compliantSignedOrderWithoutExchangeAddressData,
 | 
					            compliantSignedOrderWithoutExchangeAddressData,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* generate selectors for every exchange method
 | 
					        /*
 | 
				
			||||||
        _.each(exchangeInstance.abi, (abiDefinition: AbiDefinition) => {
 | 
					        _.each(exchangeInstance.abi, (abiDefinition: AbiDefinition) => {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                const method = new Method(abiDefinition as MethodAbi);
 | 
					                const method = new Method(abiDefinition as MethodAbi);
 | 
				
			||||||
                console.log('\n', `// ${method.getDataItem().name}`);
 | 
					                console.log(method.getSignature());
 | 
				
			||||||
                console.log(`bytes4 constant ${method.getDataItem().name}Selector = ${method.getSelector()};`);
 | 
					                if (!method.getSignature().startsWith('matchOrders')) {
 | 
				
			||||||
                console.log(`bytes4 constant ${method.getDataItem().name}SelectorGenerator = byes4(keccak256('${method.getSignature()}'));`);
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                console.log(`FOUND IT`);
 | 
				
			||||||
 | 
					                const signedOrderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(
 | 
				
			||||||
 | 
					                    compliantSignedOrder,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const args = [signedOrderWithoutExchangeAddress, signedOrderWithoutExchangeAddress, compliantSignedOrder.signature, compliantSignedOrder.signature];
 | 
				
			||||||
 | 
					                console.log(method.encode(args, {annotate: true}));
 | 
				
			||||||
 | 
					                //console.log('\n', `// ${method.getDataItem().name}`);
 | 
				
			||||||
 | 
					                //console.log(`bytes4 constant ${method.getDataItem().name}Selector = ${method.getSelector()};`);
 | 
				
			||||||
 | 
					                //console.log(`bytes4 constant ${method.getDataItem().name}SelectorGenerator = byes4(keccak256('${method.getSignature()}'));`);
 | 
				
			||||||
            } catch(e) {
 | 
					            } catch(e) {
 | 
				
			||||||
                _.noop();
 | 
					                console.log(`encoding failed: ${e}`);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });*/
 | 
					        });
 | 
				
			||||||
 | 
					        throw new Error(`w`);*/
 | 
				
			||||||
 | 
					        logDecoder = new LogDecoder(web3Wrapper);
 | 
				
			||||||
 | 
					        balanceThresholdWrapper = new BalanceThresholdWrapper(compliantForwarderInstance, exchangeInstance, new TransactionFactory(takerPrivateKey, exchangeInstance.address), provider);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    beforeEach(async () => {
 | 
					    beforeEach(async () => {
 | 
				
			||||||
        await blockchainLifecycle.startAsync();
 | 
					        await blockchainLifecycle.startAsync();
 | 
				
			||||||
@@ -208,54 +244,9 @@ describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
				
			|||||||
    afterEach(async () => {
 | 
					    afterEach(async () => {
 | 
				
			||||||
        await blockchainLifecycle.revertAsync();
 | 
					        await blockchainLifecycle.revertAsync();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    describe.only('fillOrder', () => {
 | 
					
 | 
				
			||||||
        beforeEach(async () => {
 | 
					    describe('General Sanity Checks', () => {
 | 
				
			||||||
            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
					        it('should revert if the signed transaction is not intended for supported', async () => {
 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('should transfer the correct amounts when maker and taker are compliant', async () => {
 | 
					 | 
				
			||||||
            const txHash = await compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.salt,
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.signerAddress,
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.data,
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.signature,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const decoder = new LogDecoder(web3Wrapper);
 | 
					 | 
				
			||||||
            const tx = await decoder.getTxWithDecodedLogsAsync(txHash);
 | 
					 | 
				
			||||||
            console.log(JSON.stringify(tx, null, 4));
 | 
					 | 
				
			||||||
            console.log('****** MAKER ADDRESS = ', compliantSignedOrder.makerAddress);
 | 
					 | 
				
			||||||
            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
					 | 
				
			||||||
            const makerAssetFillAmount = takerAssetFillAmount
 | 
					 | 
				
			||||||
                .times(compliantSignedOrder.makerAssetAmount)
 | 
					 | 
				
			||||||
                .dividedToIntegerBy(compliantSignedOrder.takerAssetAmount);
 | 
					 | 
				
			||||||
            const makerFeePaid = compliantSignedOrder.makerFee
 | 
					 | 
				
			||||||
                .times(makerAssetFillAmount)
 | 
					 | 
				
			||||||
                .dividedToIntegerBy(compliantSignedOrder.makerAssetAmount);
 | 
					 | 
				
			||||||
            const takerFeePaid = compliantSignedOrder.takerFee
 | 
					 | 
				
			||||||
                .times(makerAssetFillAmount)
 | 
					 | 
				
			||||||
                .dividedToIntegerBy(compliantSignedOrder.makerAssetAmount);
 | 
					 | 
				
			||||||
            expect(newBalances[compliantMakerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[compliantMakerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(newBalances[compliantMakerAddress][defaultTakerAssetAddress]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[compliantMakerAddress][defaultTakerAssetAddress].add(takerAssetFillAmount),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(newBalances[compliantMakerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[compliantMakerAddress][zrxToken.address].minus(makerFeePaid),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(newBalances[compliantTakerAddress][defaultTakerAssetAddress]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[compliantTakerAddress][defaultTakerAssetAddress].minus(takerAssetFillAmount),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(newBalances[compliantTakerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[compliantTakerAddress][defaultMakerAssetAddress].add(makerAssetFillAmount),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(newBalances[compliantTakerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[compliantTakerAddress][zrxToken.address].minus(takerFeePaid),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                erc20Balances[feeRecipientAddress][zrxToken.address].add(makerFeePaid.add(takerFeePaid)),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        it('should revert if the signed transaction is not intended for fillOrder', async () => {
 | 
					 | 
				
			||||||
            // Create signed order without the fillOrder function selector
 | 
					            // Create signed order without the fillOrder function selector
 | 
				
			||||||
            const txDataBuf = ethUtil.toBuffer(compliantSignedFillOrderTx.data);
 | 
					            const txDataBuf = ethUtil.toBuffer(compliantSignedFillOrderTx.data);
 | 
				
			||||||
            const selectorLengthInBytes = 4;
 | 
					            const selectorLengthInBytes = 4;
 | 
				
			||||||
@@ -297,18 +288,90 @@ describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
				
			|||||||
                signedFillOrderTx.signature,
 | 
					                signedFillOrderTx.signature,
 | 
				
			||||||
            ));
 | 
					            ));
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        it('should revert if taker address is not compliant (does not hold a Yes Token)', async () => {
 | 
					        // @TODO - greater than 1 balance
 | 
				
			||||||
            return expectTransactionFailedAsync(
 | 
					    });
 | 
				
			||||||
                compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
					
 | 
				
			||||||
                    compliantSignedFillOrderTx.salt,
 | 
					
 | 
				
			||||||
                    nonCompliantAddress,
 | 
					
 | 
				
			||||||
                    compliantSignedFillOrderTx.data,
 | 
					    describe('batchFillOrders', () => {
 | 
				
			||||||
                    compliantSignedFillOrderTx.signature,
 | 
					        beforeEach(async () => {
 | 
				
			||||||
                ),
 | 
					            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
				
			||||||
                RevertReason.AtLeastOneAddressDoesNotMeetBalanceThreshold
 | 
					        });
 | 
				
			||||||
 | 
					        it('should transfer the correct amounts when maker and taker are compliant', async () => {
 | 
				
			||||||
 | 
					            let order2 = _.cloneDeep(compliantSignedOrder);
 | 
				
			||||||
 | 
					            order2.makerAddress = `0x${_.reverse(compliantSignedOrder.makerAddress.slice(2).split('')).join('')}`;
 | 
				
			||||||
 | 
					            const orders = [compliantSignedOrder, order2];
 | 
				
			||||||
 | 
					            const fillAmounts = [new BigNumber(4), new BigNumber(4)];
 | 
				
			||||||
 | 
					            const signatures = ["0xabcd", "0xabcd"];
 | 
				
			||||||
 | 
					            const exchangeCalldata = exchangeInstance.batchFillOrders.getABIEncodedTransactionData(orders, fillAmounts, signatures);
 | 
				
			||||||
 | 
					            console.log('*'.repeat(40), exchangeCalldata, '*'.repeat(40));
 | 
				
			||||||
 | 
					            console.log('****** MAKER ADDRESS = ', compliantSignedOrder.makerAddress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const txHash = await compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
				
			||||||
 | 
					                compliantSignedFillOrderTx.salt,
 | 
				
			||||||
 | 
					                compliantSignedFillOrderTx.signerAddress,
 | 
				
			||||||
 | 
					                exchangeCalldata,
 | 
				
			||||||
 | 
					                compliantSignedFillOrderTx.signature,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            const decoder = new LogDecoder(web3Wrapper);
 | 
				
			||||||
 | 
					            const tx = await decoder.getTxWithDecodedLogsAsync(txHash);
 | 
				
			||||||
 | 
					            console.log(JSON.stringify(tx, null, 4));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('batchFillOrdersNoThrow', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('batchFillOrKillOrders', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('batchFillOrKillOrders', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe.only('fillOrder', () => {
 | 
				
			||||||
 | 
					        beforeEach(async () => {
 | 
				
			||||||
 | 
					            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('should transfer the correct amounts and validate both maker/taker when both maker and taker meet the balance threshold', async () => {
 | 
				
			||||||
 | 
					            // Execute a valid fill
 | 
				
			||||||
 | 
					            const txReceipt = await balanceThresholdWrapper.fillOrderAsync(compliantSignedOrder, compliantSignedFillOrderTx.signerAddress, {takerAssetFillAmount});
 | 
				
			||||||
 | 
					            // Assert validated addresses
 | 
				
			||||||
 | 
					            const expectedValidatedAddresseses = [compliantSignedOrder.makerAddress, compliantSignedFillOrderTx.signerAddress];
 | 
				
			||||||
 | 
					            assertValidatedAddressesLog(txReceipt, expectedValidatedAddresseses);
 | 
				
			||||||
 | 
					            // Check balances
 | 
				
			||||||
 | 
					            const newBalances = await erc20Wrapper.getBalancesAsync();
 | 
				
			||||||
 | 
					            const makerAssetFillAmount = takerAssetFillAmount
 | 
				
			||||||
 | 
					                .times(compliantSignedOrder.makerAssetAmount)
 | 
				
			||||||
 | 
					                .dividedToIntegerBy(compliantSignedOrder.takerAssetAmount);
 | 
				
			||||||
 | 
					            const makerFeePaid = compliantSignedOrder.makerFee
 | 
				
			||||||
 | 
					                .times(makerAssetFillAmount)
 | 
				
			||||||
 | 
					                .dividedToIntegerBy(compliantSignedOrder.makerAssetAmount);
 | 
				
			||||||
 | 
					            const takerFeePaid = compliantSignedOrder.takerFee
 | 
				
			||||||
 | 
					                .times(makerAssetFillAmount)
 | 
				
			||||||
 | 
					                .dividedToIntegerBy(compliantSignedOrder.makerAssetAmount);
 | 
				
			||||||
 | 
					            expect(newBalances[compliantMakerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[compliantMakerAddress][defaultMakerAssetAddress].minus(makerAssetFillAmount),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(newBalances[compliantMakerAddress][defaultTakerAssetAddress]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[compliantMakerAddress][defaultTakerAssetAddress].add(takerAssetFillAmount),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(newBalances[compliantMakerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[compliantMakerAddress][zrxToken.address].minus(makerFeePaid),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(newBalances[compliantTakerAddress][defaultTakerAssetAddress]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[compliantTakerAddress][defaultTakerAssetAddress].minus(takerAssetFillAmount),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(newBalances[compliantTakerAddress][defaultMakerAssetAddress]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[compliantTakerAddress][defaultMakerAssetAddress].add(makerAssetFillAmount),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(newBalances[compliantTakerAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[compliantTakerAddress][zrxToken.address].minus(takerFeePaid),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            expect(newBalances[feeRecipientAddress][zrxToken.address]).to.be.bignumber.equal(
 | 
				
			||||||
 | 
					                erc20Balances[feeRecipientAddress][zrxToken.address].add(makerFeePaid.add(takerFeePaid)),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        it('should revert if maker address is not compliant (does not hold a Yes Token)', async () => {
 | 
					        it('should revert if maker does not meet the balance threshold', async () => {
 | 
				
			||||||
            // Create signed order with non-compliant maker address
 | 
					            // Create signed order with non-compliant maker address
 | 
				
			||||||
            const signedOrderWithBadMakerAddress = await orderFactory.newSignedOrderAsync({
 | 
					            const signedOrderWithBadMakerAddress = await orderFactory.newSignedOrderAsync({
 | 
				
			||||||
                senderAddress: compliantForwarderInstance.address,
 | 
					                senderAddress: compliantForwarderInstance.address,
 | 
				
			||||||
@@ -336,32 +399,92 @@ describe.only(ContractName.BalanceThresholdFilter, () => {
 | 
				
			|||||||
                RevertReason.AtLeastOneAddressDoesNotMeetBalanceThreshold
 | 
					                RevertReason.AtLeastOneAddressDoesNotMeetBalanceThreshold
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        it('should revert if taker does not meet the balance threshold', async () => {
 | 
				
			||||||
 | 
					            return expectTransactionFailedAsync(
 | 
				
			||||||
 | 
					                compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
				
			||||||
 | 
					                    compliantSignedFillOrderTx.salt,
 | 
				
			||||||
 | 
					                    nonCompliantAddress,
 | 
				
			||||||
 | 
					                    compliantSignedFillOrderTx.data,
 | 
				
			||||||
 | 
					                    compliantSignedFillOrderTx.signature,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                RevertReason.AtLeastOneAddressDoesNotMeetBalanceThreshold
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe('batchFillOrders', () => {
 | 
					    describe('fillOrderNoThrow', () => {
 | 
				
			||||||
        beforeEach(async () => {
 | 
					        beforeEach(async () => {
 | 
				
			||||||
            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
					            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        it('should transfer the correct amounts when maker and taker are compliant', async () => {
 | 
					        it('should transfer the correct amounts and validate both maker/taker when both maker and taker meet the balance threshold', async () => {
 | 
				
			||||||
            let order2 = _.cloneDeep(compliantSignedOrder);
 | 
					           
 | 
				
			||||||
            order2.makerAddress = `0x${_.reverse(compliantSignedOrder.makerAddress.slice(2).split('')).join('')}`;
 | 
					 | 
				
			||||||
            const orders = [compliantSignedOrder, order2];
 | 
					 | 
				
			||||||
            const fillAmounts = [new BigNumber(4), new BigNumber(4)];
 | 
					 | 
				
			||||||
            const signatures = ["0xabcd", "0xabcd"];
 | 
					 | 
				
			||||||
            const exchangeCalldata = exchangeInstance.batchFillOrders.getABIEncodedTransactionData(orders, fillAmounts, signatures);
 | 
					 | 
				
			||||||
            console.log('*'.repeat(40), exchangeCalldata, '*'.repeat(40));
 | 
					 | 
				
			||||||
            console.log('****** MAKER ADDRESS = ', compliantSignedOrder.makerAddress);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            const txHash = await compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.salt,
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.signerAddress,
 | 
					 | 
				
			||||||
                exchangeCalldata,
 | 
					 | 
				
			||||||
                compliantSignedFillOrderTx.signature,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const decoder = new LogDecoder(web3Wrapper);
 | 
					 | 
				
			||||||
            const tx = await decoder.getTxWithDecodedLogsAsync(txHash);
 | 
					 | 
				
			||||||
            console.log(JSON.stringify(tx, null, 4));
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        it('should revert if maker does not meet the balance threshold', async () => {
 | 
				
			||||||
 | 
					            // Create signed order with non-compliant maker address
 | 
				
			||||||
 | 
					            const signedOrderWithBadMakerAddress = await orderFactory.newSignedOrderAsync({
 | 
				
			||||||
 | 
					                senderAddress: compliantForwarderInstance.address,
 | 
				
			||||||
 | 
					                makerAddress: nonCompliantAddress
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            const signedOrderWithoutExchangeAddress = orderUtils.getOrderWithoutExchangeAddress(
 | 
				
			||||||
 | 
					                signedOrderWithBadMakerAddress,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            const signedOrderWithoutExchangeAddressData = exchangeInstance.fillOrder.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					                signedOrderWithoutExchangeAddress,
 | 
				
			||||||
 | 
					                takerAssetFillAmount,
 | 
				
			||||||
 | 
					                compliantSignedOrder.signature,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            const signedFillOrderTx = takerTransactionFactory.newSignedTransaction(
 | 
				
			||||||
 | 
					                signedOrderWithoutExchangeAddressData,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            // Call compliant forwarder
 | 
				
			||||||
 | 
					            return expectTransactionFailedAsync(
 | 
				
			||||||
 | 
					                compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
				
			||||||
 | 
					                    signedFillOrderTx.salt,
 | 
				
			||||||
 | 
					                    signedFillOrderTx.signerAddress,
 | 
				
			||||||
 | 
					                    signedFillOrderTx.data,
 | 
				
			||||||
 | 
					                    signedFillOrderTx.signature,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                RevertReason.AtLeastOneAddressDoesNotMeetBalanceThreshold
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        it('should revert if taker does not meet the balance threshold', async () => {
 | 
				
			||||||
 | 
					            return expectTransactionFailedAsync(
 | 
				
			||||||
 | 
					                compliantForwarderInstance.executeTransaction.sendTransactionAsync(
 | 
				
			||||||
 | 
					                    compliantSignedFillOrderTx.salt,
 | 
				
			||||||
 | 
					                    nonCompliantAddress,
 | 
				
			||||||
 | 
					                    compliantSignedFillOrderTx.data,
 | 
				
			||||||
 | 
					                    compliantSignedFillOrderTx.signature,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                RevertReason.AtLeastOneAddressDoesNotMeetBalanceThreshold
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('fillOrKillOrder', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('marketBuyOrders', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('marketBuyOrdersNoThrow', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('marketSellOrders', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('marketSellOrdersNoThrow', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('matchOrders', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('cancelOrder', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('batchCancelOrders', () => {
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('cancelOrdersUpTo', () => {
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
// tslint:disable:max-file-line-count
 | 
					// tslint:disable:max-file-line-count
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										243
									
								
								packages/contracts/test/utils/balance_threshold_wrapper.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								packages/contracts/test/utils/balance_threshold_wrapper.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,243 @@
 | 
				
			|||||||
 | 
					import { SignedOrder } from '@0x/types';
 | 
				
			||||||
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
 | 
					import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
				
			||||||
 | 
					import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types';
 | 
				
			||||||
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { ExchangeContract } from '../../generated-wrappers/exchange';
 | 
				
			||||||
 | 
					import { BalanceThresholdFilterContract } from '../../generated-wrappers/balance_threshold_filter';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { formatters } from './formatters';
 | 
				
			||||||
 | 
					import { LogDecoder } from './log_decoder';
 | 
				
			||||||
 | 
					import { orderUtils } from './order_utils';
 | 
				
			||||||
 | 
					import { TransactionFactory } from '../utils/transaction_factory';
 | 
				
			||||||
 | 
					import { OrderInfo } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class BalanceThresholdWrapper {
 | 
				
			||||||
 | 
					    private readonly _balanceThresholdFilter: BalanceThresholdFilterContract;
 | 
				
			||||||
 | 
					    private readonly _signerTransactionFactory: TransactionFactory;
 | 
				
			||||||
 | 
					    private readonly _exchange: ExchangeContract;
 | 
				
			||||||
 | 
					    private readonly _web3Wrapper: Web3Wrapper;
 | 
				
			||||||
 | 
					    private readonly _logDecoder: LogDecoder;
 | 
				
			||||||
 | 
					    constructor(balanceThresholdFilter: BalanceThresholdFilterContract, exchangeContract: ExchangeContract, signerTransactionFactory: TransactionFactory, provider: Provider) {
 | 
				
			||||||
 | 
					        this._balanceThresholdFilter = balanceThresholdFilter;
 | 
				
			||||||
 | 
					        this._exchange = exchangeContract;
 | 
				
			||||||
 | 
					        this._signerTransactionFactory = signerTransactionFactory;
 | 
				
			||||||
 | 
					        this._web3Wrapper = new Web3Wrapper(provider);
 | 
				
			||||||
 | 
					        this._logDecoder = new LogDecoder(this._web3Wrapper);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async fillOrderAsync(
 | 
				
			||||||
 | 
					        signedOrder: SignedOrder,
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmount?: BigNumber } = {},
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.fillOrder.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.order,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signature,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async fillOrKillOrderAsync(
 | 
				
			||||||
 | 
					        signedOrder: SignedOrder,
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmount?: BigNumber } = {},
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.fillOrKillOrder.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.order,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signature,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async fillOrderNoThrowAsync(
 | 
				
			||||||
 | 
					        signedOrder: SignedOrder,
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmount?: BigNumber; gas?: number } = {},
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.fillOrderNoThrow.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.order,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signature,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from, opts.gas);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async batchFillOrdersAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmounts?: BigNumber[] } = {},
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
 | 
				
			||||||
 | 
					        const data = this._exchange.batchFillOrders.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmounts,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async batchFillOrKillOrdersAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmounts?: BigNumber[] } = {},
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
 | 
				
			||||||
 | 
					        const data = this._exchange.batchFillOrKillOrders.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmounts,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async batchFillOrdersNoThrowAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmounts?: BigNumber[]; gas?: number } = {},
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createBatchFill(orders, opts.takerAssetFillAmounts);
 | 
				
			||||||
 | 
					        const data = this._exchange.batchFillOrKillOrders.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmounts,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from, opts.gas);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async marketSellOrdersAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmount: BigNumber },
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.marketSellOrders.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async marketSellOrdersNoThrowAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { takerAssetFillAmount: BigNumber; gas?: number },
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createMarketSellOrders(orders, opts.takerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.marketSellOrdersNoThrow.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from, opts.gas);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async marketBuyOrdersAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { makerAssetFillAmount: BigNumber },
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.marketBuyOrders.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.makerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async marketBuyOrdersNoThrowAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { makerAssetFillAmount: BigNumber; gas?: number },
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createMarketBuyOrders(orders, opts.makerAssetFillAmount);
 | 
				
			||||||
 | 
					        const data = this._exchange.marketBuyOrdersNoThrow.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.orders,
 | 
				
			||||||
 | 
					            params.makerAssetFillAmount,
 | 
				
			||||||
 | 
					            params.signatures,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from, opts.gas);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async cancelOrderAsync(signedOrder: SignedOrder, from: string): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = orderUtils.createCancel(signedOrder);
 | 
				
			||||||
 | 
					        const data = this._exchange.cancelOrder.getABIEncodedTransactionData(params.order);
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async batchCancelOrdersAsync(
 | 
				
			||||||
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = formatters.createBatchCancel(orders);
 | 
				
			||||||
 | 
					        const data = this._exchange.batchCancelOrders.getABIEncodedTransactionData(params.orders);
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async cancelOrdersUpToAsync(salt: BigNumber, from: string): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const data = this._exchange.cancelOrdersUpTo.getABIEncodedTransactionData(salt);
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
 | 
				
			||||||
 | 
					        const filledAmount = await this._exchange.filled.callAsync(orderHashHex);
 | 
				
			||||||
 | 
					        return filledAmount;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async isCancelledAsync(orderHashHex: string): Promise<boolean> {
 | 
				
			||||||
 | 
					        const isCancelled = await this._exchange.cancelled.callAsync(orderHashHex);
 | 
				
			||||||
 | 
					        return isCancelled;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async getOrderEpochAsync(makerAddress: string, senderAddress: string): Promise<BigNumber> {
 | 
				
			||||||
 | 
					        const orderEpoch = await this._exchange.orderEpoch.callAsync(makerAddress, senderAddress);
 | 
				
			||||||
 | 
					        return orderEpoch;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async getOrderInfoAsync(signedOrder: SignedOrder): Promise<OrderInfo> {
 | 
				
			||||||
 | 
					        const orderInfo = (await this._exchange.getOrderInfo.callAsync(signedOrder)) as OrderInfo;
 | 
				
			||||||
 | 
					        return orderInfo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async getOrdersInfoAsync(signedOrders: SignedOrder[]): Promise<OrderInfo[]> {
 | 
				
			||||||
 | 
					        const ordersInfo = (await this._exchange.getOrdersInfo.callAsync(signedOrders)) as OrderInfo[];
 | 
				
			||||||
 | 
					        return ordersInfo;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async matchOrdersAsync(
 | 
				
			||||||
 | 
					        signedOrderLeft: SignedOrder,
 | 
				
			||||||
 | 
					        signedOrderRight: SignedOrder,
 | 
				
			||||||
 | 
					        from: string,
 | 
				
			||||||
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
				
			||||||
 | 
					        const data = await this._exchange.matchOrders.getABIEncodedTransactionData(
 | 
				
			||||||
 | 
					            params.left,
 | 
				
			||||||
 | 
					            params.right,
 | 
				
			||||||
 | 
					            params.leftSignature,
 | 
				
			||||||
 | 
					            params.rightSignature
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = this._executeTransaction(data, from);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public getBalanceThresholdAddress(): string {
 | 
				
			||||||
 | 
					        return this._balanceThresholdFilter.address;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public getExchangeAddress(): string {
 | 
				
			||||||
 | 
					        return this._exchange.address;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private async _executeTransaction(abiEncodedExchangeTxData: string, from: string, gas?: number): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
 | 
					        const signedExchangeTx = this._signerTransactionFactory.newSignedTransaction(abiEncodedExchangeTxData);
 | 
				
			||||||
 | 
					        const txOpts = _.isUndefined(gas) ? {from} : {from, gas};
 | 
				
			||||||
 | 
					        const txHash = await this._balanceThresholdFilter.executeTransaction.sendTransactionAsync(
 | 
				
			||||||
 | 
					            signedExchangeTx.salt,
 | 
				
			||||||
 | 
					            signedExchangeTx.signerAddress,
 | 
				
			||||||
 | 
					            signedExchangeTx.data,
 | 
				
			||||||
 | 
					            signedExchangeTx.signature,
 | 
				
			||||||
 | 
					            txOpts,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txReceipt = await this._logDecoder.getTxWithDecodedLogsAsync(txHash);
 | 
				
			||||||
 | 
					        return txReceipt;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user