aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contract-wrappers/src/utils/assert.ts
blob: 30726c54635e6eb1bb1fddc46abbe32c9d5122ba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { assert as sharedAssert } from '@0xproject/assert';
// HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here
import { Schema } from '@0xproject/json-schemas'; // tslint:disable-line:no-unused-variable
import { assetDataUtils, signatureUtils } from '@0xproject/order-utils';
import { Order } from '@0xproject/types'; // tslint:disable-line:no-unused-variable
import { BigNumber } from '@0xproject/utils'; // tslint:disable-line:no-unused-variable
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider } from 'ethereum-types';
import * as _ from 'lodash';

import { constants } from './constants';

export const assert = {
    ...sharedAssert,
    async isValidSignatureAsync(
        provider: Provider,
        orderHash: string,
        signature: string,
        signerAddress: string,
    ): Promise<void> {
        const isValid = await signatureUtils.isValidSignatureAsync(provider, orderHash, signature, signerAddress);
        sharedAssert.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`);
    },
    isValidSubscriptionToken(variableName: string, subscriptionToken: string): void {
        const uuidRegex = new RegExp('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$');
        const isValid = uuidRegex.test(subscriptionToken);
        sharedAssert.assert(isValid, `Expected ${variableName} to be a valid subscription token`);
    },
    async isSenderAddressAsync(
        variableName: string,
        senderAddressHex: string,
        web3Wrapper: Web3Wrapper,
    ): Promise<void> {
        sharedAssert.isETHAddressHex(variableName, senderAddressHex);
        const isSenderAddressAvailable = await web3Wrapper.isSenderAddressAvailableAsync(senderAddressHex);
        sharedAssert.assert(
            isSenderAddressAvailable,
            `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`,
        );
    },
    ordersCanBeUsedForForwarderContract(orders: Order[], etherTokenAddress: string): void {
        sharedAssert.assert(!_.isEmpty(orders), 'Expected at least 1 signed order. Found no orders');
        assert.ordersHaveAtMostOneUniqueValueForProperty(orders, 'makerAssetData');
        assert.allTakerAssetDatasAreErc20Token(orders, etherTokenAddress);
        assert.allTakerAddressesAreNull(orders);
    },
    feeOrdersCanBeUsedForForwarderContract(orders: Order[], zrxTokenAddress: string, etherTokenAddress: string): void {
        if (!_.isEmpty(orders)) {
            assert.allMakerAssetDatasAreErc20Token(orders, zrxTokenAddress);
            assert.allTakerAssetDatasAreErc20Token(orders, etherTokenAddress);
        }
    },
    allTakerAddressesAreNull(orders: Order[]): void {
        assert.ordersHaveAtMostOneUniqueValueForProperty(orders, 'takerAddress', constants.NULL_ADDRESS);
    },
    allMakerAssetDatasAreErc20Token(orders: Order[], tokenAddress: string): void {
        assert.ordersHaveAtMostOneUniqueValueForProperty(
            orders,
            'makerAssetData',
            assetDataUtils.encodeERC20AssetData(tokenAddress),
        );
    },
    allTakerAssetDatasAreErc20Token(orders: Order[], tokenAddress: string): void {
        assert.ordersHaveAtMostOneUniqueValueForProperty(
            orders,
            'takerAssetData',
            assetDataUtils.encodeERC20AssetData(tokenAddress),
        );
    },
    /*
     * Asserts that all the orders have the same value for the provided propertyName
     * If the value parameter is provided, this asserts that all orders have the prope
    */
    ordersHaveAtMostOneUniqueValueForProperty(orders: Order[], propertyName: string, value?: any): void {
        const allValues = _.map(orders, order => _.get(order, propertyName));
        sharedAssert.hasAtMostOneUniqueValue(
            allValues,
            `Expected all orders to have the same ${propertyName} field. Found the following ${propertyName} values: ${JSON.stringify(
                allValues,
            )}`,
        );
        if (!_.isUndefined(value)) {
            const firstValue = _.head(allValues);
            sharedAssert.assert(
                firstValue === value,
                `Expected all orders to have a ${propertyName} field with value: ${value}. Found: ${firstValue}`,
            );
        }
    },
};