Modify the etherToken wrapper methods to accept an etherTokenAddress as the first arg. Since it is becoming apparent we will be updating the canonical WETH contract, we want users of 0x.js to be able to interact with n number of etherTokens without re-instantiating for each one.

This commit is contained in:
Fabio Berger 2017-12-17 00:32:53 -06:00
parent 4a73c05435
commit 1f748afed9
6 changed files with 21 additions and 46 deletions

View File

@ -199,7 +199,7 @@ export class ZeroEx {
this._web3Wrapper, config.networkId, config.tokenRegistryContractAddress, this._web3Wrapper, config.networkId, config.tokenRegistryContractAddress,
); );
this.etherToken = new EtherTokenWrapper( this.etherToken = new EtherTokenWrapper(
this._web3Wrapper, config.networkId, this.token, config.etherTokenContractAddress, this._web3Wrapper, config.networkId, this.token,
); );
this.orderStateWatcher = new OrderStateWatcher( this.orderStateWatcher = new OrderStateWatcher(
this._web3Wrapper, this._abiDecoder, this.token, this.exchange, config.orderWatcherConfig, this._web3Wrapper, this._abiDecoder, this.token, this.exchange, config.orderWatcherConfig,

View File

@ -17,24 +17,22 @@ import {TokenWrapper} from './token_wrapper';
export class EtherTokenWrapper extends ContractWrapper { export class EtherTokenWrapper extends ContractWrapper {
private _etherTokenContractIfExists?: EtherTokenContract; private _etherTokenContractIfExists?: EtherTokenContract;
private _tokenWrapper: TokenWrapper; private _tokenWrapper: TokenWrapper;
private _contractAddressIfExists?: string; constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenWrapper: TokenWrapper) {
constructor(web3Wrapper: Web3Wrapper, networkId: number, tokenWrapper: TokenWrapper,
contractAddressIfExists?: string) {
super(web3Wrapper, networkId); super(web3Wrapper, networkId);
this._tokenWrapper = tokenWrapper; this._tokenWrapper = tokenWrapper;
this._contractAddressIfExists = contractAddressIfExists;
} }
/** /**
* Deposit ETH into the Wrapped ETH smart contract and issues the equivalent number of wrapped ETH tokens * Deposit ETH into the Wrapped ETH smart contract and issues the equivalent number of wrapped ETH tokens
* to the depositor address. These wrapped ETH tokens can be used in 0x trades and are redeemable for 1-to-1 * to the depositor address. These wrapped ETH tokens can be used in 0x trades and are redeemable for 1-to-1
* for ETH. * for ETH.
* @param etherTokenAddress EtherToken address you wish to deposit into.
* @param amountInWei Amount of ETH in Wei the caller wishes to deposit. * @param amountInWei Amount of ETH in Wei the caller wishes to deposit.
* @param depositor The hex encoded user Ethereum address that would like to make the deposit. * @param depositor The hex encoded user Ethereum address that would like to make the deposit.
* @param txOpts Transaction parameters. * @param txOpts Transaction parameters.
* @return Transaction hash. * @return Transaction hash.
*/ */
public async depositAsync( public async depositAsync(
amountInWei: BigNumber, depositor: string, txOpts: TransactionOpts = {}, etherTokenAddress: string, amountInWei: BigNumber, depositor: string, txOpts: TransactionOpts = {},
): Promise<string> { ): Promise<string> {
assert.isValidBaseUnitAmount('amountInWei', amountInWei); assert.isValidBaseUnitAmount('amountInWei', amountInWei);
await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper); await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper);
@ -42,7 +40,7 @@ export class EtherTokenWrapper extends ContractWrapper {
const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor); const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor);
assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit); assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit);
const wethContract = await this._getEtherTokenContractAsync(); const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
const txHash = await wethContract.deposit.sendTransactionAsync({ const txHash = await wethContract.deposit.sendTransactionAsync({
from: depositor, from: depositor,
value: amountInWei, value: amountInWei,
@ -54,22 +52,22 @@ export class EtherTokenWrapper extends ContractWrapper {
/** /**
* Withdraw ETH to the withdrawer's address from the wrapped ETH smart contract in exchange for the * Withdraw ETH to the withdrawer's address from the wrapped ETH smart contract in exchange for the
* equivalent number of wrapped ETH tokens. * equivalent number of wrapped ETH tokens.
* @param etherTokenAddress EtherToken address you wish to withdraw from.
* @param amountInWei Amount of ETH in Wei the caller wishes to withdraw. * @param amountInWei Amount of ETH in Wei the caller wishes to withdraw.
* @param withdrawer The hex encoded user Ethereum address that would like to make the withdrawl. * @param withdrawer The hex encoded user Ethereum address that would like to make the withdrawl.
* @param txOpts Transaction parameters. * @param txOpts Transaction parameters.
* @return Transaction hash. * @return Transaction hash.
*/ */
public async withdrawAsync( public async withdrawAsync(
amountInWei: BigNumber, withdrawer: string, txOpts: TransactionOpts = {}, etherTokenAddress: string, amountInWei: BigNumber, withdrawer: string, txOpts: TransactionOpts = {},
): Promise<string> { ): Promise<string> {
assert.isValidBaseUnitAmount('amountInWei', amountInWei); assert.isValidBaseUnitAmount('amountInWei', amountInWei);
await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper); await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper);
const wethContractAddress = this.getContractAddress(); const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer);
const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(wethContractAddress, withdrawer);
assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal); assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal);
const wethContract = await this._getEtherTokenContractAsync(); const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress);
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, { const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
from: withdrawer, from: withdrawer,
gas: txOpts.gasLimit, gas: txOpts.gasLimit,
@ -77,25 +75,12 @@ export class EtherTokenWrapper extends ContractWrapper {
}); });
return txHash; return txHash;
} }
/**
* Retrieves the Wrapped Ether token contract address
* @return The Wrapped Ether token contract address
*/
public getContractAddress(): string {
const contractAddress = this._getContractAddress(
artifacts.EtherTokenArtifact, this._contractAddressIfExists,
);
return contractAddress;
}
private _invalidateContractInstance(): void { private _invalidateContractInstance(): void {
delete this._etherTokenContractIfExists; delete this._etherTokenContractIfExists;
} }
private async _getEtherTokenContractAsync(): Promise<EtherTokenContract> { private async _getEtherTokenContractAsync(etherTokenAddress: string): Promise<EtherTokenContract> {
if (!_.isUndefined(this._etherTokenContractIfExists)) {
return this._etherTokenContractIfExists;
}
const web3ContractInstance = await this._instantiateContractIfExistsAsync( const web3ContractInstance = await this._instantiateContractIfExistsAsync(
artifacts.EtherTokenArtifact, this._contractAddressIfExists, artifacts.EtherTokenArtifact, etherTokenAddress,
); );
const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults()); const contractInstance = new EtherTokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
this._etherTokenContractIfExists = contractInstance; this._etherTokenContractIfExists = contractInstance;

View File

@ -8,7 +8,6 @@ export const zeroExConfigSchema = {
gasPrice: {$ref: '/Number'}, gasPrice: {$ref: '/Number'},
exchangeContractAddress: {$ref: '/Address'}, exchangeContractAddress: {$ref: '/Address'},
tokenRegistryContractAddress: {$ref: '/Address'}, tokenRegistryContractAddress: {$ref: '/Address'},
etherTokenContractAddress: {$ref: '/Address'},
orderWatcherConfig: { orderWatcherConfig: {
type: 'object', type: 'object',
properties: { properties: {

View File

@ -268,7 +268,6 @@ export interface OrderStateWatcherConfig {
* gasPrice: Gas price to use with every transaction * gasPrice: Gas price to use with every transaction
* exchangeContractAddress: The address of an exchange contract to use * exchangeContractAddress: The address of an exchange contract to use
* tokenRegistryContractAddress: The address of a token registry contract to use * tokenRegistryContractAddress: The address of a token registry contract to use
* etherTokenContractAddress: The address of an ether token contract to use
* tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use * tokenTransferProxyContractAddress: The address of the token transfer proxy contract to use
* orderWatcherConfig: All the configs related to the orderWatcher * orderWatcherConfig: All the configs related to the orderWatcher
*/ */
@ -277,7 +276,6 @@ export interface ZeroExConfig {
gasPrice?: BigNumber; gasPrice?: BigNumber;
exchangeContractAddress?: string; exchangeContractAddress?: string;
tokenRegistryContractAddress?: string; tokenRegistryContractAddress?: string;
etherTokenContractAddress?: string;
tokenTransferProxyContractAddress?: string; tokenTransferProxyContractAddress?: string;
orderWatcherConfig?: OrderStateWatcherConfig; orderWatcherConfig?: OrderStateWatcherConfig;
} }

View File

@ -244,14 +244,6 @@ describe('ZeroEx library', () => {
const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig); const zeroExWithWrongExchangeAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS); expect(zeroExWithWrongExchangeAddress.exchange.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
}); });
it('allows to specify ether token contract address', async () => {
const zeroExConfig = {
etherTokenContractAddress: ZeroEx.NULL_ADDRESS,
networkId: constants.TESTRPC_NETWORK_ID,
};
const zeroExWithWrongEtherTokenAddress = new ZeroEx(web3.currentProvider, zeroExConfig);
expect(zeroExWithWrongEtherTokenAddress.etherToken.getContractAddress()).to.be.equal(ZeroEx.NULL_ADDRESS);
});
it('allows to specify token registry token contract address', async () => { it('allows to specify token registry token contract address', async () => {
const zeroExConfig = { const zeroExConfig = {
tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS, tokenRegistryContractAddress: ZeroEx.NULL_ADDRESS,

View File

@ -5,6 +5,7 @@ import 'mocha';
import * as Web3 from 'web3'; import * as Web3 from 'web3';
import {ZeroEx, ZeroExError} from '../src'; import {ZeroEx, ZeroExError} from '../src';
import {artifacts} from '../src/artifacts';
import {chaiSetup} from './utils/chai_setup'; import {chaiSetup} from './utils/chai_setup';
import {constants} from './utils/constants'; import {constants} from './utils/constants';
@ -38,7 +39,7 @@ describe('EtherTokenWrapper', () => {
zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig); zeroEx = new ZeroEx(web3.currentProvider, zeroExConfig);
userAddresses = await zeroEx.getAvailableAddressesAsync(); userAddresses = await zeroEx.getAvailableAddressesAsync();
addressWithETH = userAddresses[0]; addressWithETH = userAddresses[0];
wethContractAddress = zeroEx.etherToken.getContractAddress(); wethContractAddress = (zeroEx.etherToken as any)._getContractAddress(artifacts.EtherTokenArtifact);
depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5)); depositWeiAmount = (zeroEx as any)._web3Wrapper.toWei(new BigNumber(5));
decimalPlaces = 7; decimalPlaces = 7;
}); });
@ -55,7 +56,7 @@ describe('EtherTokenWrapper', () => {
expect(preETHBalance).to.be.bignumber.gt(0); expect(preETHBalance).to.be.bignumber.gt(0);
expect(preWETHBalance).to.be.bignumber.equal(0); expect(preWETHBalance).to.be.bignumber.equal(0);
const txHash = await zeroEx.etherToken.depositAsync(depositWeiAmount, addressWithETH); const txHash = await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash); await zeroEx.awaitTransactionMinedAsync(txHash);
const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH); const postETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
@ -73,7 +74,7 @@ describe('EtherTokenWrapper', () => {
const overETHBalanceinWei = preETHBalance.add(extraETHBalance); const overETHBalanceinWei = preETHBalance.add(extraETHBalance);
return expect( return expect(
zeroEx.etherToken.depositAsync(overETHBalanceinWei, addressWithETH), zeroEx.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH),
).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit); ).to.be.rejectedWith(ZeroExError.InsufficientEthBalanceForDeposit);
}); });
}); });
@ -81,7 +82,7 @@ describe('EtherTokenWrapper', () => {
it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => { it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => {
const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH); const ETHBalanceInWei = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
await zeroEx.etherToken.depositAsync(depositWeiAmount, addressWithETH); await zeroEx.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH);
const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount); const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount);
const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH); const preETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
@ -90,7 +91,7 @@ describe('EtherTokenWrapper', () => {
expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI); expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI);
expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount); expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount);
const txHash = await zeroEx.etherToken.withdrawAsync(depositWeiAmount, addressWithETH); const txHash = await zeroEx.etherToken.withdrawAsync(wethContractAddress, depositWeiAmount, addressWithETH);
await zeroEx.awaitTransactionMinedAsync(txHash); await zeroEx.awaitTransactionMinedAsync(txHash);
const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH); const postETHBalance = await (zeroEx as any)._web3Wrapper.getBalanceInWeiAsync(addressWithETH);
@ -108,7 +109,7 @@ describe('EtherTokenWrapper', () => {
const overWETHBalance = preWETHBalance.add(999999999); const overWETHBalance = preWETHBalance.add(999999999);
return expect( return expect(
zeroEx.etherToken.withdrawAsync(overWETHBalance, addressWithETH), zeroEx.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH),
).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal); ).to.be.rejectedWith(ZeroExError.InsufficientWEthBalanceForWithdrawal);
}); });
}); });