Move all exchange-libs tests to separate files
This commit is contained in:
		@@ -29,6 +29,10 @@
 | 
				
			|||||||
        "src/LibMath.sol",
 | 
					        "src/LibMath.sol",
 | 
				
			||||||
        "src/LibOrder.sol",
 | 
					        "src/LibOrder.sol",
 | 
				
			||||||
        "src/LibZeroExTransaction.sol",
 | 
					        "src/LibZeroExTransaction.sol",
 | 
				
			||||||
        "test/TestLibs.sol"
 | 
					        "test/TestLibEIP712ExchangeDomain.sol",
 | 
				
			||||||
 | 
					        "test/TestLibFillResults.sol",
 | 
				
			||||||
 | 
					        "test/TestLibMath.sol",
 | 
				
			||||||
 | 
					        "test/TestLibOrder.sol",
 | 
				
			||||||
 | 
					        "test/TestLibZeroExTransaction.sol"
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@
 | 
				
			|||||||
        "generate-exchange-selectors": "node lib/scripts/generate-exchange-selectors.js ../../../exchange/generated-artifacts/Exchange.json ./contracts/src/LibExchangeSelectors.sol"
 | 
					        "generate-exchange-selectors": "node lib/scripts/generate-exchange-selectors.js ../../../exchange/generated-artifacts/Exchange.json ./contracts/src/LibExchangeSelectors.sol"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "config": {
 | 
					    "config": {
 | 
				
			||||||
        "abis": "./generated-artifacts/@(LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibs).json",
 | 
					        "abis": "./generated-artifacts/@(LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibEIP712ExchangeDomain|TestLibFillResults|TestLibMath|TestLibOrder|TestLibZeroExTransaction).json",
 | 
				
			||||||
        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
 | 
					        "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "repository": {
 | 
					    "repository": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,12 +10,20 @@ import * as LibFillResults from '../generated-artifacts/LibFillResults.json';
 | 
				
			|||||||
import * as LibMath from '../generated-artifacts/LibMath.json';
 | 
					import * as LibMath from '../generated-artifacts/LibMath.json';
 | 
				
			||||||
import * as LibOrder from '../generated-artifacts/LibOrder.json';
 | 
					import * as LibOrder from '../generated-artifacts/LibOrder.json';
 | 
				
			||||||
import * as LibZeroExTransaction from '../generated-artifacts/LibZeroExTransaction.json';
 | 
					import * as LibZeroExTransaction from '../generated-artifacts/LibZeroExTransaction.json';
 | 
				
			||||||
import * as TestLibs from '../generated-artifacts/TestLibs.json';
 | 
					import * as TestLibEIP712ExchangeDomain from '../generated-artifacts/TestLibEIP712ExchangeDomain.json';
 | 
				
			||||||
 | 
					import * as TestLibFillResults from '../generated-artifacts/TestLibFillResults.json';
 | 
				
			||||||
 | 
					import * as TestLibMath from '../generated-artifacts/TestLibMath.json';
 | 
				
			||||||
 | 
					import * as TestLibOrder from '../generated-artifacts/TestLibOrder.json';
 | 
				
			||||||
 | 
					import * as TestLibZeroExTransaction from '../generated-artifacts/TestLibZeroExTransaction.json';
 | 
				
			||||||
export const artifacts = {
 | 
					export const artifacts = {
 | 
				
			||||||
    LibEIP712ExchangeDomain: LibEIP712ExchangeDomain as ContractArtifact,
 | 
					    LibEIP712ExchangeDomain: LibEIP712ExchangeDomain as ContractArtifact,
 | 
				
			||||||
    LibFillResults: LibFillResults as ContractArtifact,
 | 
					    LibFillResults: LibFillResults as ContractArtifact,
 | 
				
			||||||
    LibMath: LibMath as ContractArtifact,
 | 
					    LibMath: LibMath as ContractArtifact,
 | 
				
			||||||
    LibOrder: LibOrder as ContractArtifact,
 | 
					    LibOrder: LibOrder as ContractArtifact,
 | 
				
			||||||
    LibZeroExTransaction: LibZeroExTransaction as ContractArtifact,
 | 
					    LibZeroExTransaction: LibZeroExTransaction as ContractArtifact,
 | 
				
			||||||
    TestLibs: TestLibs as ContractArtifact,
 | 
					    TestLibMath: TestLibMath as ContractArtifact,
 | 
				
			||||||
 | 
					    TestLibOrder: TestLibOrder as ContractArtifact,
 | 
				
			||||||
 | 
					    TestLibZeroExTransaction: TestLibZeroExTransaction as ContractArtifact,
 | 
				
			||||||
 | 
					    TestLibFillResults: TestLibFillResults as ContractArtifact,
 | 
				
			||||||
 | 
					    TestLibEIP712ExchangeDomain: TestLibEIP712ExchangeDomain as ContractArtifact,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
import { ReferenceFunctions } from '@0x/contracts-utils';
 | 
					import { ReferenceFunctions } from '@0x/contracts-utils';
 | 
				
			||||||
import { LibMathRevertErrors } from '@0x/order-utils';
 | 
					import { LibMathRevertErrors } from '@0x/order-utils';
 | 
				
			||||||
import { FillResults } from '@0x/types';
 | 
					import { FillResults, OrderWithoutDomain } from '@0x/types';
 | 
				
			||||||
import { BigNumber } from '@0x/utils';
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const { safeAdd, safeSub, safeMul, safeDiv } = ReferenceFunctions;
 | 
					const { safeAdd, safeSub, safeMul, safeDiv } = ReferenceFunctions;
 | 
				
			||||||
@@ -87,3 +87,22 @@ export function addFillResults(a: FillResults, b: FillResults): FillResults {
 | 
				
			|||||||
        takerFeePaid: safeAdd(a.takerFeePaid, b.takerFeePaid),
 | 
					        takerFeePaid: safeAdd(a.takerFeePaid, b.takerFeePaid),
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Calculates amounts filled and fees paid by maker and taker.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export function calculateFillResults(order: OrderWithoutDomain, takerAssetFilledAmount: BigNumber): FillResults {
 | 
				
			||||||
 | 
					    const makerAssetFilledAmount = safeGetPartialAmountFloor(
 | 
				
			||||||
 | 
					        takerAssetFilledAmount,
 | 
				
			||||||
 | 
					        order.takerAssetAmount,
 | 
				
			||||||
 | 
					        order.makerAssetAmount,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    const makerFeePaid = safeGetPartialAmountFloor(makerAssetFilledAmount, order.makerAssetAmount, order.makerFee);
 | 
				
			||||||
 | 
					    const takerFeePaid = safeGetPartialAmountFloor(takerAssetFilledAmount, order.takerAssetAmount, order.takerFee);
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					        makerAssetFilledAmount,
 | 
				
			||||||
 | 
					        takerAssetFilledAmount,
 | 
				
			||||||
 | 
					        makerFeePaid,
 | 
				
			||||||
 | 
					        takerFeePaid,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,4 +8,8 @@ export * from '../generated-wrappers/lib_fill_results';
 | 
				
			|||||||
export * from '../generated-wrappers/lib_math';
 | 
					export * from '../generated-wrappers/lib_math';
 | 
				
			||||||
export * from '../generated-wrappers/lib_order';
 | 
					export * from '../generated-wrappers/lib_order';
 | 
				
			||||||
export * from '../generated-wrappers/lib_zero_ex_transaction';
 | 
					export * from '../generated-wrappers/lib_zero_ex_transaction';
 | 
				
			||||||
export * from '../generated-wrappers/test_libs';
 | 
					export * from '../generated-wrappers/test_lib_e_i_p712_exchange_domain';
 | 
				
			||||||
 | 
					export * from '../generated-wrappers/test_lib_fill_results';
 | 
				
			||||||
 | 
					export * from '../generated-wrappers/test_lib_math';
 | 
				
			||||||
 | 
					export * from '../generated-wrappers/test_lib_order';
 | 
				
			||||||
 | 
					export * from '../generated-wrappers/test_lib_zero_ex_transaction';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,23 +1,260 @@
 | 
				
			|||||||
import { blockchainTests, constants, describe, expect } from '@0x/contracts-test-utils';
 | 
					import {
 | 
				
			||||||
 | 
					    blockchainTests,
 | 
				
			||||||
 | 
					    constants,
 | 
				
			||||||
 | 
					    describe,
 | 
				
			||||||
 | 
					    expect,
 | 
				
			||||||
 | 
					    testCombinatoriallyWithReferenceFunc,
 | 
				
			||||||
 | 
					    uint256Values,
 | 
				
			||||||
 | 
					} from '@0x/contracts-test-utils';
 | 
				
			||||||
 | 
					import { LibMathRevertErrors } from '@0x/order-utils';
 | 
				
			||||||
 | 
					import { FillResults, OrderWithoutDomain as Order } from '@0x/types';
 | 
				
			||||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
 | 
					import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { artifacts, ReferenceFunctions, TestLibsContract } from '../src';
 | 
					import { artifacts, ReferenceFunctions, TestLibFillResultsContract } from '../src';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
blockchainTests('LibFillResults', env => {
 | 
					blockchainTests('LibFillResults', env => {
 | 
				
			||||||
    const CHAIN_ID = 1337;
 | 
					 | 
				
			||||||
    const { ONE_ETHER, MAX_UINT256 } = constants;
 | 
					    const { ONE_ETHER, MAX_UINT256 } = constants;
 | 
				
			||||||
    let libsContract: TestLibsContract;
 | 
					    const EMPTY_ORDER: Order = {
 | 
				
			||||||
 | 
					        senderAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					        makerAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					        takerAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					        makerFee: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        takerFee: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        makerAssetAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        takerAssetAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        makerAssetData: constants.NULL_BYTES,
 | 
				
			||||||
 | 
					        takerAssetData: constants.NULL_BYTES,
 | 
				
			||||||
 | 
					        makerFeeAssetData: constants.NULL_BYTES,
 | 
				
			||||||
 | 
					        takerFeeAssetData: constants.NULL_BYTES,
 | 
				
			||||||
 | 
					        salt: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        feeRecipientAddress: constants.NULL_ADDRESS,
 | 
				
			||||||
 | 
					        expirationTimeSeconds: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let libsContract: TestLibFillResultsContract;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        libsContract = await TestLibsContract.deployFrom0xArtifactAsync(
 | 
					        libsContract = await TestLibFillResultsContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
            artifacts.TestLibs,
 | 
					            artifacts.TestLibFillResults,
 | 
				
			||||||
            env.provider,
 | 
					            env.provider,
 | 
				
			||||||
            env.txDefaults,
 | 
					            env.txDefaults,
 | 
				
			||||||
            new BigNumber(CHAIN_ID),
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('calculateFillResults', () => {
 | 
				
			||||||
 | 
					        describe.optional('combinatorial tests', () => {
 | 
				
			||||||
 | 
					            function makeOrder(
 | 
				
			||||||
 | 
					                makerAssetAmount: BigNumber,
 | 
				
			||||||
 | 
					                takerAssetAmount: BigNumber,
 | 
				
			||||||
 | 
					                makerFee: BigNumber,
 | 
				
			||||||
 | 
					                takerFee: BigNumber,
 | 
				
			||||||
 | 
					            ): Order {
 | 
				
			||||||
 | 
					                return {
 | 
				
			||||||
 | 
					                    ...EMPTY_ORDER,
 | 
				
			||||||
 | 
					                    makerAssetAmount,
 | 
				
			||||||
 | 
					                    takerAssetAmount,
 | 
				
			||||||
 | 
					                    makerFee,
 | 
				
			||||||
 | 
					                    takerFee,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            async function referenceCalculateFillResultsAsync(
 | 
				
			||||||
 | 
					                orderTakerAssetAmount: BigNumber,
 | 
				
			||||||
 | 
					                takerAssetFilledAmount: BigNumber,
 | 
				
			||||||
 | 
					                otherAmount: BigNumber,
 | 
				
			||||||
 | 
					            ): Promise<FillResults> {
 | 
				
			||||||
 | 
					                // Note(albrow): Here we are re-using the same value (otherAmount)
 | 
				
			||||||
 | 
					                // for order.makerAssetAmount, order.makerFee, and order.takerFee.
 | 
				
			||||||
 | 
					                // This should be safe because they are never used with each other
 | 
				
			||||||
 | 
					                // in any mathematical operation in either the reference TypeScript
 | 
				
			||||||
 | 
					                // implementation or the Solidity implementation of
 | 
				
			||||||
 | 
					                // calculateFillResults.
 | 
				
			||||||
 | 
					                return ReferenceFunctions.calculateFillResults(
 | 
				
			||||||
 | 
					                    makeOrder(otherAmount, orderTakerAssetAmount, otherAmount, otherAmount),
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            async function testCalculateFillResultsAsync(
 | 
				
			||||||
 | 
					                orderTakerAssetAmount: BigNumber,
 | 
				
			||||||
 | 
					                takerAssetFilledAmount: BigNumber,
 | 
				
			||||||
 | 
					                otherAmount: BigNumber,
 | 
				
			||||||
 | 
					            ): Promise<FillResults> {
 | 
				
			||||||
 | 
					                const order = makeOrder(otherAmount, orderTakerAssetAmount, otherAmount, otherAmount);
 | 
				
			||||||
 | 
					                return libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            testCombinatoriallyWithReferenceFunc(
 | 
				
			||||||
 | 
					                'calculateFillResults',
 | 
				
			||||||
 | 
					                referenceCalculateFillResultsAsync,
 | 
				
			||||||
 | 
					                testCalculateFillResultsAsync,
 | 
				
			||||||
 | 
					                [uint256Values, uint256Values, uint256Values],
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        describe('explicit tests', () => {
 | 
				
			||||||
 | 
					            const MAX_UINT256_ROOT = constants.MAX_UINT256_ROOT;
 | 
				
			||||||
 | 
					            function makeOrder(details?: Partial<Order>): Order {
 | 
				
			||||||
 | 
					                return _.assign({}, EMPTY_ORDER, details);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('matches the output of the reference function', async () => {
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                    takerAssetAmount: ONE_ETHER.times(2),
 | 
				
			||||||
 | 
					                    makerFee: ONE_ETHER.times(0.0023),
 | 
				
			||||||
 | 
					                    takerFee: ONE_ETHER.times(0.0025),
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = ONE_ETHER.dividedToIntegerBy(3);
 | 
				
			||||||
 | 
					                const expected = ReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount);
 | 
				
			||||||
 | 
					                const actual = await libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount);
 | 
				
			||||||
 | 
					                expect(actual).to.deep.eq(expected);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if computing `fillResults.makerAssetFilledAmount` overflows', async () => {
 | 
				
			||||||
 | 
					                // All values need to be large to ensure we don't trigger a RoundingError.
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: MAX_UINT256_ROOT.times(2),
 | 
				
			||||||
 | 
					                    takerAssetAmount: MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = MAX_UINT256_ROOT;
 | 
				
			||||||
 | 
					                const expectedError = new SafeMathRevertErrors.SafeMathError(
 | 
				
			||||||
 | 
					                    SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if computing `fillResults.makerFeePaid` overflows', async () => {
 | 
				
			||||||
 | 
					                // All values need to be large to ensure we don't trigger a RoundingError.
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                    takerAssetAmount: MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                    makerFee: MAX_UINT256_ROOT.times(11),
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = MAX_UINT256_ROOT.dividedToIntegerBy(10);
 | 
				
			||||||
 | 
					                const makerAssetFilledAmount = ReferenceFunctions.getPartialAmountFloor(
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.takerAssetAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const expectedError = new SafeMathRevertErrors.SafeMathError(
 | 
				
			||||||
 | 
					                    SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
 | 
				
			||||||
 | 
					                    makerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.makerFee,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if computing `fillResults.takerFeePaid` overflows', async () => {
 | 
				
			||||||
 | 
					                // All values need to be large to ensure we don't trigger a RoundingError.
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                    takerAssetAmount: MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                    takerFee: MAX_UINT256_ROOT.times(11),
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = MAX_UINT256_ROOT.dividedToIntegerBy(10);
 | 
				
			||||||
 | 
					                const expectedError = new SafeMathRevertErrors.SafeMathError(
 | 
				
			||||||
 | 
					                    SafeMathRevertErrors.SafeMathErrorCodes.Uint256MultiplicationOverflow,
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.takerFee,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if `order.makerAssetAmount` is 0', async () => {
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					                    takerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = ONE_ETHER;
 | 
				
			||||||
 | 
					                const expectedError = new LibMathRevertErrors.DivisionByZeroError();
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if `order.takerAssetAmount` is 0', async () => {
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                    takerAssetAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = ONE_ETHER;
 | 
				
			||||||
 | 
					                const expectedError = new LibMathRevertErrors.DivisionByZeroError();
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if there is a rounding error computing `makerAsssetFilledAmount`', async () => {
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: new BigNumber(100),
 | 
				
			||||||
 | 
					                    takerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = order.takerAssetAmount.dividedToIntegerBy(3);
 | 
				
			||||||
 | 
					                const expectedError = new LibMathRevertErrors.RoundingError(
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.takerAssetAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if there is a rounding error computing `makerFeePaid`', async () => {
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                    takerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                    makerFee: new BigNumber(100),
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = order.takerAssetAmount.dividedToIntegerBy(3);
 | 
				
			||||||
 | 
					                const makerAssetFilledAmount = ReferenceFunctions.getPartialAmountFloor(
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.takerAssetAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const expectedError = new LibMathRevertErrors.RoundingError(
 | 
				
			||||||
 | 
					                    makerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                    order.makerFee,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it('reverts if there is a rounding error computing `takerFeePaid`', async () => {
 | 
				
			||||||
 | 
					                const order = makeOrder({
 | 
				
			||||||
 | 
					                    makerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                    takerAssetAmount: ONE_ETHER,
 | 
				
			||||||
 | 
					                    takerFee: new BigNumber(100),
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                const takerAssetFilledAmount = order.takerAssetAmount.dividedToIntegerBy(3);
 | 
				
			||||||
 | 
					                const makerAssetFilledAmount = ReferenceFunctions.getPartialAmountFloor(
 | 
				
			||||||
 | 
					                    takerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.takerAssetAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const expectedError = new LibMathRevertErrors.RoundingError(
 | 
				
			||||||
 | 
					                    makerAssetFilledAmount,
 | 
				
			||||||
 | 
					                    order.makerAssetAmount,
 | 
				
			||||||
 | 
					                    order.takerFee,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                return expect(libsContract.calculateFillResults.callAsync(order, takerAssetFilledAmount)).to.revertWith(
 | 
				
			||||||
 | 
					                    expectedError,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe('addFillResults', () => {
 | 
					    describe('addFillResults', () => {
 | 
				
			||||||
        describe('explicit tests', () => {
 | 
					        describe('explicit tests', () => {
 | 
				
			||||||
            const DEFAULT_FILL_RESULTS = [
 | 
					            const DEFAULT_FILL_RESULTS = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,19 +9,17 @@ import {
 | 
				
			|||||||
import { LibMathRevertErrors } from '@0x/order-utils';
 | 
					import { LibMathRevertErrors } from '@0x/order-utils';
 | 
				
			||||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
 | 
					import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { artifacts, ReferenceFunctions, TestLibsContract } from '../src';
 | 
					import { artifacts, ReferenceFunctions, TestLibMathContract } from '../src';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
blockchainTests('LibMath', env => {
 | 
					blockchainTests('LibMath', env => {
 | 
				
			||||||
    const CHAIN_ID = 1337;
 | 
					 | 
				
			||||||
    const { ONE_ETHER, MAX_UINT256, MAX_UINT256_ROOT, ZERO_AMOUNT } = constants;
 | 
					    const { ONE_ETHER, MAX_UINT256, MAX_UINT256_ROOT, ZERO_AMOUNT } = constants;
 | 
				
			||||||
    let libsContract: TestLibsContract;
 | 
					    let libsContract: TestLibMathContract;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        libsContract = await TestLibsContract.deployFrom0xArtifactAsync(
 | 
					        libsContract = await TestLibMathContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
            artifacts.TestLibs,
 | 
					            artifacts.TestLibMath,
 | 
				
			||||||
            env.provider,
 | 
					            env.provider,
 | 
				
			||||||
            env.txDefaults,
 | 
					            env.txDefaults,
 | 
				
			||||||
            new BigNumber(CHAIN_ID),
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										75
									
								
								contracts/exchange-libs/test/lib_order.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								contracts/exchange-libs/test/lib_order.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					import { addressUtils, blockchainTests, constants, describe, expect } from '@0x/contracts-test-utils';
 | 
				
			||||||
 | 
					import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
 | 
				
			||||||
 | 
					import { Order } from '@0x/types';
 | 
				
			||||||
 | 
					import { BigNumber, providerUtils, signTypedDataUtils } from '@0x/utils';
 | 
				
			||||||
 | 
					import * as ethUtil from 'ethereumjs-util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { artifacts, TestLibOrderContract } from '../src';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					blockchainTests('LibOrder', env => {
 | 
				
			||||||
 | 
					    let libOrderContract: TestLibOrderContract;
 | 
				
			||||||
 | 
					    let order: Order;
 | 
				
			||||||
 | 
					    let chainId: number;
 | 
				
			||||||
 | 
					    before(async () => {
 | 
				
			||||||
 | 
					        libOrderContract = await TestLibOrderContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
 | 
					            artifacts.TestLibOrder,
 | 
				
			||||||
 | 
					            env.provider,
 | 
				
			||||||
 | 
					            env.txDefaults,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        chainId = await providerUtils.getChainIdAsync(env.provider);
 | 
				
			||||||
 | 
					        const domain = {
 | 
				
			||||||
 | 
					            verifyingContractAddress: libOrderContract.address,
 | 
				
			||||||
 | 
					            chainId,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        order = {
 | 
				
			||||||
 | 
					            ...constants.STATIC_ORDER_PARAMS,
 | 
				
			||||||
 | 
					            makerAddress: addressUtils.generatePseudoRandomAddress(),
 | 
				
			||||||
 | 
					            takerAddress: addressUtils.generatePseudoRandomAddress(),
 | 
				
			||||||
 | 
					            senderAddress: addressUtils.generatePseudoRandomAddress(),
 | 
				
			||||||
 | 
					            feeRecipientAddress: addressUtils.generatePseudoRandomAddress(),
 | 
				
			||||||
 | 
					            makerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
 | 
				
			||||||
 | 
					            takerAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
 | 
				
			||||||
 | 
					            makerFeeAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
 | 
				
			||||||
 | 
					            takerFeeAssetData: assetDataUtils.encodeERC20AssetData(addressUtils.generatePseudoRandomAddress()),
 | 
				
			||||||
 | 
					            salt: new BigNumber(0),
 | 
				
			||||||
 | 
					            expirationTimeSeconds: new BigNumber(0),
 | 
				
			||||||
 | 
					            domain,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('LibOrder', () => {
 | 
				
			||||||
 | 
					        describe('getOrderHash', () => {
 | 
				
			||||||
 | 
					            it('should return the correct orderHash', async () => {
 | 
				
			||||||
 | 
					                const domainHash = ethUtil.bufferToHex(
 | 
				
			||||||
 | 
					                    signTypedDataUtils.generateDomainHash({
 | 
				
			||||||
 | 
					                        ...order.domain,
 | 
				
			||||||
 | 
					                        name: constants.EIP712_DOMAIN_NAME,
 | 
				
			||||||
 | 
					                        version: constants.EIP712_DOMAIN_VERSION,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const orderHashHex = await libOrderContract.getOrderHash.callAsync(order, domainHash);
 | 
				
			||||||
 | 
					                expect(orderHashUtils.getOrderHashHex(order)).to.be.equal(orderHashHex);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            it('orderHash should differ if the domain hash is different', async () => {
 | 
				
			||||||
 | 
					                const domainHash1 = ethUtil.bufferToHex(
 | 
				
			||||||
 | 
					                    signTypedDataUtils.generateDomainHash({
 | 
				
			||||||
 | 
					                        ...order.domain,
 | 
				
			||||||
 | 
					                        name: constants.EIP712_DOMAIN_NAME,
 | 
				
			||||||
 | 
					                        version: constants.EIP712_DOMAIN_VERSION,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const domainHash2 = ethUtil.bufferToHex(
 | 
				
			||||||
 | 
					                    signTypedDataUtils.generateDomainHash({
 | 
				
			||||||
 | 
					                        ...order.domain,
 | 
				
			||||||
 | 
					                        name: constants.EIP712_DOMAIN_NAME,
 | 
				
			||||||
 | 
					                        version: constants.EIP712_DOMAIN_VERSION,
 | 
				
			||||||
 | 
					                        chainId: 1337,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const orderHashHex1 = await libOrderContract.getOrderHash.callAsync(order, domainHash1);
 | 
				
			||||||
 | 
					                const orderHashHex2 = await libOrderContract.getOrderHash.callAsync(order, domainHash2);
 | 
				
			||||||
 | 
					                expect(orderHashHex1).to.be.not.equal(orderHashHex2);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										77
									
								
								contracts/exchange-libs/test/lib_zero_ex_transaction.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								contracts/exchange-libs/test/lib_zero_ex_transaction.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					import { addressUtils, blockchainTests, constants, describe, expect } from '@0x/contracts-test-utils';
 | 
				
			||||||
 | 
					import { transactionHashUtils } from '@0x/order-utils';
 | 
				
			||||||
 | 
					import { ZeroExTransaction } from '@0x/types';
 | 
				
			||||||
 | 
					import { BigNumber, providerUtils, signTypedDataUtils } from '@0x/utils';
 | 
				
			||||||
 | 
					import * as ethUtil from 'ethereumjs-util';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { artifacts, TestLibZeroExTransactionContract } from '../src';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					blockchainTests('LibZeroExTransaction', env => {
 | 
				
			||||||
 | 
					    let libZeroExTransactionContract: TestLibZeroExTransactionContract;
 | 
				
			||||||
 | 
					    let zeroExTransaction: ZeroExTransaction;
 | 
				
			||||||
 | 
					    let chainId: number;
 | 
				
			||||||
 | 
					    before(async () => {
 | 
				
			||||||
 | 
					        libZeroExTransactionContract = await TestLibZeroExTransactionContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
 | 
					            artifacts.TestLibZeroExTransaction,
 | 
				
			||||||
 | 
					            env.provider,
 | 
				
			||||||
 | 
					            env.txDefaults,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        chainId = await providerUtils.getChainIdAsync(env.provider);
 | 
				
			||||||
 | 
					        const domain = {
 | 
				
			||||||
 | 
					            verifyingContractAddress: libZeroExTransactionContract.address,
 | 
				
			||||||
 | 
					            chainId,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        zeroExTransaction = {
 | 
				
			||||||
 | 
					            signerAddress: addressUtils.generatePseudoRandomAddress(),
 | 
				
			||||||
 | 
					            salt: new BigNumber(0),
 | 
				
			||||||
 | 
					            expirationTimeSeconds: new BigNumber(0),
 | 
				
			||||||
 | 
					            data: constants.NULL_BYTES,
 | 
				
			||||||
 | 
					            domain,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    describe('LibZeroExTransaction', () => {
 | 
				
			||||||
 | 
					        describe('getTransactionHash', () => {
 | 
				
			||||||
 | 
					            it('should return the correct transactionHash', async () => {
 | 
				
			||||||
 | 
					                const domainHash = ethUtil.bufferToHex(
 | 
				
			||||||
 | 
					                    signTypedDataUtils.generateDomainHash({
 | 
				
			||||||
 | 
					                        ...zeroExTransaction.domain,
 | 
				
			||||||
 | 
					                        name: constants.EIP712_DOMAIN_NAME,
 | 
				
			||||||
 | 
					                        version: constants.EIP712_DOMAIN_VERSION,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const orderHashHex = await libZeroExTransactionContract.getZeroExTransactionHash.callAsync(
 | 
				
			||||||
 | 
					                    zeroExTransaction,
 | 
				
			||||||
 | 
					                    domainHash,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                expect(transactionHashUtils.getTransactionHashHex(zeroExTransaction)).to.be.equal(orderHashHex);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            it('transactionHash should differ if the domain hash is different', async () => {
 | 
				
			||||||
 | 
					                const domainHash1 = ethUtil.bufferToHex(
 | 
				
			||||||
 | 
					                    signTypedDataUtils.generateDomainHash({
 | 
				
			||||||
 | 
					                        ...zeroExTransaction.domain,
 | 
				
			||||||
 | 
					                        name: constants.EIP712_DOMAIN_NAME,
 | 
				
			||||||
 | 
					                        version: constants.EIP712_DOMAIN_VERSION,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const domainHash2 = ethUtil.bufferToHex(
 | 
				
			||||||
 | 
					                    signTypedDataUtils.generateDomainHash({
 | 
				
			||||||
 | 
					                        ...zeroExTransaction.domain,
 | 
				
			||||||
 | 
					                        name: constants.EIP712_DOMAIN_NAME,
 | 
				
			||||||
 | 
					                        version: constants.EIP712_DOMAIN_VERSION,
 | 
				
			||||||
 | 
					                        chainId: 1337,
 | 
				
			||||||
 | 
					                    }),
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const transactionHashHex1 = await libZeroExTransactionContract.getZeroExTransactionHash.callAsync(
 | 
				
			||||||
 | 
					                    zeroExTransaction,
 | 
				
			||||||
 | 
					                    domainHash1,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                const transactionHashHex2 = await libZeroExTransactionContract.getZeroExTransactionHash.callAsync(
 | 
				
			||||||
 | 
					                    zeroExTransaction,
 | 
				
			||||||
 | 
					                    domainHash2,
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					                expect(transactionHashHex1).to.be.not.equal(transactionHashHex2);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -8,7 +8,11 @@
 | 
				
			|||||||
        "generated-artifacts/LibMath.json",
 | 
					        "generated-artifacts/LibMath.json",
 | 
				
			||||||
        "generated-artifacts/LibOrder.json",
 | 
					        "generated-artifacts/LibOrder.json",
 | 
				
			||||||
        "generated-artifacts/LibZeroExTransaction.json",
 | 
					        "generated-artifacts/LibZeroExTransaction.json",
 | 
				
			||||||
        "generated-artifacts/TestLibs.json"
 | 
					        "generated-artifacts/TestLibEIP712ExchangeDomain.json",
 | 
				
			||||||
 | 
					        "generated-artifacts/TestLibFillResults.json",
 | 
				
			||||||
 | 
					        "generated-artifacts/TestLibMath.json",
 | 
				
			||||||
 | 
					        "generated-artifacts/TestLibOrder.json",
 | 
				
			||||||
 | 
					        "generated-artifacts/TestLibZeroExTransaction.json"
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "exclude": ["./deploy/solc/solc_bin"]
 | 
					    "exclude": ["./deploy/solc/solc_bin"]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,4 +66,6 @@ export const constants = {
 | 
				
			|||||||
    KECCAK256_NULL: ethUtil.addHexPrefix(ethUtil.bufferToHex(ethUtil.SHA3_NULL)),
 | 
					    KECCAK256_NULL: ethUtil.addHexPrefix(ethUtil.bufferToHex(ethUtil.SHA3_NULL)),
 | 
				
			||||||
    MAX_UINT256_ROOT: new BigNumber('340282366920938463463374607431768211456'),
 | 
					    MAX_UINT256_ROOT: new BigNumber('340282366920938463463374607431768211456'),
 | 
				
			||||||
    ONE_ETHER: new BigNumber(1e18),
 | 
					    ONE_ETHER: new BigNumber(1e18),
 | 
				
			||||||
 | 
					    EIP712_DOMAIN_NAME: '0x Protocol',
 | 
				
			||||||
 | 
					    EIP712_DOMAIN_VERSION: '3.0.0',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user