aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contracts/src')
-rw-r--r--packages/contracts/src/utils/address_utils.ts12
-rw-r--r--packages/contracts/src/utils/balances.ts30
-rw-r--r--packages/contracts/src/utils/constants.ts17
-rw-r--r--packages/contracts/src/utils/erc20_wrapper.ts115
-rw-r--r--packages/contracts/src/utils/erc721_wrapper.ts146
-rw-r--r--packages/contracts/src/utils/order_factory.ts2
-rw-r--r--packages/contracts/src/utils/types.ts27
7 files changed, 296 insertions, 53 deletions
diff --git a/packages/contracts/src/utils/address_utils.ts b/packages/contracts/src/utils/address_utils.ts
new file mode 100644
index 000000000..01a7a6fd4
--- /dev/null
+++ b/packages/contracts/src/utils/address_utils.ts
@@ -0,0 +1,12 @@
+import { ZeroEx } from '0x.js';
+
+import { crypto } from './crypto';
+
+export const addressUtils = {
+ generatePseudoRandomAddress(): string {
+ const randomBigNum = ZeroEx.generatePseudoRandomSalt();
+ const randomBuff = crypto.solSHA3([randomBigNum]);
+ const randomAddress = `0x${randomBuff.slice(0, 20).toString('hex')}`;
+ return randomAddress;
+ },
+};
diff --git a/packages/contracts/src/utils/balances.ts b/packages/contracts/src/utils/balances.ts
deleted file mode 100644
index 40a59e815..000000000
--- a/packages/contracts/src/utils/balances.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { BigNumber } from '@0xproject/utils';
-import * as _ from 'lodash';
-import * as Web3 from 'web3';
-
-import { DummyERC20TokenContract } from '../contract_wrappers/generated/dummy_e_r_c20_token';
-
-import { BalancesByOwner } from './types';
-
-export class Balances {
- private _tokenContractInstances: DummyERC20TokenContract[];
- private _ownerAddresses: string[];
- constructor(tokenContractInstances: DummyERC20TokenContract[], ownerAddresses: string[]) {
- this._tokenContractInstances = tokenContractInstances;
- this._ownerAddresses = ownerAddresses;
- }
- public async getAsync(): Promise<BalancesByOwner> {
- const balancesByOwner: BalancesByOwner = {};
- for (const tokenContractInstance of this._tokenContractInstances) {
- for (const ownerAddress of this._ownerAddresses) {
- let balance = await tokenContractInstance.balanceOf.callAsync(ownerAddress);
- balance = new BigNumber(balance);
- if (_.isUndefined(balancesByOwner[ownerAddress])) {
- balancesByOwner[ownerAddress] = {};
- }
- balancesByOwner[ownerAddress][tokenContractInstance.address] = balance;
- }
- }
- return balancesByOwner;
- }
-}
diff --git a/packages/contracts/src/utils/constants.ts b/packages/contracts/src/utils/constants.ts
index 49872fc59..2c9d7b272 100644
--- a/packages/contracts/src/utils/constants.ts
+++ b/packages/contracts/src/utils/constants.ts
@@ -1,3 +1,5 @@
+import { ZeroEx } from '0x.js';
+import { BigNumber } from '@0xproject/utils';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';
@@ -25,7 +27,18 @@ export const constants = {
MAX_ETHERTOKEN_WITHDRAW_GAS: 43000,
MAX_TOKEN_TRANSFERFROM_GAS: 80000,
MAX_TOKEN_APPROVE_GAS: 60000,
- DUMMY_TOKEN_ARGS: [DUMMY_TOKEN_NAME, DUMMY_TOKEN_SYMBOL, DUMMY_TOKEN_DECIMALS, DUMMY_TOKEN_TOTAL_SUPPLY],
- DUMMY_ERC721TOKEN_ARGS: [DUMMY_TOKEN_NAME, DUMMY_TOKEN_SYMBOL],
+ DUMMY_ERC20_TOKEN_ARGS: [DUMMY_TOKEN_NAME, DUMMY_TOKEN_SYMBOL, DUMMY_TOKEN_DECIMALS, DUMMY_TOKEN_TOTAL_SUPPLY],
+ DUMMY_ERC721_TOKEN_ARGS: [DUMMY_TOKEN_NAME, DUMMY_TOKEN_SYMBOL],
+ NUM_DUMMY_ERC20_TO_DEPLOY: 3,
+ NUM_DUMMY_ERC721_TO_DEPLOY: 1,
+ NUM_ERC721_TOKENS_TO_MINT: 2,
TESTRPC_PRIVATE_KEYS: _.map(TESTRPC_PRIVATE_KEYS_STRINGS, privateKeyString => ethUtil.toBuffer(privateKeyString)),
+ INITIAL_ERC20_BALANCE: ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18),
+ INITIAL_ERC20_ALLOWANCE: ZeroEx.toBaseUnitAmount(new BigNumber(10000), 18),
+ STATIC_ORDER_PARAMS: {
+ makerAssetAmount: ZeroEx.toBaseUnitAmount(new BigNumber(100), 18),
+ takerAssetAmount: ZeroEx.toBaseUnitAmount(new BigNumber(200), 18),
+ makerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+ takerFee: ZeroEx.toBaseUnitAmount(new BigNumber(1), 18),
+ },
};
diff --git a/packages/contracts/src/utils/erc20_wrapper.ts b/packages/contracts/src/utils/erc20_wrapper.ts
new file mode 100644
index 000000000..c2effb617
--- /dev/null
+++ b/packages/contracts/src/utils/erc20_wrapper.ts
@@ -0,0 +1,115 @@
+import { Deployer } from '@0xproject/deployer';
+import { Provider } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import * as _ from 'lodash';
+
+import { DummyERC20TokenContract } from '../contract_wrappers/generated/dummy_e_r_c20_token';
+import { ERC20ProxyContract } from '../contract_wrappers/generated/e_r_c20_proxy';
+
+import { constants } from './constants';
+import { ContractName, ERC20BalancesByOwner } from './types';
+
+export class ERC20Wrapper {
+ private _tokenOwnerAddresses: string[];
+ private _contractOwnerAddress: string;
+ private _deployer: Deployer;
+ private _provider: Provider;
+ private _dummyTokenContracts?: DummyERC20TokenContract[];
+ private _proxyContract?: ERC20ProxyContract;
+ constructor(deployer: Deployer, provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
+ this._deployer = deployer;
+ this._provider = provider;
+ this._tokenOwnerAddresses = tokenOwnerAddresses;
+ this._contractOwnerAddress = contractOwnerAddress;
+ }
+ public async deployDummyTokensAsync(): Promise<DummyERC20TokenContract[]> {
+ const tokenContractInstances = await Promise.all(
+ _.times(constants.NUM_DUMMY_ERC20_TO_DEPLOY, () =>
+ this._deployer.deployAsync(ContractName.DummyERC20Token, constants.DUMMY_ERC20_TOKEN_ARGS),
+ ),
+ );
+ this._dummyTokenContracts = _.map(
+ tokenContractInstances,
+ tokenContractInstance =>
+ new DummyERC20TokenContract(tokenContractInstance.abi, tokenContractInstance.address, this._provider),
+ );
+ return this._dummyTokenContracts;
+ }
+ public async deployProxyAsync(): Promise<ERC20ProxyContract> {
+ const proxyContractInstance = await this._deployer.deployAsync(ContractName.ERC20Proxy);
+ this._proxyContract = new ERC20ProxyContract(
+ proxyContractInstance.abi,
+ proxyContractInstance.address,
+ this._provider,
+ );
+ return this._proxyContract;
+ }
+ public async setBalancesAndAllowancesAsync() {
+ this._validateDummyTokenContractsExistOrThrow();
+ this._validateProxyContractExistsOrThrow();
+ const setBalancePromises: Array<Promise<string>> = [];
+ const setAllowancePromises: Array<Promise<string>> = [];
+ _.forEach(this._dummyTokenContracts, dummyTokenContract => {
+ _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
+ setBalancePromises.push(
+ dummyTokenContract.setBalance.sendTransactionAsync(
+ tokenOwnerAddress,
+ constants.INITIAL_ERC20_BALANCE,
+ { from: this._contractOwnerAddress },
+ ),
+ );
+ setAllowancePromises.push(
+ dummyTokenContract.approve.sendTransactionAsync(
+ (this._proxyContract as ERC20ProxyContract).address,
+ constants.INITIAL_ERC20_ALLOWANCE,
+ { from: tokenOwnerAddress },
+ ),
+ );
+ });
+ });
+ await Promise.all([...setBalancePromises, ...setAllowancePromises]);
+ }
+ public async getBalancesAsync(): Promise<ERC20BalancesByOwner> {
+ this._validateDummyTokenContractsExistOrThrow();
+ const balancesByOwner: ERC20BalancesByOwner = {};
+ const balancePromises: Array<Promise<BigNumber>> = [];
+ const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = [];
+ _.forEach(this._dummyTokenContracts, dummyTokenContract => {
+ _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
+ balancePromises.push(dummyTokenContract.balanceOf.callAsync(tokenOwnerAddress));
+ balanceInfo.push({
+ tokenOwnerAddress,
+ tokenAddress: dummyTokenContract.address,
+ });
+ });
+ });
+ const balances = await Promise.all(balancePromises);
+ _.forEach(balances, (balance, balanceIndex) => {
+ const tokenAddress = balanceInfo[balanceIndex].tokenAddress;
+ const tokenOwnerAddress = balanceInfo[balanceIndex].tokenOwnerAddress;
+ if (_.isUndefined(balancesByOwner[tokenOwnerAddress])) {
+ balancesByOwner[tokenOwnerAddress] = {};
+ }
+ const wrappedBalance = new BigNumber(balance);
+ balancesByOwner[tokenOwnerAddress][tokenAddress] = wrappedBalance;
+ });
+ return balancesByOwner;
+ }
+ public getTokenOwnerAddresses(): string[] {
+ return this._tokenOwnerAddresses;
+ }
+ public getTokenAddresses(): string[] {
+ const tokenAddresses = _.map(this._dummyTokenContracts, dummyTokenContract => dummyTokenContract.address);
+ return tokenAddresses;
+ }
+ private _validateDummyTokenContractsExistOrThrow() {
+ if (_.isUndefined(this._dummyTokenContracts)) {
+ throw new Error('Dummy ERC20 tokens not yet deployed, please call "deployDummyTokensAsync"');
+ }
+ }
+ private _validateProxyContractExistsOrThrow() {
+ if (_.isUndefined(this._proxyContract)) {
+ throw new Error('ERC20 proxy contract not yet deployed, please call "deployProxyAsync"');
+ }
+ }
+}
diff --git a/packages/contracts/src/utils/erc721_wrapper.ts b/packages/contracts/src/utils/erc721_wrapper.ts
new file mode 100644
index 000000000..b78b76b51
--- /dev/null
+++ b/packages/contracts/src/utils/erc721_wrapper.ts
@@ -0,0 +1,146 @@
+import { ZeroEx } from '0x.js';
+import { Deployer } from '@0xproject/deployer';
+import { Provider } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import * as _ from 'lodash';
+
+import { DummyERC721TokenContract } from '../contract_wrappers/generated/dummy_e_r_c721_token';
+import { ERC721ProxyContract } from '../contract_wrappers/generated/e_r_c721_proxy';
+
+import { constants } from './constants';
+import { ContractName, ERC721TokenIdsByOwner } from './types';
+
+export class ERC721Wrapper {
+ private _tokenOwnerAddresses: string[];
+ private _contractOwnerAddress: string;
+ private _deployer: Deployer;
+ private _provider: Provider;
+ private _dummyTokenContracts?: DummyERC721TokenContract[];
+ private _proxyContract?: ERC721ProxyContract;
+ private _initialTokenIdsByOwner: ERC721TokenIdsByOwner = {};
+ constructor(deployer: Deployer, provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) {
+ this._deployer = deployer;
+ this._provider = provider;
+ this._tokenOwnerAddresses = tokenOwnerAddresses;
+ this._contractOwnerAddress = contractOwnerAddress;
+ }
+ public async deployDummyTokensAsync(): Promise<DummyERC721TokenContract[]> {
+ const tokenContractInstances = await Promise.all(
+ _.times(constants.NUM_DUMMY_ERC721_TO_DEPLOY, () =>
+ this._deployer.deployAsync(ContractName.DummyERC721Token, constants.DUMMY_ERC721_TOKEN_ARGS),
+ ),
+ );
+ this._dummyTokenContracts = _.map(
+ tokenContractInstances,
+ tokenContractInstance =>
+ new DummyERC721TokenContract(tokenContractInstance.abi, tokenContractInstance.address, this._provider),
+ );
+ return this._dummyTokenContracts;
+ }
+ public async deployProxyAsync(): Promise<ERC721ProxyContract> {
+ const proxyContractInstance = await this._deployer.deployAsync(ContractName.ERC721Proxy);
+ this._proxyContract = new ERC721ProxyContract(
+ proxyContractInstance.abi,
+ proxyContractInstance.address,
+ this._provider,
+ );
+ return this._proxyContract;
+ }
+ public async setBalancesAndAllowancesAsync() {
+ this._validateDummyTokenContractsExistOrThrow();
+ this._validateProxyContractExistsOrThrow();
+ const setBalancePromises: Array<Promise<string>> = [];
+ const setAllowancePromises: Array<Promise<string>> = [];
+ this._initialTokenIdsByOwner = {};
+ _.forEach(this._dummyTokenContracts, dummyTokenContract => {
+ _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
+ _.forEach(_.range(constants.NUM_ERC721_TOKENS_TO_MINT), () => {
+ const tokenId = ZeroEx.generatePseudoRandomSalt();
+ setBalancePromises.push(
+ dummyTokenContract.mint.sendTransactionAsync(tokenOwnerAddress, tokenId, {
+ from: this._contractOwnerAddress,
+ }),
+ );
+ if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress])) {
+ this._initialTokenIdsByOwner[tokenOwnerAddress] = {
+ [dummyTokenContract.address]: [],
+ };
+ }
+ if (_.isUndefined(this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address])) {
+ this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address] = [];
+ }
+ this._initialTokenIdsByOwner[tokenOwnerAddress][dummyTokenContract.address].push(tokenId);
+ });
+ const shouldApprove = true;
+ setAllowancePromises.push(
+ dummyTokenContract.setApprovalForAll.sendTransactionAsync(
+ (this._proxyContract as ERC721ProxyContract).address,
+ shouldApprove,
+ { from: tokenOwnerAddress },
+ ),
+ );
+ });
+ });
+ await Promise.all([...setBalancePromises, ...setAllowancePromises]);
+ }
+ public async getBalancesAsync(): Promise<ERC721TokenIdsByOwner> {
+ this._validateDummyTokenContractsExistOrThrow();
+ this._validateBalancesAndAllowancesSetOrThrow();
+ const tokenIdsByOwner: ERC721TokenIdsByOwner = {};
+ const tokenOwnerPromises: Array<Promise<string>> = [];
+ const tokenInfo: Array<{ tokenId: BigNumber; tokenAddress: string }> = [];
+ _.forEach(this._dummyTokenContracts, dummyTokenContract => {
+ _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => {
+ const initialTokenOwnerIds = this._initialTokenIdsByOwner[tokenOwnerAddress][
+ dummyTokenContract.address
+ ];
+ _.forEach(initialTokenOwnerIds, tokenId => {
+ tokenOwnerPromises.push(dummyTokenContract.ownerOf.callAsync(tokenId));
+ tokenInfo.push({
+ tokenId,
+ tokenAddress: dummyTokenContract.address,
+ });
+ });
+ });
+ });
+ const tokenOwnerAddresses = await Promise.all(tokenOwnerPromises);
+ _.forEach(tokenOwnerAddresses, (tokenOwnerAddress, ownerIndex) => {
+ const tokenAddress = tokenInfo[ownerIndex].tokenAddress;
+ const tokenId = tokenInfo[ownerIndex].tokenId;
+ if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress])) {
+ tokenIdsByOwner[tokenOwnerAddress] = {
+ [tokenAddress]: [],
+ };
+ }
+ if (_.isUndefined(tokenIdsByOwner[tokenOwnerAddress][tokenAddress])) {
+ tokenIdsByOwner[tokenOwnerAddress][tokenAddress] = [];
+ }
+ tokenIdsByOwner[tokenOwnerAddress][tokenAddress].push(tokenId);
+ });
+ return tokenIdsByOwner;
+ }
+ public getTokenOwnerAddresses(): string[] {
+ return this._tokenOwnerAddresses;
+ }
+ public getTokenAddresses(): string[] {
+ const tokenAddresses = _.map(this._dummyTokenContracts, dummyTokenContract => dummyTokenContract.address);
+ return tokenAddresses;
+ }
+ private _validateDummyTokenContractsExistOrThrow() {
+ if (_.isUndefined(this._dummyTokenContracts)) {
+ throw new Error('Dummy ERC721 tokens not yet deployed, please call "deployDummyTokensAsync"');
+ }
+ }
+ private _validateProxyContractExistsOrThrow() {
+ if (_.isUndefined(this._proxyContract)) {
+ throw new Error('ERC721 proxy contract not yet deployed, please call "deployProxyAsync"');
+ }
+ }
+ private _validateBalancesAndAllowancesSetOrThrow() {
+ if (_.keys(this._initialTokenIdsByOwner).length === 0) {
+ throw new Error(
+ 'Dummy ERC721 balances and allowances not yet set, please call "setBalancesAndAllowancesAsync"',
+ );
+ }
+ }
+}
diff --git a/packages/contracts/src/utils/order_factory.ts b/packages/contracts/src/utils/order_factory.ts
index bdf5f9abe..08853054d 100644
--- a/packages/contracts/src/utils/order_factory.ts
+++ b/packages/contracts/src/utils/order_factory.ts
@@ -4,7 +4,7 @@ import * as _ from 'lodash';
import { orderUtils } from './order_utils';
import { signingUtils } from './signing_utils';
-import { DefaultOrderParams, SignatureType, SignedOrder, UnsignedOrder } from './types';
+import { SignatureType, SignedOrder, UnsignedOrder } from './types';
export class OrderFactory {
private _defaultOrderParams: Partial<UnsignedOrder>;
diff --git a/packages/contracts/src/utils/types.ts b/packages/contracts/src/utils/types.ts
index 8bc9641fc..1e3cd5b9a 100644
--- a/packages/contracts/src/utils/types.ts
+++ b/packages/contracts/src/utils/types.ts
@@ -1,12 +1,18 @@
import { AbiDefinition, ContractAbi } from '@0xproject/types';
import { BigNumber } from '@0xproject/utils';
-export interface BalancesByOwner {
+export interface ERC20BalancesByOwner {
[ownerAddress: string]: {
[tokenAddress: string]: BigNumber;
};
}
+export interface ERC721TokenIdsByOwner {
+ [ownerAddress: string]: {
+ [tokenAddress: string]: BigNumber[];
+ };
+}
+
export interface SubmissionContractEventArgs {
transactionId: BigNumber;
}
@@ -43,20 +49,6 @@ export enum AssetProxyId {
ERC721,
}
-export interface DefaultOrderParams {
- exchangeAddress: string;
- makerAddress: string;
- feeRecipientAddress: string;
- makerAssetAddress: string;
- takerAssetAddress: string;
- makerAssetAmount: BigNumber;
- takerAssetAmount: BigNumber;
- makerFee: BigNumber;
- takerFee: BigNumber;
- makerAssetData: string;
- takerAssetData: string;
-}
-
export interface TransactionDataParams {
name: string;
abi: AbiDefinition[];
@@ -82,11 +74,6 @@ export interface Token {
swarmHash: string;
}
-export interface TokenInfoByNetwork {
- development: Token[];
- live: Token[];
-}
-
export enum ExchangeContractErrs {
ERROR_ORDER_EXPIRED,
ERROR_ORDER_FULLY_FILLED,