Merge branch 'v2-prototype' into v2-contract-wrappers-WIP

This commit is contained in:
Leonid Logvinov
2018-07-05 15:04:01 +02:00
278 changed files with 8510 additions and 2798 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -13,25 +13,35 @@
"pre_build": "run-s copy_artifacts generate_contract_wrappers",
"copy_artifacts": "copyfiles 'artifacts/**/*' ./lib",
"clean": "shx rm -rf lib src/contract_wrappers",
"lint": "tslint --project . --exclude **/src/v2/contract_wrappers/**/* --exclude **/src/v1/contract_wrappers/**/*",
"lint":
"tslint --project . --exclude **/src/v2/contract_wrappers/**/* --exclude **/src/v1/contract_wrappers/**/*",
"migrate:v1": "run-s build compile:v1 script:migrate:v1",
"migrate:v2": "run-s build compile:v2 script:migrate:v2",
"migrate:v2-beta-testnet": "run-s build compile:v2-beta-testnet script:migrate:v2-beta-testnet",
"script:migrate:v1": "node ./lib/migrate.js --contracts-version 1.0.0",
"script:migrate:v2": "node ./lib/migrate.js --contracts-version 2.0.0",
"script:migrate:v2-beta-testnet": "node ./lib/migrate.js --contracts-version 2.0.0-beta-testnet",
"generate_contract_wrappers": "run-p generate_contract_wrappers:*",
"generate_contract_wrappers:v1":
"abi-gen --abis ${npm_package_config_abis_v1} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/v1/contract_wrappers --backend ethers",
"abi-gen --abis ${npm_package_config_abis_v1} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/1.0.0/contract_wrappers --backend ethers",
"generate_contract_wrappers:v2":
"abi-gen --abis ${npm_package_config_abis_v2} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/v2/contract_wrappers --backend ethers",
"compile:v1": "sol-compiler --artifacts-dir artifacts/1.0.0 --contracts Exchange_v1,DummyERC20Token,ZRXToken,WETH9,TokenTransferProxy_v1,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,TokenRegistry",
"compile:v2": "sol-compiler --artifacts-dir artifacts/2.0.0 --contracts AssetProxyOwner,ERC20Token,DummyERC20Token,ERC721Token,DummyERC721Token,ERC20Proxy,ERC721Proxy,Exchange,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,ZRXToken,WETH9,IWallet,IValidator"
"abi-gen --abis ${npm_package_config_abis_v2} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/2.0.0/contract_wrappers --backend ethers",
"generate_contract_wrappers:v2-beta-testnet":
"abi-gen --abis ${npm_package_config_abis_v2BetaTestnet} --template ../contract_templates/contract.handlebars --partials '../contract_templates/partials/**/*.handlebars' --output src/2.0.0-beta-testnet/contract_wrappers --backend ethers",
"compile:v1":
"sol-compiler --artifacts-dir artifacts/1.0.0 --contracts Exchange_v1,DummyERC20Token,ZRXToken,WETH9,TokenTransferProxy_v1,MultiSigWallet,MultiSigWalletWithTimeLock,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,TokenRegistry",
"compile:v2":
"sol-compiler --artifacts-dir artifacts/2.0.0 --contracts ERC20Token,DummyERC20Token,ERC721Token,DummyERC721Token,ERC20Proxy,ERC721Proxy,Exchange,MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress,ZRXToken,WETH9,IWallet,IValidator",
"compile:v2-beta-testnet":
"sol-compiler --artifacts-dir artifacts/2.0.0-beta-testnet --contracts AssetProxyOwner,ERC20Proxy,ERC721Proxy,Exchange"
},
"config": {
"abis": {
"v1":
"artifacts/1.0.0/@(DummyERC20Token|TokenTransferProxy_v1|Exchange_v1|TokenRegistry|MultiSigWallet|MultiSigWalletWithTimeLock|MultiSigWalletWithTimeLockExceptRemoveAuthorizedAddress|TokenRegistry|ZRXToken|WETH9).json",
"v2":
"artifacts/2.0.0/@(ERC20Token|DummyERC20Token|ERC721Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|AssetProxyOwner|ZRXToken|WETH9|IWallet|IValidator).json"
"artifacts/2.0.0/@(ERC20Token|DummyERC20Token|ERC721Token|DummyERC721Token|ERC20Proxy|ERC721Proxy|Exchange|AssetProxyOwner|ZRXToken|WETH9|IWallet|IValidator).json",
"v2BetaTestnet": "artifacts/2.0.0-beta-testnet/@(ERC20Proxy|ERC721Proxy|Exchange|AssetProxyOwner).json"
}
},
"license": "Apache-2.0",
@@ -52,12 +62,18 @@
"@0xproject/base-contract": "^0.3.4",
"@0xproject/order-utils": "^1.0.0",
"@0xproject/sol-compiler": "^0.5.2",
"@0xproject/typescript-typings": "^0.4.1",
"@0xproject/subproviders": "^0.10.4",
"@0xproject/typescript-typings": "^0.4.2",
"@0xproject/utils": "^0.7.1",
"@0xproject/web3-wrapper": "^0.7.1",
"ethereum-types": "^0.0.1",
"@ledgerhq/hw-app-eth": "^4.3.0",
"ethereum-types": "^0.0.2",
"ethers": "3.0.22",
"lodash": "^4.17.4"
"lodash": "^4.17.4",
"web3-provider-engine": "14.0.6"
},
"optionalDependencies": {
"@ledgerhq/hw-transport-node-hid": "^4.3.0"
},
"publishConfig": {
"access": "public"

View File

@@ -2,7 +2,7 @@ import { BigNumber, NULL_BYTES } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider, TxData } from 'ethereum-types';
import { ArtifactWriter } from '../artifact_writer';
import { ArtifactWriter } from '../utils/artifact_writer';
import { erc20TokenInfo } from '../utils/token_info';
import { artifacts } from './artifacts';

View File

@@ -0,0 +1,13 @@
import { ContractArtifact } from '@0xproject/sol-compiler';
import * as AssetProxyOwner from '../../artifacts/2.0.0-beta-testnet/AssetProxyOwner.json';
import * as ERC20Proxy from '../../artifacts/2.0.0-beta-testnet/ERC20Proxy.json';
import * as ERC721Proxy from '../../artifacts/2.0.0-beta-testnet/ERC721Proxy.json';
import * as Exchange from '../../artifacts/2.0.0-beta-testnet/Exchange.json';
export const artifacts = {
AssetProxyOwner: (AssetProxyOwner as any) as ContractArtifact,
Exchange: (Exchange as any) as ContractArtifact,
ERC20Proxy: (ERC20Proxy as any) as ContractArtifact,
ERC721Proxy: (ERC721Proxy as any) as ContractArtifact,
};

View File

@@ -0,0 +1,105 @@
import { logUtils } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider, TxData } from 'ethereum-types';
import { ArtifactWriter } from '../utils/artifact_writer';
import { constants } from '../utils/constants';
import { artifacts } from './artifacts';
import { AssetProxyOwnerContract } from './contract_wrappers/asset_proxy_owner';
import { ERC20ProxyContract } from './contract_wrappers/e_r_c20_proxy';
import { ERC721ProxyContract } from './contract_wrappers/e_r_c721_proxy';
import { ExchangeContract } from './contract_wrappers/exchange';
/**
* Custom migrations should be defined in this function. This will be called with the CLI 'migrate:v2-beta-testnet' command.
* Migrations could be written to run in parallel, but if you want contract addresses to be created deterministically,
* the migration should be written to run synchronously.
* @param provider Web3 provider instance.
* @param artifactsDir The directory with compiler artifact files.
* @param txDefaults Default transaction values to use when deploying contracts.
*/
export const runV2TestnetMigrationsAsync = async (
provider: Provider,
artifactsDir: string,
txDefaults: Partial<TxData>,
) => {
const web3Wrapper = new Web3Wrapper(provider);
const networkId = await web3Wrapper.getNetworkIdAsync();
const artifactsWriter = new ArtifactWriter(artifactsDir, networkId);
// Deploy AssetProxies
const erc20proxy = await ERC20ProxyContract.deployFrom0xArtifactAsync(artifacts.ERC20Proxy, provider, txDefaults);
artifactsWriter.saveArtifact(erc20proxy);
const erc721proxy = await ERC721ProxyContract.deployFrom0xArtifactAsync(
artifacts.ERC721Proxy,
provider,
txDefaults,
);
artifactsWriter.saveArtifact(erc721proxy);
// Deploy Exchange
const exchange = await ExchangeContract.deployFrom0xArtifactAsync(artifacts.Exchange, provider, txDefaults);
artifactsWriter.saveArtifact(exchange);
let txHash;
// Register AssetProxies in Exchange
const oldAssetProxy = constants.NULL_ADDRESS;
txHash = await exchange.registerAssetProxy.sendTransactionAsync(
constants.ERC20_PROXY_ID,
erc20proxy.address,
oldAssetProxy,
);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Registering ERC20Proxy');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
txHash = await exchange.registerAssetProxy.sendTransactionAsync(
constants.ERC721_PROXY_ID,
erc721proxy.address,
oldAssetProxy,
);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Registering ERC721Proxy');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
// Deploy AssetProxyOwner
const assetProxyOwner = await AssetProxyOwnerContract.deployFrom0xArtifactAsync(
artifacts.AssetProxyOwner,
provider,
txDefaults,
constants.ASSET_PROXY_OWNER_OWNERS,
[erc20proxy.address, erc721proxy.address],
constants.ASSET_PROXY_OWNER_CONFIRMATIONS,
constants.ASSET_PROXY_OWNER_TIMELOCK,
);
artifactsWriter.saveArtifact(assetProxyOwner);
// Authorize Exchange contracts to call AssetProxies
txHash = await erc20proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Authorizing Exchange on ERC20Proxy');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
txHash = await erc721proxy.addAuthorizedAddress.sendTransactionAsync(exchange.address);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Authorizing Exchange on ERC721Proxy');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
// Transfer ownership of AssetProxies and Exchange to AssetProxyOwner
txHash = await erc20proxy.transferOwnership.sendTransactionAsync(assetProxyOwner.address);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Transferring ownership of ERC20Proxy');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
txHash = await erc721proxy.transferOwnership.sendTransactionAsync(assetProxyOwner.address);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Transferring ownership of ERC721Proxy');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
txHash = await exchange.transferOwnership.sendTransactionAsync(assetProxyOwner.address);
logUtils.log(`transactionHash: ${txHash}`);
logUtils.log('Transferring ownership of Exchange');
await web3Wrapper.awaitTransactionSuccessAsync(txHash);
};

View File

@@ -1,9 +1,9 @@
import { assetProxyUtils, constants } from '@0xproject/order-utils';
import { assetProxyUtils } from '@0xproject/order-utils';
import { BigNumber } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider, TxData } from 'ethereum-types';
import { ArtifactWriter } from '../artifact_writer';
import { ArtifactWriter } from '../utils/artifact_writer';
import { erc20TokenInfo, erc721TokenInfo } from '../utils/token_info';
import { artifacts } from './artifacts';
@@ -96,16 +96,11 @@ export const runV2MigrationsAsync = async (provider: Provider, artifactsDir: str
);
// Register the Asset Proxies to the Exchange
// HACK: These are exposed in the types package but migrations currently uses an older version
// but we can pull the asset data id from the proxies
const erc20ProxyId = await erc20proxy.getProxyId.callAsync();
const erc721ProxyId = await erc721proxy.getProxyId.callAsync();
const oldAddress = constants.NULL_ADDRESS;
await web3Wrapper.awaitTransactionSuccessAsync(
await exchange.registerAssetProxy.sendTransactionAsync(erc20ProxyId, erc20proxy.address, oldAddress),
await exchange.registerAssetProxy.sendTransactionAsync(erc20proxy.address),
);
await web3Wrapper.awaitTransactionSuccessAsync(
await exchange.registerAssetProxy.sendTransactionAsync(erc721ProxyId, erc721proxy.address, oldAddress),
await exchange.registerAssetProxy.sendTransactionAsync(erc721proxy.address),
);
// Dummy ERC20 tokens

View File

@@ -1,2 +1,3 @@
export { runV1MigrationsAsync } from './v1/migration';
export { runV2MigrationsAsync } from './v2/migration';
export { runV1MigrationsAsync } from './1.0.0/migration';
export { runV2MigrationsAsync } from './2.0.0/migration';
export { runV2TestnetMigrationsAsync } from './2.0.0-beta-testnet/migration';

View File

@@ -1,30 +1,58 @@
#!/usr/bin/env node
import { devConstants, web3Factory } from '@0xproject/dev-utils';
import { logUtils } from '@0xproject/utils';
import { Web3Wrapper } from '@0xproject/web3-wrapper';
import { Provider } from 'ethereum-types';
import * as yargs from 'yargs';
import { runV1MigrationsAsync } from './v1/migration';
import { runV2MigrationsAsync } from './v2/migration';
import { runV1MigrationsAsync } from './1.0.0/migration';
import { runV2TestnetMigrationsAsync } from './2.0.0-beta-testnet/migration';
import { runV2MigrationsAsync } from './2.0.0/migration';
import { providerFactory } from './utils/provider_factory';
enum ContractVersions {
V1 = '1.0.0',
V2 = '2.0.0',
V2Testnet = '2.0.0-beta-testnet',
}
const args = yargs.argv;
(async () => {
const txDefaults = {
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
const providerConfigs = { shouldUseInProcessGanache: false };
const provider: Provider = web3Factory.getRpcProvider(providerConfigs);
const contractsVersion = args.contractsVersion;
const artifactsDir = `artifacts/${contractsVersion}`;
if (contractsVersion === ContractVersions.V1) {
await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
} else {
await runV2MigrationsAsync(provider, artifactsDir, txDefaults);
let providerConfigs;
let provider: Provider;
let txDefaults;
switch (contractsVersion) {
case ContractVersions.V1:
providerConfigs = { shouldUseInProcessGanache: false };
provider = web3Factory.getRpcProvider(providerConfigs);
txDefaults = {
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
await runV1MigrationsAsync(provider, artifactsDir, txDefaults);
break;
case ContractVersions.V2:
providerConfigs = { shouldUseInProcessGanache: false };
provider = web3Factory.getRpcProvider(providerConfigs);
txDefaults = {
from: devConstants.TESTRPC_FIRST_ADDRESS,
};
await runV2MigrationsAsync(provider, artifactsDir, txDefaults);
break;
case ContractVersions.V2Testnet:
provider = await providerFactory.getLedgerProviderAsync();
const web3Wrapper = new Web3Wrapper(provider);
const accounts = await web3Wrapper.getAvailableAddressesAsync();
txDefaults = {
from: accounts[0],
gas: devConstants.GAS_LIMIT,
};
await runV2TestnetMigrationsAsync(provider, artifactsDir, txDefaults);
break;
default:
throw new Error(`Unsupported contract version: ${contractsVersion}`);
}
process.exit(0);
})().catch(err => {

View File

@@ -0,0 +1,16 @@
import { BigNumber } from '@0xproject/utils';
export const constants = {
ASSET_PROXY_OWNER_OWNERS: [
'0x9df8137872ac09a8fee71d0da5c7539923fb9bf0',
'0xcf34d44db312d188789f43a63d11cf2bebb4da15',
'0x73fd50f2a6beac9cdac9fe87ef68a18edc415831',
],
ASSET_PROXY_OWNER_TIMELOCK: new BigNumber(0),
ASSET_PROXY_OWNER_CONFIRMATIONS: new BigNumber(1),
ERC20_PROXY_ID: '0xf47261b0',
ERC721_PROXY_ID: '0x08e937fa',
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
RPC_URL: 'http://localhost:8545',
KOVAN_NETWORK_ID: 42,
};

View File

@@ -0,0 +1,33 @@
import { LedgerEthereumClient, LedgerSubprovider } from '@0xproject/subproviders';
import Eth from '@ledgerhq/hw-app-eth';
// tslint:disable:no-implicit-dependencies
import TransportNodeHid from '@ledgerhq/hw-transport-node-hid';
import { Provider } from 'ethereum-types';
import ProviderEngine = require('web3-provider-engine');
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
import { constants } from './constants';
async function ledgerEthereumNodeJsClientFactoryAsync(): Promise<LedgerEthereumClient> {
const ledgerConnection = await TransportNodeHid.create();
const ledgerEthClient = new Eth(ledgerConnection);
return ledgerEthClient;
}
export const providerFactory = {
async getLedgerProviderAsync(): Promise<Provider> {
const provider = new ProviderEngine();
const ledgerWalletConfigs = {
networkId: constants.KOVAN_NETWORK_ID,
ledgerEthereumClientFactoryAsync: ledgerEthereumNodeJsClientFactoryAsync,
};
const ledgerSubprovider = new LedgerSubprovider(ledgerWalletConfigs);
provider.addProvider(ledgerSubprovider);
provider.addProvider(
new RpcSubprovider({
rpcUrl: constants.RPC_URL,
}),
);
provider.start();
return provider;
},
};