116 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { BlockchainLifecycle, devConstants, web3Factory } from '@0x/dev-utils';
 | 
						|
import { FillScenarios } from '@0x/fill-scenarios';
 | 
						|
import { runMigrationsAsync } from '@0x/migrations';
 | 
						|
import { assetDataUtils } from '@0x/order-utils';
 | 
						|
import { SignedOrder } from '@0x/types';
 | 
						|
import { BigNumber } from '@0x/utils';
 | 
						|
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
						|
import * as chai from 'chai';
 | 
						|
import 'mocha';
 | 
						|
 | 
						|
import { ContractWrappers } from '../src';
 | 
						|
 | 
						|
import { chaiSetup } from './utils/chai_setup';
 | 
						|
import { constants } from './utils/constants';
 | 
						|
import { tokenUtils } from './utils/token_utils';
 | 
						|
 | 
						|
chaiSetup.configure();
 | 
						|
const expect = chai.expect;
 | 
						|
 | 
						|
describe('Revert Validation ExchangeWrapper', () => {
 | 
						|
    let contractWrappers: ContractWrappers;
 | 
						|
    let userAddresses: string[];
 | 
						|
    let fillScenarios: FillScenarios;
 | 
						|
    let makerTokenAddress: string;
 | 
						|
    let takerTokenAddress: string;
 | 
						|
    let makerAddress: string;
 | 
						|
    let takerAddress: string;
 | 
						|
    let makerAssetData: string;
 | 
						|
    let takerAssetData: string;
 | 
						|
    let txHash: string;
 | 
						|
    let blockchainLifecycle: BlockchainLifecycle;
 | 
						|
    let web3Wrapper: Web3Wrapper;
 | 
						|
    const fillableAmount = new BigNumber(5);
 | 
						|
    const takerTokenFillAmount = new BigNumber(5);
 | 
						|
    let signedOrder: SignedOrder;
 | 
						|
    before(async () => {
 | 
						|
        // vmErrorsOnRPCResponse is useful for quick feedback and testing during development
 | 
						|
        // but is not the default behaviour in production. Here we ensure our failure cases
 | 
						|
        // are handled in an environment which behaves similar to production
 | 
						|
        const provider = web3Factory.getRpcProvider({
 | 
						|
            shouldUseInProcessGanache: true,
 | 
						|
            shouldThrowErrorsOnGanacheRPCResponse: false,
 | 
						|
        });
 | 
						|
        web3Wrapper = new Web3Wrapper(provider);
 | 
						|
        blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
 | 
						|
        // Re-deploy the artifacts in this provider, rather than in the default provider exposed in
 | 
						|
        // the beforeAll hook. This is due to the fact that the default provider enabled vmErrorsOnRPCResponse
 | 
						|
        // and we are explicity testing with vmErrorsOnRPCResponse disabled.
 | 
						|
        const txDefaults = {
 | 
						|
            gas: devConstants.GAS_LIMIT,
 | 
						|
            from: devConstants.TESTRPC_FIRST_ADDRESS,
 | 
						|
        };
 | 
						|
        await blockchainLifecycle.startAsync();
 | 
						|
        const contractAddresses = await runMigrationsAsync(provider, txDefaults);
 | 
						|
        const config = {
 | 
						|
            networkId: constants.TESTRPC_NETWORK_ID,
 | 
						|
            contractAddresses,
 | 
						|
            blockPollingIntervalMs: 10,
 | 
						|
        };
 | 
						|
        contractWrappers = new ContractWrappers(provider, config);
 | 
						|
        userAddresses = await web3Wrapper.getAvailableAddressesAsync();
 | 
						|
        fillScenarios = new FillScenarios(
 | 
						|
            provider,
 | 
						|
            userAddresses,
 | 
						|
            contractAddresses.zrxToken,
 | 
						|
            contractAddresses.exchange,
 | 
						|
            contractAddresses.erc20Proxy,
 | 
						|
            contractAddresses.erc721Proxy,
 | 
						|
        );
 | 
						|
        [, makerAddress, takerAddress] = userAddresses;
 | 
						|
        [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses();
 | 
						|
        [makerAssetData, takerAssetData] = [
 | 
						|
            assetDataUtils.encodeERC20AssetData(makerTokenAddress),
 | 
						|
            assetDataUtils.encodeERC20AssetData(takerTokenAddress),
 | 
						|
        ];
 | 
						|
        signedOrder = await fillScenarios.createFillableSignedOrderAsync(
 | 
						|
            makerAssetData,
 | 
						|
            takerAssetData,
 | 
						|
            makerAddress,
 | 
						|
            takerAddress,
 | 
						|
            fillableAmount,
 | 
						|
        );
 | 
						|
    });
 | 
						|
    after(async () => {
 | 
						|
        await blockchainLifecycle.revertAsync();
 | 
						|
    });
 | 
						|
    beforeEach(async () => {
 | 
						|
        await blockchainLifecycle.startAsync();
 | 
						|
    });
 | 
						|
    afterEach(async () => {
 | 
						|
        await blockchainLifecycle.revertAsync();
 | 
						|
    });
 | 
						|
    describe('#fillOrderAsync', () => {
 | 
						|
        it('should throw the revert reason when shouldValidate is true and a fill would revert', async () => {
 | 
						|
            // Create a scenario where the fill will revert
 | 
						|
            const makerTokenBalance = await contractWrappers.erc20Token.getBalanceAsync(
 | 
						|
                makerTokenAddress,
 | 
						|
                makerAddress,
 | 
						|
            );
 | 
						|
            // Transfer all of the tokens from maker to create a failure scenario
 | 
						|
            txHash = await contractWrappers.erc20Token.transferAsync(
 | 
						|
                makerTokenAddress,
 | 
						|
                makerAddress,
 | 
						|
                takerAddress,
 | 
						|
                makerTokenBalance,
 | 
						|
            );
 | 
						|
            await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS);
 | 
						|
            return expect(
 | 
						|
                contractWrappers.exchange.fillOrderAsync(signedOrder, takerTokenFillAmount, takerAddress, {
 | 
						|
                    shouldValidate: true,
 | 
						|
                }),
 | 
						|
            ).to.be.rejectedWith('TRANSFER_FAILED');
 | 
						|
        });
 | 
						|
    });
 | 
						|
});
 |