aboutsummaryrefslogtreecommitdiffstats
path: root/src/contract_wrappers
diff options
context:
space:
mode:
authorLeonid <logvinov.leon@gmail.com>2017-06-03 03:01:58 +0800
committerGitHub <noreply@github.com>2017-06-03 03:01:58 +0800
commit88815e5b4514e4953cc150241340e0b53dadc198 (patch)
treee8e0ba5b603f07bddf6cd01329e001b06b5987dd /src/contract_wrappers
parent5925f81fe185a90efaa82dd90bd8d65d74326f11 (diff)
parent36e937f8de348cfdb35ff8f72504aed1dfab07b2 (diff)
downloaddexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.tar
dexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.tar.gz
dexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.tar.bz2
dexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.tar.lz
dexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.tar.xz
dexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.tar.zst
dexon-0x-contracts-88815e5b4514e4953cc150241340e0b53dadc198.zip
Merge pull request #29 from 0xProject/remainingTokenMethods
Implement Remaining Token Methods
Diffstat (limited to 'src/contract_wrappers')
-rw-r--r--src/contract_wrappers/token_wrapper.ts89
1 files changed, 74 insertions, 15 deletions
diff --git a/src/contract_wrappers/token_wrapper.ts b/src/contract_wrappers/token_wrapper.ts
index 69bcc9024..c8b557d0d 100644
--- a/src/contract_wrappers/token_wrapper.ts
+++ b/src/contract_wrappers/token_wrapper.ts
@@ -33,21 +33,52 @@ export class TokenWrapper extends ContractWrapper {
return balance;
}
/**
- * Retrieves the allowance in baseUnits of the ERC20 token set to the 0x proxy contract
- * by an owner address.
+ * Sets the spender's allowance to a specified number of baseUnits on behalf of the owner address.
+ * Equivalent to the ERC20 spec method `approve`.
*/
- public async getProxyAllowanceAsync(tokenAddress: string, ownerAddress: string) {
+ public async setAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string,
+ amountInBaseUnits: BigNumber.BigNumber): Promise<void> {
assert.isETHAddressHex('ownerAddress', ownerAddress);
+ assert.isETHAddressHex('spenderAddress', spenderAddress);
assert.isETHAddressHex('tokenAddress', tokenAddress);
+ assert.isBigNumber('amountInBaseUnits', amountInBaseUnits);
const tokenContract = await this.getTokenContractAsync(tokenAddress);
- const proxyAddress = await this.getProxyAddressAsync();
- let allowanceInBaseUnits = await tokenContract.allowance.call(ownerAddress, proxyAddress);
+ // Hack: for some reason default estimated gas amount causes `base fee exceeds gas limit` exception
+ // on testrpc. Probably related to https://github.com/ethereumjs/testrpc/issues/294
+ // TODO: Debug issue in testrpc and submit a PR, then remove this hack
+ const networkIdIfExists = await this.web3Wrapper.getNetworkIdIfExistsAsync();
+ const gas = networkIdIfExists === constants.TESTRPC_NETWORK_ID ? ALLOWANCE_TO_ZERO_GAS_AMOUNT : undefined;
+ await tokenContract.approve(spenderAddress, amountInBaseUnits, {
+ from: ownerAddress,
+ gas,
+ });
+ }
+ /**
+ * Retrieves the owners allowance in baseUnits set to the spender's address.
+ */
+ public async getAllowanceAsync(tokenAddress: string, ownerAddress: string, spenderAddress: string) {
+ assert.isETHAddressHex('ownerAddress', ownerAddress);
+ assert.isETHAddressHex('tokenAddress', tokenAddress);
+
+ const tokenContract = await this.getTokenContractAsync(tokenAddress);
+ let allowanceInBaseUnits = await tokenContract.allowance.call(ownerAddress, spenderAddress);
// Wrap BigNumbers returned from web3 with our own (later) version of BigNumber
allowanceInBaseUnits = new BigNumber(allowanceInBaseUnits);
return allowanceInBaseUnits;
}
/**
+ * Retrieves the owner's allowance in baseUnits set to the 0x proxy contract.
+ */
+ public async getProxyAllowanceAsync(tokenAddress: string, ownerAddress: string) {
+ assert.isETHAddressHex('ownerAddress', ownerAddress);
+ assert.isETHAddressHex('tokenAddress', tokenAddress);
+
+ const proxyAddress = await this.getProxyAddressAsync();
+ const allowanceInBaseUnits = await this.getAllowanceAsync(tokenAddress, ownerAddress, proxyAddress);
+ return allowanceInBaseUnits;
+ }
+ /**
* Sets the 0x proxy contract's allowance to a specified number of a tokens' baseUnits on behalf
* of an owner address.
*/
@@ -57,17 +88,8 @@ export class TokenWrapper extends ContractWrapper {
assert.isETHAddressHex('tokenAddress', tokenAddress);
assert.isBigNumber('amountInBaseUnits', amountInBaseUnits);
- const tokenContract = await this.getTokenContractAsync(tokenAddress);
const proxyAddress = await this.getProxyAddressAsync();
- // Hack: for some reason default estimated gas amount causes `base fee exceeds gas limit` exception
- // on testrpc. Probably related to https://github.com/ethereumjs/testrpc/issues/294
- // TODO: Debug issue in testrpc and submit a PR, then remove this hack
- const networkIdIfExists = await this.web3Wrapper.getNetworkIdIfExistsAsync();
- const gas = networkIdIfExists === constants.TESTRPC_NETWORK_ID ? ALLOWANCE_TO_ZERO_GAS_AMOUNT : undefined;
- await tokenContract.approve(proxyAddress, amountInBaseUnits, {
- from: ownerAddress,
- gas,
- });
+ await this.setAllowanceAsync(tokenAddress, ownerAddress, proxyAddress, amountInBaseUnits);
}
/**
* Transfers `amountInBaseUnits` ERC20 tokens from `fromAddress` to `toAddress`.
@@ -80,10 +102,47 @@ export class TokenWrapper extends ContractWrapper {
assert.isBigNumber('amountInBaseUnits', amountInBaseUnits);
const tokenContract = await this.getTokenContractAsync(tokenAddress);
+
+ const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
+ if (fromAddressBalance.lessThan(amountInBaseUnits)) {
+ throw new Error(ZeroExError.INSUFFICIENT_BALANCE_FOR_TRANSFER);
+ }
+
await tokenContract.transfer(toAddress, amountInBaseUnits, {
from: fromAddress,
});
}
+ /**
+ * Transfers `amountInBaseUnits` ERC20 tokens from `fromAddress` to `toAddress`.
+ * Requires the fromAddress to have sufficient funds and to have approved an allowance of
+ * `amountInBaseUnits` for senderAddress.
+ */
+ public async transferFromAsync(tokenAddress: string, fromAddress: string, toAddress: string,
+ senderAddress: string, amountInBaseUnits: BigNumber.BigNumber):
+ Promise<void> {
+ assert.isETHAddressHex('tokenAddress', tokenAddress);
+ assert.isETHAddressHex('fromAddress', fromAddress);
+ assert.isETHAddressHex('toAddress', toAddress);
+ assert.isETHAddressHex('senderAddress', senderAddress);
+ assert.isBigNumber('amountInBaseUnits', amountInBaseUnits);
+ await assert.isSenderAddressAvailableAsync(this.web3Wrapper, senderAddress);
+
+ const tokenContract = await this.getTokenContractAsync(tokenAddress);
+
+ const fromAddressAllowance = await this.getAllowanceAsync(tokenAddress, fromAddress, senderAddress);
+ if (fromAddressAllowance.lessThan(amountInBaseUnits)) {
+ throw new Error(ZeroExError.INSUFFICIENT_ALLOWANCE_FOR_TRANSFER);
+ }
+
+ const fromAddressBalance = await this.getBalanceAsync(tokenAddress, fromAddress);
+ if (fromAddressBalance.lessThan(amountInBaseUnits)) {
+ throw new Error(ZeroExError.INSUFFICIENT_BALANCE_FOR_TRANSFER);
+ }
+
+ await tokenContract.transferFrom(fromAddress, toAddress, amountInBaseUnits, {
+ from: senderAddress,
+ });
+ }
private async getTokenContractAsync(tokenAddress: string): Promise<TokenContract> {
let tokenContract = this.tokenContractsByAddress[tokenAddress];
if (!_.isUndefined(tokenContract)) {