From 1f968fa4fdb260f647c06a4cf690792ff7bc45fd Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Sat, 21 Apr 2018 21:42:36 -0700 Subject: Add ERC20Wrapper --- packages/contracts/src/utils/balances.ts | 30 ------- packages/contracts/src/utils/constants.ts | 15 +++- packages/contracts/src/utils/erc20_wrapper.ts | 114 ++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 32 deletions(-) delete mode 100644 packages/contracts/src/utils/balances.ts create mode 100644 packages/contracts/src/utils/erc20_wrapper.ts 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 { - 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..9662a5c27 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,16 @@ 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_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..950b20c99 --- /dev/null +++ b/packages/contracts/src/utils/erc20_wrapper.ts @@ -0,0 +1,114 @@ +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 _dummyERC20TokenContracts?: DummyERC20TokenContract[]; + private _erc20ProxyContract?: ERC20ProxyContract; + constructor(deployer: Deployer, provider: Provider, tokenOwnerAddresses: string[], contractOwnerAddress: string) { + this._deployer = deployer; + this._provider = provider; + this._tokenOwnerAddresses = tokenOwnerAddresses; + this._contractOwnerAddress = contractOwnerAddress; + } + public async deployDummyERC20TokensAsync(): Promise { + const tokenContractInstances = await Promise.all( + _.map(this._tokenOwnerAddresses, tokenOwnerAddress => + this._deployer.deployAsync(ContractName.DummyERC20Token, constants.DUMMY_ERC20_TOKEN_ARGS), + ), + ); + this._dummyERC20TokenContracts = _.map( + tokenContractInstances, + tokenContractInstance => + new DummyERC20TokenContract(tokenContractInstance.abi, tokenContractInstance.address, this._provider), + ); + return this._dummyERC20TokenContracts; + } + public async deployERC20ProxyAsync(): Promise { + const proxyContractInstance = await this._deployer.deployAsync(ContractName.ERC20Proxy); + this._erc20ProxyContract = new ERC20ProxyContract( + proxyContractInstance.abi, + proxyContractInstance.address, + this._provider, + ); + return this._erc20ProxyContract; + } + public async setBalancesAndAllowancesAsync() { + if (_.isUndefined(this._dummyERC20TokenContracts)) { + throw new Error('Dummy ERC20 tokens not yet deployed, please call "deployDummyERC20TokensAsync"'); + } + if (_.isUndefined(this._erc20ProxyContract)) { + throw new Error('ERC20 proxy contract not yet deployed, please call "deployERC20ProxyAsync"'); + } + const setBalancePromises: any[] = []; + const setAllowancePromises: any[] = []; + _.forEach(this._dummyERC20TokenContracts, dummyERC20TokenContract => { + _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => { + setBalancePromises.push( + dummyERC20TokenContract.setBalance.sendTransactionAsync( + tokenOwnerAddress, + constants.INITIAL_ERC20_BALANCE, + { from: this._contractOwnerAddress }, + ), + ); + setAllowancePromises.push( + dummyERC20TokenContract.approve.sendTransactionAsync( + (this._erc20ProxyContract as ERC20ProxyContract).address, + constants.INITIAL_ERC20_ALLOWANCE, + { from: tokenOwnerAddress }, + ), + ); + }); + }); + await Promise.all([...setBalancePromises, ...setAllowancePromises]); + } + public async getBalancesAsync(): Promise { + if (_.isUndefined(this._dummyERC20TokenContracts)) { + throw new Error('Dummy ERC20 tokens not yet deployed, please call "deployDummyTokensAsync"'); + } + const balancesByOwner: ERC20BalancesByOwner = {}; + const balancePromises: any[] = []; + const balanceInfo: Array<{ tokenOwnerAddress: string; tokenAddress: string }> = []; + _.forEach(this._dummyERC20TokenContracts, dummyERC20TokenContract => { + _.forEach(this._tokenOwnerAddresses, tokenOwnerAddress => { + balancePromises.push(dummyERC20TokenContract.balanceOf.callAsync(tokenOwnerAddress)); + balanceInfo.push({ + tokenOwnerAddress, + tokenAddress: dummyERC20TokenContract.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._dummyERC20TokenContracts, + dummyERC20TokenContract => dummyERC20TokenContract.address, + ); + return tokenAddresses; + } +} -- cgit v1.2.3