aboutsummaryrefslogblamecommitdiffstats
path: root/packages/contracts/src/utils/new_order_factory.ts
blob: a4ded423040f433d2bcba613107d9c1acb6daed1 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                                                                   

                                                                                               


                                        
                          










                                                                            















                                                                                                                       

                                



                                                           
                                









                                                                                                  








                                                                     



                                                                                                  













                                                             
                                                             







                                                                                                     
                                                                                        

                                                               


                                                                      

                                                     
                                                                                                               

                                                              


                                                                            



                                                                                           



                                                                       

                                                               



                                                                             








                                                                                             
                                                                                        

                                                               


                                                                      

                                                     
                                                                                                               

                                                              


                                                                            



                                                                                           



                                                                       

                                                               



                                                                             



























































































                                                                                                                

                         






                                             
                                                   




                                  

     
import { assetProxyUtils, generatePseudoRandomSalt } from '@0xproject/order-utils';
import { Order } from '@0xproject/types';
import { BigNumber, errorUtils } from '@0xproject/utils';

import { DummyERC721TokenContract } from '../contract_wrappers/generated/dummy_e_r_c721_token';

import { constants } from './constants';
import {
    AssetDataScenario,
    ERC721TokenIdsByOwner,
    ExpirationTimeSecondsScenario,
    FeeRecipientAddressScenario,
    OrderAmountScenario,
} from './types';

const TEN_UNITS_EIGHTEEN_DECIMALS = new BigNumber(10000000000000000000);
const POINT_ONE_UNITS_EIGHTEEN_DECIMALS = new BigNumber(100000000000000000);
const TEN_UNITS_FIVE_DECIMALS = new BigNumber(1000000);
const ONE_NFT_UNIT = new BigNumber(1);
const TEN_MINUTES_MS = 1000 * 60 * 10;

/*
 * TODO:
 * - Write function that given an order, fillAmount, retrieves orderRelevantState and maps it to expected test outcome.
 * - Write function that generates order permutations.
 * - Write functions for other steps that must be permutated
 */

export class NewOrderFactory {
    private _userAddresses: string[];
    private _zrxAddress: string;
    private _nonZrxERC20EighteenDecimalTokenAddresses: string[];
    private _erc20FiveDecimalTokenAddresses: string[];
    private _erc721Token: DummyERC721TokenContract;
    private _erc721Balances: ERC721TokenIdsByOwner;
    private _exchangeAddress: string;
    constructor(
        userAddresses: string[],
        zrxAddress: string,
        nonZrxERC20EighteenDecimalTokenAddresses: string[],
        erc20FiveDecimalTokenAddresses: string[],
        erc721Token: DummyERC721TokenContract,
        erc721Balances: ERC721TokenIdsByOwner,
        exchangeAddress: string,
    ) {
        this._userAddresses = userAddresses;
        this._zrxAddress = zrxAddress;
        this._nonZrxERC20EighteenDecimalTokenAddresses = nonZrxERC20EighteenDecimalTokenAddresses;
        this._erc20FiveDecimalTokenAddresses = erc20FiveDecimalTokenAddresses;
        this._erc721Token = erc721Token;
        this._erc721Balances = erc721Balances;
        this._exchangeAddress = exchangeAddress;
    }
    public generateOrder(
        feeRecipientScenario: FeeRecipientAddressScenario,
        makerAssetAmountScenario: OrderAmountScenario,
        takerAssetAmountScenario: OrderAmountScenario,
        makerFeeScenario: OrderAmountScenario,
        takerFeeScenario: OrderAmountScenario,
        expirationTimeSecondsScenario: ExpirationTimeSecondsScenario,
        makerAssetDataScenario: AssetDataScenario,
        takerAssetDataScenario: AssetDataScenario,
    ): Order {
        const makerAddress = this._userAddresses[1];
        const takerAddress = this._userAddresses[2];
        const erc721MakerAssetIds = this._erc721Balances[makerAddress][this._erc721Token.address];
        const erc721TakerAssetIds = this._erc721Balances[takerAddress][this._erc721Token.address];
        let feeRecipientAddress;
        let makerAssetAmount;
        let takerAssetAmount;
        let makerFee;
        let takerFee;
        let expirationTimeSeconds;
        let makerAssetData;
        let takerAssetData;

        switch (feeRecipientScenario) {
            case FeeRecipientAddressScenario.BurnAddress:
                feeRecipientAddress = constants.NULL_ADDRESS;
                break;
            case FeeRecipientAddressScenario.EthUserAddress:
                feeRecipientAddress = this._userAddresses[4];
                break;
            default:
                throw errorUtils.spawnSwitchErr('FeeRecipientAddressScenario', feeRecipientScenario);
        }

        const invalidAssetProxyIdHex = '0A';
        switch (makerAssetDataScenario) {
            case AssetDataScenario.ZRXFeeToken:
                makerAssetData = assetProxyUtils.encodeERC20ProxyData(this._zrxAddress);
                break;
            case AssetDataScenario.ERC20NonZRXEighteenDecimals:
                makerAssetData = assetProxyUtils.encodeERC20ProxyData(
                    this._nonZrxERC20EighteenDecimalTokenAddresses[0],
                );
                break;
            case AssetDataScenario.ERC20FiveDecimals:
                makerAssetData = assetProxyUtils.encodeERC20ProxyData(this._erc20FiveDecimalTokenAddresses[0]);
                break;
            case AssetDataScenario.ERC20InvalidAssetProxyId: {
                const validAssetData = assetProxyUtils.encodeERC20ProxyData(
                    this._nonZrxERC20EighteenDecimalTokenAddresses[0],
                );
                makerAssetData = `${validAssetData.slice(0, -2)}${invalidAssetProxyIdHex}`;
                break;
            }
            case AssetDataScenario.ERC721ValidAssetProxyId:
                makerAssetData = assetProxyUtils.encodeERC721ProxyData(
                    this._erc721Token.address,
                    erc721MakerAssetIds[0],
                );
                break;
            case AssetDataScenario.ERC721InvalidAssetProxyId: {
                const validAssetData = assetProxyUtils.encodeERC721ProxyData(
                    this._erc721Token.address,
                    erc721MakerAssetIds[0],
                );
                makerAssetData = `${validAssetData.slice(0, -2)}${invalidAssetProxyIdHex}`;
                break;
            }
            default:
                throw errorUtils.spawnSwitchErr('AssetDataScenario', makerAssetDataScenario);
        }

        switch (takerAssetDataScenario) {
            case AssetDataScenario.ZRXFeeToken:
                takerAssetData = assetProxyUtils.encodeERC20ProxyData(this._zrxAddress);
                break;
            case AssetDataScenario.ERC20NonZRXEighteenDecimals:
                takerAssetData = assetProxyUtils.encodeERC20ProxyData(
                    this._nonZrxERC20EighteenDecimalTokenAddresses[1],
                );
                break;
            case AssetDataScenario.ERC20FiveDecimals:
                takerAssetData = assetProxyUtils.encodeERC20ProxyData(this._erc20FiveDecimalTokenAddresses[1]);
                break;
            case AssetDataScenario.ERC20InvalidAssetProxyId: {
                const validAssetData = assetProxyUtils.encodeERC20ProxyData(
                    this._nonZrxERC20EighteenDecimalTokenAddresses[1],
                );
                takerAssetData = `${validAssetData.slice(0, -2)}${invalidAssetProxyIdHex}`;
                break;
            }
            case AssetDataScenario.ERC721ValidAssetProxyId:
                takerAssetData = assetProxyUtils.encodeERC721ProxyData(
                    this._erc721Token.address,
                    erc721TakerAssetIds[0],
                );
                break;
            case AssetDataScenario.ERC721InvalidAssetProxyId: {
                const validAssetData = assetProxyUtils.encodeERC721ProxyData(
                    this._erc721Token.address,
                    erc721TakerAssetIds[0],
                );
                takerAssetData = `${validAssetData.slice(0, -2)}${invalidAssetProxyIdHex}`;
                break;
            }
            default:
                throw errorUtils.spawnSwitchErr('AssetDataScenario', takerAssetDataScenario);
        }

        switch (makerAssetAmountScenario) {
            case OrderAmountScenario.NonZero:
                switch (makerAssetDataScenario) {
                    case AssetDataScenario.ERC20NonZRXEighteenDecimals:
                    case AssetDataScenario.ERC20InvalidAssetProxyId:
                        makerAssetAmount = TEN_UNITS_EIGHTEEN_DECIMALS;
                        break;
                    case AssetDataScenario.ERC20FiveDecimals:
                        makerAssetAmount = TEN_UNITS_FIVE_DECIMALS;
                        break;
                    case AssetDataScenario.ERC721ValidAssetProxyId:
                    case AssetDataScenario.ERC721InvalidAssetProxyId:
                        makerAssetAmount = ONE_NFT_UNIT;
                        break;
                    default:
                        throw errorUtils.spawnSwitchErr('AssetDataScenario', makerAssetDataScenario);
                }
                break;
            case OrderAmountScenario.Zero:
                makerAssetAmount = new BigNumber(0);
                break;
            default:
                throw errorUtils.spawnSwitchErr('OrderAmountScenario', makerAssetAmountScenario);
        }

        switch (takerAssetAmountScenario) {
            case OrderAmountScenario.NonZero:
                switch (takerAssetDataScenario) {
                    case AssetDataScenario.ERC20NonZRXEighteenDecimals:
                    case AssetDataScenario.ERC20InvalidAssetProxyId:
                        takerAssetAmount = TEN_UNITS_EIGHTEEN_DECIMALS;
                        break;
                    case AssetDataScenario.ERC20FiveDecimals:
                        takerAssetAmount = TEN_UNITS_FIVE_DECIMALS;
                        break;
                    case AssetDataScenario.ERC721ValidAssetProxyId:
                    case AssetDataScenario.ERC721InvalidAssetProxyId:
                        takerAssetAmount = ONE_NFT_UNIT;
                        break;
                    default:
                        throw errorUtils.spawnSwitchErr('AssetDataScenario', takerAssetDataScenario);
                }
                break;
            case OrderAmountScenario.Zero:
                takerAssetAmount = new BigNumber(0);
                break;
            default:
                throw errorUtils.spawnSwitchErr('OrderAmountScenario', takerAssetAmountScenario);
        }

        switch (makerFeeScenario) {
            case OrderAmountScenario.NonZero:
                makerFee = POINT_ONE_UNITS_EIGHTEEN_DECIMALS;
                break;
            case OrderAmountScenario.Zero:
                makerFee = new BigNumber(0);
                break;
            default:
                throw errorUtils.spawnSwitchErr('OrderAmountScenario', makerFeeScenario);
        }

        switch (takerFeeScenario) {
            case OrderAmountScenario.NonZero:
                takerFee = POINT_ONE_UNITS_EIGHTEEN_DECIMALS;
                break;
            case OrderAmountScenario.Zero:
                takerFee = new BigNumber(0);
                break;
            default:
                throw errorUtils.spawnSwitchErr('OrderAmountScenario', takerFeeScenario);
        }

        switch (expirationTimeSecondsScenario) {
            case ExpirationTimeSecondsScenario.InFuture:
                expirationTimeSeconds = new BigNumber(Date.now() + TEN_MINUTES_MS);
                break;
            case ExpirationTimeSecondsScenario.InPast:
                expirationTimeSeconds = new BigNumber(Date.now() - TEN_MINUTES_MS);
                break;
            default:
                throw errorUtils.spawnSwitchErr('ExpirationTimeSecondsScenario', expirationTimeSecondsScenario);
        }

        const order: Order = {
            senderAddress: constants.NULL_ADDRESS,
            makerAddress,
            takerAddress,
            makerFee,
            takerFee,
            makerAssetAmount,
            takerAssetAmount,
            makerAssetData,
            takerAssetData,
            salt: generatePseudoRandomSalt(),
            exchangeAddress: this._exchangeAddress,
            feeRecipientAddress,
            expirationTimeSeconds,
        };

        return order;
    }
}