From 31f9a848f90fa53d5d3817fe6cfb668a44919ef6 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 6 Feb 2018 15:06:56 -0800 Subject: Lowercase public addresses Normalize the public api addresses to lowercase to prevent an avoidable error --- packages/0x.js/src/0x.ts | 15 ++- .../src/contract_wrappers/ether_token_wrapper.ts | 37 ++++-- .../src/contract_wrappers/exchange_wrapper.ts | 52 +++++--- .../contract_wrappers/token_registry_wrapper.ts | 5 +- .../token_transfer_proxy_wrapper.ts | 7 +- .../0x.js/src/contract_wrappers/token_wrapper.ts | 145 ++++++++++++++------- 6 files changed, 172 insertions(+), 89 deletions(-) diff --git a/packages/0x.js/src/0x.ts b/packages/0x.js/src/0x.ts index 6cfa65cc2..c37b3e1ef 100644 --- a/packages/0x.js/src/0x.ts +++ b/packages/0x.js/src/0x.ts @@ -71,11 +71,12 @@ export class ZeroEx { * @return Whether the signature is valid for the supplied signerAddress and data. */ public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean { + const normalizedSignerAddress = signerAddress.toLowerCase(); assert.isHexString('data', data); assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema); - assert.isETHAddressHex('signerAddress', signerAddress); + assert.isETHAddressHex('signerAddress', normalizedSignerAddress); - const isValidSignature = signatureUtils.isValidSignature(data, signature, signerAddress); + const isValidSignature = signatureUtils.isValidSignature(data, signature, normalizedSignerAddress); return isValidSignature; } /** @@ -244,7 +245,9 @@ export class ZeroEx { shouldAddPersonalMessagePrefix: boolean, ): Promise { assert.isHexString('orderHash', orderHash); - await assert.isSenderAddressAsync('signerAddress', signerAddress, this._web3Wrapper); + const normalizedSignerAddress = signerAddress.toLowerCase(); + assert.isETHAddressHex('signerAddress', normalizedSignerAddress); + await assert.isSenderAddressAsync('signerAddress', normalizedSignerAddress, this._web3Wrapper); let msgHashHex = orderHash; if (shouldAddPersonalMessagePrefix) { @@ -253,7 +256,7 @@ export class ZeroEx { msgHashHex = ethUtil.bufferToHex(msgHashBuff); } - const signature = await this._web3Wrapper.signTransactionAsync(signerAddress, msgHashHex); + const signature = await this._web3Wrapper.signTransactionAsync(normalizedSignerAddress, msgHashHex); // HACK: There is no consensus on whether the signatureHex string should be formatted as // v + r + s OR r + s + v, and different clients (even different versions of the same client) @@ -262,7 +265,7 @@ export class ZeroEx { const validVParamValues = [27, 28]; const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature); if (_.includes(validVParamValues, ecSignatureVRS.v)) { - const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, signerAddress); + const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress); if (isValidVRSSignature) { return ecSignatureVRS; } @@ -270,7 +273,7 @@ export class ZeroEx { const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature); if (_.includes(validVParamValues, ecSignatureRSV.v)) { - const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, signerAddress); + const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress); if (isValidRSVSignature) { return ecSignatureRSV; } diff --git a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts index db7cdee43..236b2be4f 100644 --- a/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/ether_token_wrapper.ts @@ -41,15 +41,19 @@ export class EtherTokenWrapper extends ContractWrapper { depositor: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedDepositorAddress = depositor.toLowerCase(); + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + assert.isETHAddressHex('depositor', normalizedDepositorAddress); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.isValidBaseUnitAmount('amountInWei', amountInWei); - await assert.isSenderAddressAsync('depositor', depositor, this._web3Wrapper); + await assert.isSenderAddressAsync('depositor', normalizedDepositorAddress, this._web3Wrapper); - const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(depositor); + const ethBalanceInWei = await this._web3Wrapper.getBalanceInWeiAsync(normalizedDepositorAddress); assert.assert(ethBalanceInWei.gte(amountInWei), ZeroExError.InsufficientEthBalanceForDeposit); - const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress); + const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); const txHash = await wethContract.deposit.sendTransactionAsync({ - from: depositor, + from: normalizedDepositorAddress, value: amountInWei, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, @@ -71,15 +75,22 @@ export class EtherTokenWrapper extends ContractWrapper { withdrawer: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + const normalizedWithdrawerAddress = withdrawer.toLowerCase(); + assert.isETHAddressHex('withdrawer', normalizedWithdrawerAddress); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.isValidBaseUnitAmount('amountInWei', amountInWei); - await assert.isSenderAddressAsync('withdrawer', withdrawer, this._web3Wrapper); + await assert.isSenderAddressAsync('withdrawer', normalizedWithdrawerAddress, this._web3Wrapper); - const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync(etherTokenAddress, withdrawer); + const WETHBalanceInBaseUnits = await this._tokenWrapper.getBalanceAsync( + normalizedEtherTokenAddress, + normalizedWithdrawerAddress, + ); assert.assert(WETHBalanceInBaseUnits.gte(amountInWei), ZeroExError.InsufficientWEthBalanceForWithdrawal); - const wethContract = await this._getEtherTokenContractAsync(etherTokenAddress); + const wethContract = await this._getEtherTokenContractAsync(normalizedEtherTokenAddress); const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, { - from: withdrawer, + from: normalizedWithdrawerAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }); @@ -100,12 +111,13 @@ export class EtherTokenWrapper extends ContractWrapper { blockRange: BlockRange, indexFilterValues: IndexedFilterValues, ): Promise>> { - assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const logs = await this._getLogsAsync( - etherTokenAddress, + normalizedEtherTokenAddress, eventName, blockRange, indexFilterValues, @@ -128,12 +140,13 @@ export class EtherTokenWrapper extends ContractWrapper { indexFilterValues: IndexedFilterValues, callback: EventCallback, ): string { - assert.isETHAddressHex('etherTokenAddress', etherTokenAddress); + const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase(); + assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); const subscriptionToken = this._subscribe( - etherTokenAddress, + normalizedEtherTokenAddress, eventName, indexFilterValues, artifacts.EtherTokenArtifact.abi, diff --git a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts index c82b7ecf5..71f0618f0 100644 --- a/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/exchange_wrapper.ts @@ -179,7 +179,9 @@ export class ExchangeWrapper extends ContractWrapper { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const exchangeInstance = await this._getExchangeContractAsync(); const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) @@ -192,7 +194,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -208,7 +210,7 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder.ecSignature.r, signedOrder.ecSignature.s, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -253,7 +255,9 @@ export class ExchangeWrapper extends ContractWrapper { ); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ? SHOULD_VALIDATE_BY_DEFAULT @@ -267,7 +271,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, signedOrder, fillTakerTokenAmount.minus(filledTakerTokenAmount), - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount); @@ -301,7 +305,7 @@ export class ExchangeWrapper extends ContractWrapper { rArray, sArray, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -344,7 +348,9 @@ export class ExchangeWrapper extends ContractWrapper { ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, ); assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate) ? SHOULD_VALIDATE_BY_DEFAULT : orderTransactionOpts.shouldValidate; @@ -356,7 +362,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -389,7 +395,7 @@ export class ExchangeWrapper extends ContractWrapper { rArray, sArray, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -416,7 +422,9 @@ export class ExchangeWrapper extends ContractWrapper { ): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const exchangeInstance = await this._getExchangeContractAsync(); @@ -430,7 +438,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -444,7 +452,7 @@ export class ExchangeWrapper extends ContractWrapper { signedOrder.ecSignature.r, signedOrder.ecSignature.s, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -475,7 +483,9 @@ export class ExchangeWrapper extends ContractWrapper { exchangeContractAddresses, ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress, ); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); if (_.isEmpty(orderFillRequests)) { throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem); } @@ -492,7 +502,7 @@ export class ExchangeWrapper extends ContractWrapper { exchangeTradeEmulator, orderFillRequest.signedOrder, orderFillRequest.takerTokenFillAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -520,7 +530,7 @@ export class ExchangeWrapper extends ContractWrapper { rParams, sParams, { - from: takerAddress, + from: normalizedTakerAddress, gas: orderTransactionOpts.gasLimit, gasPrice: orderTransactionOpts.gasPrice, }, @@ -756,14 +766,16 @@ export class ExchangeWrapper extends ContractWrapper { ): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const zrxTokenAddress = this.getZRXTokenAddress(); const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } @@ -802,14 +814,16 @@ export class ExchangeWrapper extends ContractWrapper { ): Promise { assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema); assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount); - await assert.isSenderAddressAsync('takerAddress', takerAddress, this._web3Wrapper); + const normalizedTakerAddress = takerAddress.toLowerCase(); + assert.isETHAddressHex('takerAddress', normalizedTakerAddress); + await assert.isSenderAddressAsync('takerAddress', normalizedTakerAddress, this._web3Wrapper); const zrxTokenAddress = this.getZRXTokenAddress(); const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest); await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync( exchangeTradeEmulator, signedOrder, fillTakerTokenAmount, - takerAddress, + normalizedTakerAddress, zrxTokenAddress, ); } diff --git a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts index f54aaf0f8..508ff15d7 100644 --- a/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_registry_wrapper.ts @@ -57,10 +57,11 @@ export class TokenRegistryWrapper extends ContractWrapper { * @return An object that conforms to the Token interface or undefined if token not found. */ public async getTokenIfExistsAsync(address: string): Promise { - assert.isETHAddressHex('address', address); + const normalizedAddress = address.toLowerCase(); + assert.isETHAddressHex('address', normalizedAddress); const tokenRegistryContract = await this._getTokenRegistryContractAsync(); - const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address); + const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress); const token = TokenRegistryWrapper._createTokenFromMetadata(metadata); return token; } diff --git a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts index f5d9d108a..41afd2f67 100644 --- a/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_transfer_proxy_wrapper.ts @@ -2,6 +2,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import { artifacts } from '../artifacts'; +import { assert } from '../utils/assert'; import { ContractWrapper } from './contract_wrapper'; import { TokenTransferProxyContract } from './generated/token_transfer_proxy'; @@ -22,8 +23,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper { * @return Whether the exchangeContractAddress is authorized. */ public async isAuthorizedAsync(exchangeContractAddress: string): Promise { + const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase(); + assert.isETHAddressHex('exchangeContractAddress', normalizedExchangeContractAddress); const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync(); - const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(exchangeContractAddress); + const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync( + normalizedExchangeContractAddress, + ); return isAuthorized; } /** diff --git a/packages/0x.js/src/contract_wrappers/token_wrapper.ts b/packages/0x.js/src/contract_wrappers/token_wrapper.ts index a018006b8..61da8c6ef 100644 --- a/packages/0x.js/src/contract_wrappers/token_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/token_wrapper.ts @@ -44,12 +44,14 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts?: MethodOpts, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let balance = await tokenContract.balanceOf.callAsync(ownerAddress, defaultBlock); + let balance = await tokenContract.balanceOf.callAsync(normalizedOwnerAddress, defaultBlock); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber balance = new BigNumber(balance); return balance; @@ -72,14 +74,17 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper); - assert.isETHAddressHex('spenderAddress', spenderAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); + await assert.isSenderAddressAsync('ownerAddress', normalizedOwnerAddress, this._web3Wrapper); + assert.isETHAddressHex('spenderAddress', normalizedSpenderAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - const tokenContract = await this._getTokenContractAsync(tokenAddress); - const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, { - from: ownerAddress, + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); + const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, { + from: normalizedOwnerAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }); @@ -103,10 +108,16 @@ export class TokenWrapper extends ContractWrapper { spenderAddress: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); + assert.isETHAddressHex('spenderAddress', normalizedSpenderAddress); const txHash = await this.setAllowanceAsync( - tokenAddress, - ownerAddress, - spenderAddress, + normalizedTokenAddress, + normalizedOwnerAddress, + normalizedSpenderAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts, ); @@ -126,12 +137,19 @@ export class TokenWrapper extends ContractWrapper { spenderAddress: string, methodOpts?: MethodOpts, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + const normalizedSpenderAddress = spenderAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); const defaultBlock = _.isUndefined(methodOpts) ? undefined : methodOpts.defaultBlock; - let allowanceInBaseUnits = await tokenContract.allowance.callAsync(ownerAddress, spenderAddress, defaultBlock); + let allowanceInBaseUnits = await tokenContract.allowance.callAsync( + normalizedOwnerAddress, + normalizedSpenderAddress, + defaultBlock, + ); // Wrap BigNumbers returned from web3 with our own (later) version of BigNumber allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits); return allowanceInBaseUnits; @@ -147,11 +165,18 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, methodOpts?: MethodOpts, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress(); - const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, methodOpts); + const allowanceInBaseUnits = await this.getAllowanceAsync( + normalizedTokenAddress, + normalizedOwnerAddress, + proxyAddress, + methodOpts, + ); return allowanceInBaseUnits; } /** @@ -170,14 +195,16 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - assert.isETHAddressHex('ownerAddress', ownerAddress); - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress(); const txHash = await this.setAllowanceAsync( - tokenAddress, - ownerAddress, + normalizedTokenAddress, + normalizedOwnerAddress, proxyAddress, amountInBaseUnits, txOpts, @@ -200,9 +227,13 @@ export class TokenWrapper extends ContractWrapper { ownerAddress: string, txOpts: TransactionOpts = {}, ): Promise { + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedOwnerAddress = ownerAddress.toLowerCase(); + assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); const txHash = await this.setProxyAllowanceAsync( - tokenAddress, - ownerAddress, + normalizedTokenAddress, + normalizedOwnerAddress, this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS, txOpts, ); @@ -224,20 +255,24 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - assert.isETHAddressHex('tokenAddress', tokenAddress); - await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedFromAddress = fromAddress.toLowerCase(); + const normalizedToAddress = toAddress.toLowerCase(); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.isETHAddressHex('toAddress', toAddress); + assert.isETHAddressHex('fromAddress', normalizedFromAddress); + await assert.isSenderAddressAsync('fromAddress', normalizedFromAddress, this._web3Wrapper); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress); + const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress); if (fromAddressBalance.lessThan(amountInBaseUnits)) { throw new Error(ZeroExError.InsufficientBalanceForTransfer); } - const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, { - from: fromAddress, + const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, { + from: normalizedFromAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }); @@ -265,30 +300,39 @@ export class TokenWrapper extends ContractWrapper { amountInBaseUnits: BigNumber, txOpts: TransactionOpts = {}, ): Promise { - assert.isETHAddressHex('tokenAddress', tokenAddress); - assert.isETHAddressHex('fromAddress', fromAddress); - assert.isETHAddressHex('toAddress', toAddress); - await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper); + const normalizedToAddress = toAddress.toLowerCase(); + const normalizedFromAddress = fromAddress.toLowerCase(); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + const normalizedSenderAddress = senderAddress.toLowerCase(); + assert.isETHAddressHex('toAddress', normalizedToAddress); + assert.isETHAddressHex('fromAddress', normalizedFromAddress); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); + assert.isETHAddressHex('senderAddress', normalizedSenderAddress); + await assert.isSenderAddressAsync('senderAddress', normalizedSenderAddress, this._web3Wrapper); assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits); - const tokenContract = await this._getTokenContractAsync(tokenAddress); + const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress); - const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress); + const fromAddressAllowance = await this.getAllowanceAsync( + normalizedTokenAddress, + normalizedFromAddress, + normalizedSenderAddress, + ); if (fromAddressAllowance.lessThan(amountInBaseUnits)) { throw new Error(ZeroExError.InsufficientAllowanceForTransfer); } - const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress); + const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress); if (fromAddressBalance.lessThan(amountInBaseUnits)) { throw new Error(ZeroExError.InsufficientBalanceForTransfer); } const txHash = await tokenContract.transferFrom.sendTransactionAsync( - fromAddress, - toAddress, + normalizedFromAddress, + normalizedToAddress, amountInBaseUnits, { - from: senderAddress, + from: normalizedSenderAddress, gas: txOpts.gasLimit, gasPrice: txOpts.gasPrice, }, @@ -310,12 +354,13 @@ export class TokenWrapper extends ContractWrapper { indexFilterValues: IndexedFilterValues, callback: EventCallback, ): string { - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); assert.isFunction('callback', callback); const subscriptionToken = this._subscribe( - tokenAddress, + normalizedTokenAddress, eventName, indexFilterValues, artifacts.TokenArtifact.abi, @@ -351,12 +396,13 @@ export class TokenWrapper extends ContractWrapper { blockRange: BlockRange, indexFilterValues: IndexedFilterValues, ): Promise>> { - assert.isETHAddressHex('tokenAddress', tokenAddress); + const normalizedTokenAddress = tokenAddress.toLowerCase(); + assert.isETHAddressHex('tokenAddress', normalizedTokenAddress); assert.doesBelongToStringEnum('eventName', eventName, TokenEvents); assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema); assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema); const logs = await this._getLogsAsync( - tokenAddress, + normalizedTokenAddress, eventName, blockRange, indexFilterValues, @@ -369,17 +415,18 @@ export class TokenWrapper extends ContractWrapper { this._tokenContractsByAddress = {}; } private async _getTokenContractAsync(tokenAddress: string): Promise { - let tokenContract = this._tokenContractsByAddress[tokenAddress]; + const normalizedTokenAddress = tokenAddress.toLowerCase(); + let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress]; if (!_.isUndefined(tokenContract)) { return tokenContract; } const web3ContractInstance = await this._instantiateContractIfExistsAsync( artifacts.TokenArtifact, - tokenAddress, + normalizedTokenAddress, ); const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults()); tokenContract = contractInstance; - this._tokenContractsByAddress[tokenAddress] = tokenContract; + this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract; return tokenContract; } } -- cgit