* `@0x/contracts-zero-ex`: Govern `FeeCollector`s through a separate `FeeCollectorController` contract. * `@0x/contracts-integrations`: Fix broken EP protocol fees test. `@0x/contracts-integrations`: Make this package private. * `@0x/contract-addresses`: Update ganache snapshot addresses. * Update contracts/zero-ex/contracts/src/external/FeeCollectorController.sol Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com> * Apply suggestions from code review Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com> * rebase Co-authored-by: Lawrence Forman <me@merklejerk.com> Co-authored-by: mzhu25 <mchl.zhu.96@gmail.com>
280 lines
8.9 KiB
TypeScript
280 lines
8.9 KiB
TypeScript
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 { ZERO_BYTES32 } from './constants';
|
|
import {
|
|
FeeCollectorControllerContract,
|
|
FullMigrationContract,
|
|
InitialMigrationContract,
|
|
IZeroExContract,
|
|
MetaTransactionsFeatureContract,
|
|
NativeOrdersFeatureContract,
|
|
OwnableFeatureContract,
|
|
SignatureValidatorFeatureContract,
|
|
SimpleFunctionRegistryFeatureContract,
|
|
TokenSpenderFeatureContract,
|
|
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<TxData>,
|
|
features: Partial<BootstrapFeatures> = {},
|
|
featureArtifacts: Partial<BootstrapFeatureArtifacts> = {},
|
|
): Promise<BootstrapFeatures> {
|
|
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<TxData>,
|
|
features: Partial<BootstrapFeatures> = {},
|
|
): Promise<ZeroExContract> {
|
|
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 {
|
|
tokenSpender: string;
|
|
transformERC20: string;
|
|
signatureValidator: string;
|
|
metaTransactions: string;
|
|
nativeOrders: string;
|
|
}
|
|
|
|
/**
|
|
* Artifacts to use when deploying full features.
|
|
*/
|
|
export interface FullFeatureArtifacts extends BootstrapFeatureArtifacts {
|
|
tokenSpender: SimpleContractArtifact;
|
|
transformERC20: SimpleContractArtifact;
|
|
signatureValidator: SimpleContractArtifact;
|
|
metaTransactions: SimpleContractArtifact;
|
|
nativeOrders: SimpleContractArtifact;
|
|
feeCollectorController: SimpleContractArtifact;
|
|
}
|
|
|
|
/**
|
|
* Configuration for deploying full features..
|
|
*/
|
|
export interface FullFeaturesDeployConfig {
|
|
zeroExAddress: string;
|
|
wethAddress: string;
|
|
stakingAddress: string;
|
|
protocolFeeMultiplier: number;
|
|
greedyTokensBloomFilter: string;
|
|
}
|
|
|
|
/**
|
|
* 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,
|
|
greedyTokensBloomFilter: ZERO_BYTES32,
|
|
};
|
|
|
|
const DEFAULT_FULL_FEATURES_ARTIFACTS = {
|
|
tokenSpender: artifacts.TokenSpenderFeature,
|
|
transformERC20: artifacts.TransformERC20Feature,
|
|
signatureValidator: artifacts.SignatureValidatorFeature,
|
|
metaTransactions: artifacts.MetaTransactionsFeature,
|
|
nativeOrders: artifacts.NativeOrdersFeature,
|
|
feeCollectorController: artifacts.FeeCollectorController,
|
|
};
|
|
|
|
/**
|
|
* Deploy all the features for a full Exchange Proxy.
|
|
*/
|
|
export async function deployFullFeaturesAsync(
|
|
provider: SupportedProvider,
|
|
txDefaults: Partial<TxData>,
|
|
config: Partial<FullFeaturesDeployConfig> = {},
|
|
features: Partial<FullFeatures> = {},
|
|
featureArtifacts: Partial<FullFeatureArtifacts> = {},
|
|
): Promise<FullFeatures> {
|
|
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)),
|
|
tokenSpender:
|
|
features.tokenSpender ||
|
|
(await TokenSpenderFeatureContract.deployFrom0xArtifactAsync(
|
|
_featureArtifacts.tokenSpender,
|
|
provider,
|
|
txDefaults,
|
|
artifacts,
|
|
)).address,
|
|
transformERC20:
|
|
features.transformERC20 ||
|
|
(await TransformERC20FeatureContract.deployFrom0xArtifactAsync(
|
|
_featureArtifacts.transformERC20,
|
|
provider,
|
|
txDefaults,
|
|
artifacts,
|
|
_config.greedyTokensBloomFilter,
|
|
)).address,
|
|
signatureValidator:
|
|
features.signatureValidator ||
|
|
(await SignatureValidatorFeatureContract.deployFrom0xArtifactAsync(
|
|
_featureArtifacts.signatureValidator,
|
|
provider,
|
|
txDefaults,
|
|
artifacts,
|
|
)).address,
|
|
metaTransactions:
|
|
features.metaTransactions ||
|
|
(await MetaTransactionsFeatureContract.deployFrom0xArtifactAsync(
|
|
_featureArtifacts.metaTransactions,
|
|
provider,
|
|
txDefaults,
|
|
artifacts,
|
|
_config.zeroExAddress,
|
|
_config.greedyTokensBloomFilter,
|
|
)).address,
|
|
nativeOrders:
|
|
features.nativeOrders ||
|
|
(await NativeOrdersFeatureContract.deployFrom0xArtifactAsync(
|
|
_featureArtifacts.nativeOrders,
|
|
provider,
|
|
txDefaults,
|
|
artifacts,
|
|
_config.zeroExAddress,
|
|
_config.wethAddress,
|
|
_config.stakingAddress,
|
|
_config.feeCollectorController,
|
|
_config.protocolFeeMultiplier,
|
|
_config.greedyTokensBloomFilter,
|
|
)).address,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Deploy a fully featured instance of the Exchange Proxy.
|
|
*/
|
|
export async function fullMigrateAsync(
|
|
owner: string,
|
|
provider: SupportedProvider,
|
|
txDefaults: Partial<TxData>,
|
|
features: Partial<FullFeatures> = {},
|
|
config: Partial<FullMigrationConfig> = {},
|
|
featureArtifacts: Partial<FullFeatureArtifacts> = {},
|
|
): Promise<IZeroExContract> {
|
|
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);
|
|
}
|