import { SupportedProvider } from '@0x/subproviders'; import { SimpleContractArtifact } from '@0x/types'; import { NULL_ADDRESS } from '@0x/utils'; import { TxData } from 'ethereum-types'; import * as _ from 'lodash'; import { artifacts } from './artifacts'; import { FeeCollectorControllerContract, FullMigrationContract, InitialMigrationContract, IZeroExContract, MetaTransactionsFeatureContract, NativeOrdersFeatureContract, OtcOrdersFeatureContract, OwnableFeatureContract, SimpleFunctionRegistryFeatureContract, TransformERC20FeatureContract, ZeroExContract, } from './wrappers'; // tslint:disable: completed-docs /** * Addresses of minimum features for a deployment of the Exchange Proxy. */ export interface BootstrapFeatures { registry: string; ownable: string; } /** * Artifacts to use when deploying bootstrap features. */ export interface BootstrapFeatureArtifacts { registry: SimpleContractArtifact; ownable: SimpleContractArtifact; } const DEFAULT_BOOTSTRAP_FEATURE_ARTIFACTS = { registry: artifacts.SimpleFunctionRegistryFeature, ownable: artifacts.OwnableFeature, }; /** * Deploy the minimum features of the Exchange Proxy. */ export async function deployBootstrapFeaturesAsync( provider: SupportedProvider, txDefaults: Partial, features: Partial = {}, featureArtifacts: Partial = {}, ): Promise { const _featureArtifacts = { ...DEFAULT_BOOTSTRAP_FEATURE_ARTIFACTS, ...featureArtifacts, }; return { registry: features.registry || ( await SimpleFunctionRegistryFeatureContract.deployFrom0xArtifactAsync( _featureArtifacts.registry, provider, txDefaults, artifacts, ) ).address, ownable: features.ownable || ( await OwnableFeatureContract.deployFrom0xArtifactAsync( _featureArtifacts.ownable, provider, txDefaults, artifacts, ) ).address, }; } /** * Migrate an instance of the Exchange proxy with minimum viable features. */ export async function initialMigrateAsync( owner: string, provider: SupportedProvider, txDefaults: Partial, features: Partial = {}, ): Promise { const migrator = await InitialMigrationContract.deployFrom0xArtifactAsync( artifacts.InitialMigration, provider, txDefaults, artifacts, txDefaults.from as string, ); const zeroEx = await ZeroExContract.deployFrom0xArtifactAsync( artifacts.ZeroEx, provider, txDefaults, artifacts, migrator.address, ); const _features = await deployBootstrapFeaturesAsync(provider, txDefaults, features); await migrator.initializeZeroEx(owner, zeroEx.address, _features).awaitTransactionSuccessAsync(); return zeroEx; } /** * Addresses of features for a full deployment of the Exchange Proxy. */ export interface FullFeatures extends BootstrapFeatures { transformERC20: string; metaTransactions: string; nativeOrders: string; otcOrders: string; } /** * Artifacts to use when deploying full features. */ export interface FullFeatureArtifacts extends BootstrapFeatureArtifacts { transformERC20: SimpleContractArtifact; metaTransactions: SimpleContractArtifact; nativeOrders: SimpleContractArtifact; feeCollectorController: SimpleContractArtifact; otcOrders: SimpleContractArtifact; } /** * Configuration for deploying full features.. */ export interface FullFeaturesDeployConfig { zeroExAddress: string; wethAddress: string; stakingAddress: string; protocolFeeMultiplier: number; } /** * Configuration options for a full migration of the Exchange Proxy. */ export interface FullMigrationConfig extends FullFeaturesDeployConfig { transformerDeployer?: string; } const DEFAULT_FULL_FEATURES_DEPLOY_CONFIG = { zeroExAddress: NULL_ADDRESS, wethAddress: NULL_ADDRESS, stakingAddress: NULL_ADDRESS, feeCollectorController: NULL_ADDRESS, protocolFeeMultiplier: 70e3, }; const DEFAULT_FULL_FEATURES_ARTIFACTS = { transformERC20: artifacts.TransformERC20Feature, metaTransactions: artifacts.MetaTransactionsFeature, nativeOrders: artifacts.NativeOrdersFeature, feeCollectorController: artifacts.FeeCollectorController, otcOrders: artifacts.OtcOrdersFeature, }; /** * Deploy all the features for a full Exchange Proxy. */ export async function deployFullFeaturesAsync( provider: SupportedProvider, txDefaults: Partial, config: Partial = {}, features: Partial = {}, featureArtifacts: Partial = {}, ): Promise { const _config = { ...DEFAULT_FULL_FEATURES_DEPLOY_CONFIG, ...config }; const _featureArtifacts = { ...DEFAULT_FULL_FEATURES_ARTIFACTS, ...featureArtifacts, }; if (_config.feeCollectorController === NULL_ADDRESS) { _config.feeCollectorController = ( await FeeCollectorControllerContract.deployFrom0xArtifactAsync( _featureArtifacts.feeCollectorController, provider, txDefaults, artifacts, _config.wethAddress, _config.stakingAddress, ) ).address; } return { ...(await deployBootstrapFeaturesAsync(provider, txDefaults)), transformERC20: features.transformERC20 || ( await TransformERC20FeatureContract.deployFrom0xArtifactAsync( _featureArtifacts.transformERC20, provider, txDefaults, artifacts, ) ).address, metaTransactions: features.metaTransactions || ( await MetaTransactionsFeatureContract.deployFrom0xArtifactAsync( _featureArtifacts.metaTransactions, provider, txDefaults, artifacts, _config.zeroExAddress, ) ).address, nativeOrders: features.nativeOrders || ( await NativeOrdersFeatureContract.deployFrom0xArtifactAsync( _featureArtifacts.nativeOrders, provider, txDefaults, artifacts, _config.zeroExAddress, _config.wethAddress, _config.stakingAddress, _config.feeCollectorController, _config.protocolFeeMultiplier, ) ).address, otcOrders: features.otcOrders || ( await OtcOrdersFeatureContract.deployFrom0xArtifactAsync( _featureArtifacts.otcOrders, provider, txDefaults, artifacts, _config.zeroExAddress, _config.wethAddress, ) ).address, }; } /** * Deploy a fully featured instance of the Exchange Proxy. */ export async function fullMigrateAsync( owner: string, provider: SupportedProvider, txDefaults: Partial, features: Partial = {}, config: Partial = {}, featureArtifacts: Partial = {}, ): Promise { const migrator = await FullMigrationContract.deployFrom0xArtifactAsync( artifacts.FullMigration, provider, txDefaults, artifacts, txDefaults.from as string, ); const zeroEx = await ZeroExContract.deployFrom0xArtifactAsync( artifacts.ZeroEx, provider, txDefaults, artifacts, await migrator.getBootstrapper().callAsync(), ); const _config = { ...config, zeroExAddress: zeroEx.address }; const _features = await deployFullFeaturesAsync(provider, txDefaults, _config, features, featureArtifacts); const migrateOpts = { transformerDeployer: txDefaults.from as string, ..._config, }; await migrator.migrateZeroEx(owner, zeroEx.address, _features, migrateOpts).awaitTransactionSuccessAsync(); return new IZeroExContract(zeroEx.address, provider, txDefaults); }