Lowercase public addresses
Normalize the public api addresses to lowercase to prevent an avoidable error
This commit is contained in:
parent
097fc477a2
commit
31f9a848f9
@ -71,11 +71,12 @@ export class ZeroEx {
|
|||||||
* @return Whether the signature is valid for the supplied signerAddress and data.
|
* @return Whether the signature is valid for the supplied signerAddress and data.
|
||||||
*/
|
*/
|
||||||
public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
|
public static isValidSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
|
||||||
|
const normalizedSignerAddress = signerAddress.toLowerCase();
|
||||||
assert.isHexString('data', data);
|
assert.isHexString('data', data);
|
||||||
assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
|
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;
|
return isValidSignature;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -244,7 +245,9 @@ export class ZeroEx {
|
|||||||
shouldAddPersonalMessagePrefix: boolean,
|
shouldAddPersonalMessagePrefix: boolean,
|
||||||
): Promise<ECSignature> {
|
): Promise<ECSignature> {
|
||||||
assert.isHexString('orderHash', orderHash);
|
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;
|
let msgHashHex = orderHash;
|
||||||
if (shouldAddPersonalMessagePrefix) {
|
if (shouldAddPersonalMessagePrefix) {
|
||||||
@ -253,7 +256,7 @@ export class ZeroEx {
|
|||||||
msgHashHex = ethUtil.bufferToHex(msgHashBuff);
|
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
|
// 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)
|
// 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 validVParamValues = [27, 28];
|
||||||
const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature);
|
const ecSignatureVRS = signatureUtils.parseSignatureHexAsVRS(signature);
|
||||||
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
|
if (_.includes(validVParamValues, ecSignatureVRS.v)) {
|
||||||
const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, signerAddress);
|
const isValidVRSSignature = ZeroEx.isValidSignature(orderHash, ecSignatureVRS, normalizedSignerAddress);
|
||||||
if (isValidVRSSignature) {
|
if (isValidVRSSignature) {
|
||||||
return ecSignatureVRS;
|
return ecSignatureVRS;
|
||||||
}
|
}
|
||||||
@ -270,7 +273,7 @@ export class ZeroEx {
|
|||||||
|
|
||||||
const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature);
|
const ecSignatureRSV = signatureUtils.parseSignatureHexAsRSV(signature);
|
||||||
if (_.includes(validVParamValues, ecSignatureRSV.v)) {
|
if (_.includes(validVParamValues, ecSignatureRSV.v)) {
|
||||||
const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, signerAddress);
|
const isValidRSVSignature = ZeroEx.isValidSignature(orderHash, ecSignatureRSV, normalizedSignerAddress);
|
||||||
if (isValidRSVSignature) {
|
if (isValidRSVSignature) {
|
||||||
return ecSignatureRSV;
|
return ecSignatureRSV;
|
||||||
}
|
}
|
||||||
|
@ -41,15 +41,19 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
depositor: string,
|
depositor: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
const normalizedDepositorAddress = depositor.toLowerCase();
|
||||||
|
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('depositor', normalizedDepositorAddress);
|
||||||
|
assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
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);
|
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({
|
const txHash = await wethContract.deposit.sendTransactionAsync({
|
||||||
from: depositor,
|
from: normalizedDepositorAddress,
|
||||||
value: amountInWei,
|
value: amountInWei,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
@ -71,15 +75,22 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
withdrawer: string,
|
withdrawer: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||||
|
const normalizedWithdrawerAddress = withdrawer.toLowerCase();
|
||||||
|
assert.isETHAddressHex('withdrawer', normalizedWithdrawerAddress);
|
||||||
|
assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInWei', amountInWei);
|
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);
|
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, {
|
const txHash = await wethContract.withdraw.sendTransactionAsync(amountInWei, {
|
||||||
from: withdrawer,
|
from: normalizedWithdrawerAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
@ -100,12 +111,13 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
blockRange: BlockRange,
|
blockRange: BlockRange,
|
||||||
indexFilterValues: IndexedFilterValues,
|
indexFilterValues: IndexedFilterValues,
|
||||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
etherTokenAddress,
|
normalizedEtherTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
blockRange,
|
blockRange,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
@ -128,12 +140,13 @@ export class EtherTokenWrapper extends ContractWrapper {
|
|||||||
indexFilterValues: IndexedFilterValues,
|
indexFilterValues: IndexedFilterValues,
|
||||||
callback: EventCallback<ArgsType>,
|
callback: EventCallback<ArgsType>,
|
||||||
): string {
|
): string {
|
||||||
assert.isETHAddressHex('etherTokenAddress', etherTokenAddress);
|
const normalizedEtherTokenAddress = etherTokenAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('etherTokenAddress', normalizedEtherTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, EtherTokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
etherTokenAddress,
|
normalizedEtherTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
artifacts.EtherTokenArtifact.abi,
|
artifacts.EtherTokenArtifact.abi,
|
||||||
|
@ -179,7 +179,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
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 exchangeInstance = await this._getExchangeContractAsync();
|
||||||
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
@ -192,7 +194,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -208,7 +210,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
signedOrder.ecSignature.r,
|
signedOrder.ecSignature.r,
|
||||||
signedOrder.ecSignature.s,
|
signedOrder.ecSignature.s,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@ -253,7 +255,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
);
|
);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
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)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
? SHOULD_VALIDATE_BY_DEFAULT
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
@ -267,7 +271,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount.minus(filledTakerTokenAmount),
|
fillTakerTokenAmount.minus(filledTakerTokenAmount),
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
|
filledTakerTokenAmount = filledTakerTokenAmount.plus(singleFilledTakerTokenAmount);
|
||||||
@ -301,7 +305,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
rArray,
|
rArray,
|
||||||
sArray,
|
sArray,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@ -344,7 +348,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
||||||
);
|
);
|
||||||
assert.isBoolean('shouldThrowOnInsufficientBalanceOrAllowance', shouldThrowOnInsufficientBalanceOrAllowance);
|
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)
|
const shouldValidate = _.isUndefined(orderTransactionOpts.shouldValidate)
|
||||||
? SHOULD_VALIDATE_BY_DEFAULT
|
? SHOULD_VALIDATE_BY_DEFAULT
|
||||||
: orderTransactionOpts.shouldValidate;
|
: orderTransactionOpts.shouldValidate;
|
||||||
@ -356,7 +362,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
orderFillRequest.signedOrder,
|
orderFillRequest.signedOrder,
|
||||||
orderFillRequest.takerTokenFillAmount,
|
orderFillRequest.takerTokenFillAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -389,7 +395,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
rArray,
|
rArray,
|
||||||
sArray,
|
sArray,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@ -416,7 +422,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
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();
|
const exchangeInstance = await this._getExchangeContractAsync();
|
||||||
|
|
||||||
@ -430,7 +438,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -444,7 +452,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
signedOrder.ecSignature.r,
|
signedOrder.ecSignature.r,
|
||||||
signedOrder.ecSignature.s,
|
signedOrder.ecSignature.s,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@ -475,7 +483,9 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeContractAddresses,
|
exchangeContractAddresses,
|
||||||
ExchangeContractErrs.BatchOrdersMustHaveSameExchangeAddress,
|
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)) {
|
if (_.isEmpty(orderFillRequests)) {
|
||||||
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
throw new Error(ExchangeContractErrs.BatchOrdersMustHaveAtLeastOneItem);
|
||||||
}
|
}
|
||||||
@ -492,7 +502,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
orderFillRequest.signedOrder,
|
orderFillRequest.signedOrder,
|
||||||
orderFillRequest.takerTokenFillAmount,
|
orderFillRequest.takerTokenFillAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -520,7 +530,7 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
rParams,
|
rParams,
|
||||||
sParams,
|
sParams,
|
||||||
{
|
{
|
||||||
from: takerAddress,
|
from: normalizedTakerAddress,
|
||||||
gas: orderTransactionOpts.gasLimit,
|
gas: orderTransactionOpts.gasLimit,
|
||||||
gasPrice: orderTransactionOpts.gasPrice,
|
gasPrice: orderTransactionOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@ -756,14 +766,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
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 zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -802,14 +814,16 @@ export class ExchangeWrapper extends ContractWrapper {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
assert.doesConformToSchema('signedOrder', signedOrder, schemas.signedOrderSchema);
|
||||||
assert.isValidBaseUnitAmount('fillTakerTokenAmount', fillTakerTokenAmount);
|
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 zrxTokenAddress = this.getZRXTokenAddress();
|
||||||
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
const exchangeTradeEmulator = new ExchangeTransferSimulator(this._tokenWrapper, BlockParamLiteral.Latest);
|
||||||
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
await this._orderValidationUtils.validateFillOrKillOrderThrowIfInvalidAsync(
|
||||||
exchangeTradeEmulator,
|
exchangeTradeEmulator,
|
||||||
signedOrder,
|
signedOrder,
|
||||||
fillTakerTokenAmount,
|
fillTakerTokenAmount,
|
||||||
takerAddress,
|
normalizedTakerAddress,
|
||||||
zrxTokenAddress,
|
zrxTokenAddress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,11 @@ export class TokenRegistryWrapper extends ContractWrapper {
|
|||||||
* @return An object that conforms to the Token interface or undefined if token not found.
|
* @return An object that conforms to the Token interface or undefined if token not found.
|
||||||
*/
|
*/
|
||||||
public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> {
|
public async getTokenIfExistsAsync(address: string): Promise<Token | undefined> {
|
||||||
assert.isETHAddressHex('address', address);
|
const normalizedAddress = address.toLowerCase();
|
||||||
|
assert.isETHAddressHex('address', normalizedAddress);
|
||||||
|
|
||||||
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
const tokenRegistryContract = await this._getTokenRegistryContractAsync();
|
||||||
const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(address);
|
const metadata = await tokenRegistryContract.getTokenMetaData.callAsync(normalizedAddress);
|
||||||
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
const token = TokenRegistryWrapper._createTokenFromMetadata(metadata);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import { artifacts } from '../artifacts';
|
import { artifacts } from '../artifacts';
|
||||||
|
import { assert } from '../utils/assert';
|
||||||
|
|
||||||
import { ContractWrapper } from './contract_wrapper';
|
import { ContractWrapper } from './contract_wrapper';
|
||||||
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
|
import { TokenTransferProxyContract } from './generated/token_transfer_proxy';
|
||||||
@ -22,8 +23,12 @@ export class TokenTransferProxyWrapper extends ContractWrapper {
|
|||||||
* @return Whether the exchangeContractAddress is authorized.
|
* @return Whether the exchangeContractAddress is authorized.
|
||||||
*/
|
*/
|
||||||
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
public async isAuthorizedAsync(exchangeContractAddress: string): Promise<boolean> {
|
||||||
|
const normalizedExchangeContractAddress = exchangeContractAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('exchangeContractAddress', normalizedExchangeContractAddress);
|
||||||
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
|
const tokenTransferProxyContractInstance = await this._getTokenTransferProxyContractAsync();
|
||||||
const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(exchangeContractAddress);
|
const isAuthorized = await tokenTransferProxyContractInstance.authorized.callAsync(
|
||||||
|
normalizedExchangeContractAddress,
|
||||||
|
);
|
||||||
return isAuthorized;
|
return isAuthorized;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
@ -44,12 +44,14 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
ownerAddress: string,
|
ownerAddress: string,
|
||||||
methodOpts?: MethodOpts,
|
methodOpts?: MethodOpts,
|
||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
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;
|
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
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
balance = new BigNumber(balance);
|
balance = new BigNumber(balance);
|
||||||
return balance;
|
return balance;
|
||||||
@ -72,14 +74,17 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
await assert.isSenderAddressAsync('ownerAddress', ownerAddress, this._web3Wrapper);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('spenderAddress', spenderAddress);
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedSpenderAddress = spenderAddress.toLowerCase();
|
||||||
|
await assert.isSenderAddressAsync('ownerAddress', normalizedOwnerAddress, this._web3Wrapper);
|
||||||
|
assert.isETHAddressHex('spenderAddress', normalizedSpenderAddress);
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const tokenContract = await this._getTokenContractAsync(tokenAddress);
|
const tokenContract = await this._getTokenContractAsync(normalizedTokenAddress);
|
||||||
const txHash = await tokenContract.approve.sendTransactionAsync(spenderAddress, amountInBaseUnits, {
|
const txHash = await tokenContract.approve.sendTransactionAsync(normalizedSpenderAddress, amountInBaseUnits, {
|
||||||
from: ownerAddress,
|
from: normalizedOwnerAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
@ -103,10 +108,16 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
spenderAddress: string,
|
spenderAddress: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
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(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
ownerAddress,
|
normalizedOwnerAddress,
|
||||||
spenderAddress,
|
normalizedSpenderAddress,
|
||||||
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
txOpts,
|
txOpts,
|
||||||
);
|
);
|
||||||
@ -126,12 +137,19 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
spenderAddress: string,
|
spenderAddress: string,
|
||||||
methodOpts?: MethodOpts,
|
methodOpts?: MethodOpts,
|
||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
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;
|
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
|
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
|
||||||
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
|
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
|
||||||
return allowanceInBaseUnits;
|
return allowanceInBaseUnits;
|
||||||
@ -147,11 +165,18 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
ownerAddress: string,
|
ownerAddress: string,
|
||||||
methodOpts?: MethodOpts,
|
methodOpts?: MethodOpts,
|
||||||
): Promise<BigNumber> {
|
): Promise<BigNumber> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress);
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
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;
|
return allowanceInBaseUnits;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -170,14 +195,16 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('ownerAddress', ownerAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress);
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
||||||
|
|
||||||
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
const proxyAddress = this._tokenTransferProxyWrapper.getContractAddress();
|
||||||
const txHash = await this.setAllowanceAsync(
|
const txHash = await this.setAllowanceAsync(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
ownerAddress,
|
normalizedOwnerAddress,
|
||||||
proxyAddress,
|
proxyAddress,
|
||||||
amountInBaseUnits,
|
amountInBaseUnits,
|
||||||
txOpts,
|
txOpts,
|
||||||
@ -200,9 +227,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
ownerAddress: string,
|
ownerAddress: string,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
const normalizedOwnerAddress = ownerAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('ownerAddress', normalizedOwnerAddress);
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
const txHash = await this.setProxyAllowanceAsync(
|
const txHash = await this.setProxyAllowanceAsync(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
ownerAddress,
|
normalizedOwnerAddress,
|
||||||
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
this.UNLIMITED_ALLOWANCE_IN_BASE_UNITS,
|
||||||
txOpts,
|
txOpts,
|
||||||
);
|
);
|
||||||
@ -224,20 +255,24 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
await assert.isSenderAddressAsync('fromAddress', fromAddress, this._web3Wrapper);
|
const normalizedFromAddress = fromAddress.toLowerCase();
|
||||||
|
const normalizedToAddress = toAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
assert.isETHAddressHex('toAddress', toAddress);
|
||||||
|
assert.isETHAddressHex('fromAddress', normalizedFromAddress);
|
||||||
|
await assert.isSenderAddressAsync('fromAddress', normalizedFromAddress, this._web3Wrapper);
|
||||||
assert.isValidBaseUnitAmount('amountInBaseUnits', amountInBaseUnits);
|
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)) {
|
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
|
||||||
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txHash = await tokenContract.transfer.sendTransactionAsync(toAddress, amountInBaseUnits, {
|
const txHash = await tokenContract.transfer.sendTransactionAsync(normalizedToAddress, amountInBaseUnits, {
|
||||||
from: fromAddress,
|
from: normalizedFromAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
});
|
});
|
||||||
@ -265,30 +300,39 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
amountInBaseUnits: BigNumber,
|
amountInBaseUnits: BigNumber,
|
||||||
txOpts: TransactionOpts = {},
|
txOpts: TransactionOpts = {},
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedToAddress = toAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('fromAddress', fromAddress);
|
const normalizedFromAddress = fromAddress.toLowerCase();
|
||||||
assert.isETHAddressHex('toAddress', toAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
await assert.isSenderAddressAsync('senderAddress', senderAddress, this._web3Wrapper);
|
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);
|
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)) {
|
if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
|
||||||
throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
|
throw new Error(ZeroExError.InsufficientAllowanceForTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
|
const fromAddressBalance = await this.getBalanceAsync(normalizedTokenAddress, normalizedFromAddress);
|
||||||
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
|
if (fromAddressBalance.lessThan(amountInBaseUnits)) {
|
||||||
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
throw new Error(ZeroExError.InsufficientBalanceForTransfer);
|
||||||
}
|
}
|
||||||
|
|
||||||
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
const txHash = await tokenContract.transferFrom.sendTransactionAsync(
|
||||||
fromAddress,
|
normalizedFromAddress,
|
||||||
toAddress,
|
normalizedToAddress,
|
||||||
amountInBaseUnits,
|
amountInBaseUnits,
|
||||||
{
|
{
|
||||||
from: senderAddress,
|
from: normalizedSenderAddress,
|
||||||
gas: txOpts.gasLimit,
|
gas: txOpts.gasLimit,
|
||||||
gasPrice: txOpts.gasPrice,
|
gasPrice: txOpts.gasPrice,
|
||||||
},
|
},
|
||||||
@ -310,12 +354,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
indexFilterValues: IndexedFilterValues,
|
indexFilterValues: IndexedFilterValues,
|
||||||
callback: EventCallback<ArgsType>,
|
callback: EventCallback<ArgsType>,
|
||||||
): string {
|
): string {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
assert.isFunction('callback', callback);
|
assert.isFunction('callback', callback);
|
||||||
const subscriptionToken = this._subscribe<ArgsType>(
|
const subscriptionToken = this._subscribe<ArgsType>(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
artifacts.TokenArtifact.abi,
|
artifacts.TokenArtifact.abi,
|
||||||
@ -351,12 +396,13 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
blockRange: BlockRange,
|
blockRange: BlockRange,
|
||||||
indexFilterValues: IndexedFilterValues,
|
indexFilterValues: IndexedFilterValues,
|
||||||
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
): Promise<Array<LogWithDecodedArgs<ArgsType>>> {
|
||||||
assert.isETHAddressHex('tokenAddress', tokenAddress);
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
assert.isETHAddressHex('tokenAddress', normalizedTokenAddress);
|
||||||
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
assert.doesBelongToStringEnum('eventName', eventName, TokenEvents);
|
||||||
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
assert.doesConformToSchema('blockRange', blockRange, schemas.blockRangeSchema);
|
||||||
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
assert.doesConformToSchema('indexFilterValues', indexFilterValues, schemas.indexFilterValuesSchema);
|
||||||
const logs = await this._getLogsAsync<ArgsType>(
|
const logs = await this._getLogsAsync<ArgsType>(
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
eventName,
|
eventName,
|
||||||
blockRange,
|
blockRange,
|
||||||
indexFilterValues,
|
indexFilterValues,
|
||||||
@ -369,17 +415,18 @@ export class TokenWrapper extends ContractWrapper {
|
|||||||
this._tokenContractsByAddress = {};
|
this._tokenContractsByAddress = {};
|
||||||
}
|
}
|
||||||
private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
|
private async _getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
|
||||||
let tokenContract = this._tokenContractsByAddress[tokenAddress];
|
const normalizedTokenAddress = tokenAddress.toLowerCase();
|
||||||
|
let tokenContract = this._tokenContractsByAddress[normalizedTokenAddress];
|
||||||
if (!_.isUndefined(tokenContract)) {
|
if (!_.isUndefined(tokenContract)) {
|
||||||
return tokenContract;
|
return tokenContract;
|
||||||
}
|
}
|
||||||
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
const web3ContractInstance = await this._instantiateContractIfExistsAsync(
|
||||||
artifacts.TokenArtifact,
|
artifacts.TokenArtifact,
|
||||||
tokenAddress,
|
normalizedTokenAddress,
|
||||||
);
|
);
|
||||||
const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
const contractInstance = new TokenContract(web3ContractInstance, this._web3Wrapper.getContractDefaults());
|
||||||
tokenContract = contractInstance;
|
tokenContract = contractInstance;
|
||||||
this._tokenContractsByAddress[tokenAddress] = tokenContract;
|
this._tokenContractsByAddress[normalizedTokenAddress] = tokenContract;
|
||||||
return tokenContract;
|
return tokenContract;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user