aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/test/tokens
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-07-02 17:12:01 +0800
committerFabio Berger <me@fabioberger.com>2018-07-02 17:12:01 +0800
commitde9f0732a09893f035ce8a7e8e01fa1141882a3a (patch)
tree63d1f0bbc6f9d65576e5d12b379378700eb88567 /packages/contracts/test/tokens
parent20acdbf6c3ba6a62e87a9a496021cb6482c0c03a (diff)
parentb9b00e10d39c3c84bc72892ef37f1313e904414d (diff)
downloaddexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.tar
dexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.tar.gz
dexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.tar.bz2
dexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.tar.lz
dexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.tar.xz
dexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.tar.zst
dexon-sol-tools-de9f0732a09893f035ce8a7e8e01fa1141882a3a.zip
Merge branch 'v2-prototype' into fix/five_decimal_scenario
* v2-prototype: (75 commits) Update relayer grid tiles to use Text Fix build Update file structure Update 2.0.0 artifacts Move ledgerhq module declarations to typescript-typings Export LedgerEthereumClient type in subproviders Update artifacts Add logging and updated artifacts Fix migrations Run prettier Add Kovan artifacts Use ledger subprovider Add Kovan migrations Remove state variable from Link component in Portal Make registerAssetProxy append only Update staging api link Change getTransactionReceipt to awaitTransactionMined Move /docs route to the end Remove extra call to scrollIntoView for wallet in onboarding Update expectRevertReasonOrAlwaysFailingTransactionAsync to check status codes ...
Diffstat (limited to 'packages/contracts/test/tokens')
-rw-r--r--packages/contracts/test/tokens/ether_token.ts138
-rw-r--r--packages/contracts/test/tokens/unlimited_allowance_token.ts191
-rw-r--r--packages/contracts/test/tokens/zrx_token.ts206
3 files changed, 535 insertions, 0 deletions
diff --git a/packages/contracts/test/tokens/ether_token.ts b/packages/contracts/test/tokens/ether_token.ts
new file mode 100644
index 000000000..25ef15595
--- /dev/null
+++ b/packages/contracts/test/tokens/ether_token.ts
@@ -0,0 +1,138 @@
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as chai from 'chai';
+
+import { WETH9Contract } from '../../generated_contract_wrappers/weth9';
+import { artifacts } from '../utils/artifacts';
+import { expectInsufficientFundsAsync, expectRevertOrAlwaysFailingTransactionAsync } from '../utils/assertions';
+import { chaiSetup } from '../utils/chai_setup';
+import { constants } from '../utils/constants';
+import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
+
+chaiSetup.configure();
+const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
+describe('EtherToken', () => {
+ let account: string;
+ const gasPrice = Web3Wrapper.toBaseUnitAmount(new BigNumber(20), 9);
+ let etherToken: WETH9Contract;
+
+ before(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ before(async () => {
+ const accounts = await web3Wrapper.getAvailableAddressesAsync();
+ account = accounts[0];
+
+ etherToken = await WETH9Contract.deployFrom0xArtifactAsync(artifacts.EtherToken, provider, {
+ gasPrice,
+ ...txDefaults,
+ });
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ describe('deposit', () => {
+ it('should throw if caller attempts to deposit more Ether than caller balance', async () => {
+ const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const ethToDeposit = initEthBalance.plus(1);
+
+ return expectInsufficientFundsAsync(etherToken.deposit.sendTransactionAsync({ value: ethToDeposit }));
+ });
+
+ it('should convert deposited Ether to wrapped Ether tokens', async () => {
+ const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+
+ const ethToDeposit = new BigNumber(Web3Wrapper.toWei(new BigNumber(1)));
+
+ const txHash = await etherToken.deposit.sendTransactionAsync({ value: ethToDeposit });
+ const receipt = await web3Wrapper.awaitTransactionSuccessAsync(
+ txHash,
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+ const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const finalEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+
+ expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
+ expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
+ });
+ });
+
+ describe('withdraw', () => {
+ it('should throw if caller attempts to withdraw greater than caller balance', async () => {
+ const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+ const ethTokensToWithdraw = initEthTokenBalance.plus(1);
+
+ return expectRevertOrAlwaysFailingTransactionAsync(
+ etherToken.withdraw.sendTransactionAsync(ethTokensToWithdraw),
+ );
+ });
+
+ it('should convert ether tokens to ether with sufficient balance', async () => {
+ const ethToDeposit = new BigNumber(Web3Wrapper.toWei(new BigNumber(1)));
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await etherToken.deposit.sendTransactionAsync({ value: ethToDeposit }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+ const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const ethTokensToWithdraw = initEthTokenBalance;
+ expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0);
+ const txHash = await etherToken.withdraw.sendTransactionAsync(ethTokensToWithdraw, {
+ gas: constants.MAX_ETHERTOKEN_WITHDRAW_GAS,
+ });
+ const receipt = await web3Wrapper.awaitTransactionSuccessAsync(
+ txHash,
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+ const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const finalEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+
+ expect(finalEthBalance).to.be.bignumber.equal(
+ initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas)),
+ );
+ expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw));
+ });
+ });
+
+ describe('fallback', () => {
+ it('should convert sent ether to ether tokens', async () => {
+ const initEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const initEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+
+ const ethToDeposit = Web3Wrapper.toBaseUnitAmount(new BigNumber(1), 18);
+
+ const txHash = await web3Wrapper.sendTransactionAsync({
+ from: account,
+ to: etherToken.address,
+ value: ethToDeposit,
+ gasPrice,
+ });
+
+ const receipt = await web3Wrapper.awaitTransactionSuccessAsync(
+ txHash,
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const ethSpentOnGas = gasPrice.times(receipt.gasUsed);
+ const finalEthBalance = await web3Wrapper.getBalanceInWeiAsync(account);
+ const finalEthTokenBalance = await etherToken.balanceOf.callAsync(account);
+
+ expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas)));
+ expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit));
+ });
+ });
+});
diff --git a/packages/contracts/test/tokens/unlimited_allowance_token.ts b/packages/contracts/test/tokens/unlimited_allowance_token.ts
new file mode 100644
index 000000000..09a24950c
--- /dev/null
+++ b/packages/contracts/test/tokens/unlimited_allowance_token.ts
@@ -0,0 +1,191 @@
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { RevertReason } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import * as chai from 'chai';
+
+import { DummyERC20TokenContract } from '../../generated_contract_wrappers/dummy_e_r_c20_token';
+import { artifacts } from '../utils/artifacts';
+import { expectRevertOrOtherErrorAsync } from '../utils/assertions';
+import { chaiSetup } from '../utils/chai_setup';
+import { constants } from '../utils/constants';
+import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
+
+chaiSetup.configure();
+const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
+describe('UnlimitedAllowanceToken', () => {
+ let owner: string;
+ let spender: string;
+ const MAX_MINT_VALUE = new BigNumber(100000000000000000000);
+ let token: DummyERC20TokenContract;
+
+ before(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ before(async () => {
+ const accounts = await web3Wrapper.getAvailableAddressesAsync();
+ owner = accounts[0];
+ spender = accounts[1];
+ token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
+ artifacts.DummyERC20Token,
+ provider,
+ txDefaults,
+ constants.DUMMY_TOKEN_NAME,
+ constants.DUMMY_TOKEN_SYMBOL,
+ constants.DUMMY_TOKEN_DECIMALS,
+ constants.DUMMY_TOKEN_TOTAL_SUPPLY,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.mint.sendTransactionAsync(MAX_MINT_VALUE, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ describe('transfer', () => {
+ it('should throw if owner has insufficient balance', async () => {
+ const ownerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = ownerBalance.plus(1);
+ return expectRevertOrOtherErrorAsync(
+ token.transfer.callAsync(spender, amountToTransfer, { from: owner }),
+ RevertReason.Erc20InsufficientBalance,
+ );
+ });
+
+ it('should transfer balance from sender to receiver', async () => {
+ const receiver = spender;
+ const initOwnerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = new BigNumber(1);
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.transfer.sendTransactionAsync(receiver, amountToTransfer, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ const finalOwnerBalance = await token.balanceOf.callAsync(owner);
+ const finalReceiverBalance = await token.balanceOf.callAsync(receiver);
+
+ const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+ const expectedFinalReceiverBalance = amountToTransfer;
+ expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+ expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+ });
+
+ it('should return true on a 0 value transfer', async () => {
+ const didReturnTrue = await token.transfer.callAsync(spender, new BigNumber(0), {
+ from: owner,
+ });
+ expect(didReturnTrue).to.be.true();
+ });
+ });
+
+ describe('transferFrom', () => {
+ it('should throw if owner has insufficient balance', async () => {
+ const ownerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = ownerBalance.plus(1);
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.approve.sendTransactionAsync(spender, amountToTransfer, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ return expectRevertOrOtherErrorAsync(
+ token.transferFrom.callAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ }),
+ RevertReason.Erc20InsufficientBalance,
+ );
+ });
+
+ it('should throw if spender has insufficient allowance', async () => {
+ const ownerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = ownerBalance;
+
+ const spenderAllowance = await token.allowance.callAsync(owner, spender);
+ const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+ expect(isSpenderAllowanceInsufficient).to.be.true();
+
+ return expectRevertOrOtherErrorAsync(
+ token.transferFrom.callAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ }),
+ RevertReason.Erc20InsufficientAllowance,
+ );
+ });
+
+ it('should return true on a 0 value transfer', async () => {
+ const amountToTransfer = new BigNumber(0);
+ const didReturnTrue = await token.transferFrom.callAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ });
+ expect(didReturnTrue).to.be.true();
+ });
+
+ it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+ const initOwnerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = initOwnerBalance;
+ const initSpenderAllowance = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const newSpenderAllowance = await token.allowance.callAsync(owner, spender);
+ expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+ });
+
+ it('should transfer the correct balances if spender has sufficient allowance', async () => {
+ const initOwnerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = initOwnerBalance;
+ const initSpenderAllowance = initOwnerBalance;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const newOwnerBalance = await token.balanceOf.callAsync(owner);
+ const newSpenderBalance = await token.balanceOf.callAsync(spender);
+
+ expect(newOwnerBalance).to.be.bignumber.equal(0);
+ expect(newSpenderBalance).to.be.bignumber.equal(initOwnerBalance);
+ });
+
+ it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+ const initOwnerBalance = await token.balanceOf.callAsync(owner);
+ const amountToTransfer = initOwnerBalance;
+ const initSpenderAllowance = initOwnerBalance;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.approve.sendTransactionAsync(spender, initSpenderAllowance, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await token.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const newSpenderAllowance = await token.allowance.callAsync(owner, spender);
+ expect(newSpenderAllowance).to.be.bignumber.equal(0);
+ });
+ });
+});
diff --git a/packages/contracts/test/tokens/zrx_token.ts b/packages/contracts/test/tokens/zrx_token.ts
new file mode 100644
index 000000000..a0d77c924
--- /dev/null
+++ b/packages/contracts/test/tokens/zrx_token.ts
@@ -0,0 +1,206 @@
+import { BlockchainLifecycle } from '@0xproject/dev-utils';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as chai from 'chai';
+
+import { ZRXTokenContract } from '../../generated_contract_wrappers/zrx_token';
+import { artifacts } from '../utils/artifacts';
+import { chaiSetup } from '../utils/chai_setup';
+import { constants } from '../utils/constants';
+import { provider, txDefaults, web3Wrapper } from '../utils/web3_wrapper';
+
+chaiSetup.configure();
+const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper);
+
+describe('ZRXToken', () => {
+ let owner: string;
+ let spender: string;
+ let MAX_UINT: BigNumber;
+ let zrxToken: ZRXTokenContract;
+
+ before(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ after(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ before(async () => {
+ const accounts = await web3Wrapper.getAvailableAddressesAsync();
+ owner = accounts[0];
+ spender = accounts[1];
+ zrxToken = await ZRXTokenContract.deployFrom0xArtifactAsync(artifacts.ZRX, provider, txDefaults);
+ MAX_UINT = constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS;
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ });
+ describe('constants', () => {
+ it('should have 18 decimals', async () => {
+ const decimals = new BigNumber(await zrxToken.decimals.callAsync());
+ const expectedDecimals = 18;
+ expect(decimals).to.be.bignumber.equal(expectedDecimals);
+ });
+
+ it('should have a total supply of 1 billion tokens', async () => {
+ const totalSupply = new BigNumber(await zrxToken.totalSupply.callAsync());
+ const expectedTotalSupply = 1000000000;
+ expect(Web3Wrapper.toUnitAmount(totalSupply, 18)).to.be.bignumber.equal(expectedTotalSupply);
+ });
+
+ it('should be named 0x Protocol Token', async () => {
+ const name = await zrxToken.name.callAsync();
+ const expectedName = '0x Protocol Token';
+ expect(name).to.be.equal(expectedName);
+ });
+
+ it('should have the symbol ZRX', async () => {
+ const symbol = await zrxToken.symbol.callAsync();
+ const expectedSymbol = 'ZRX';
+ expect(symbol).to.be.equal(expectedSymbol);
+ });
+ });
+
+ describe('constructor', () => {
+ it('should initialize owner balance to totalSupply', async () => {
+ const ownerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const totalSupply = new BigNumber(await zrxToken.totalSupply.callAsync());
+ expect(totalSupply).to.be.bignumber.equal(ownerBalance);
+ });
+ });
+
+ describe('transfer', () => {
+ it('should transfer balance from sender to receiver', async () => {
+ const receiver = spender;
+ const initOwnerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const amountToTransfer = new BigNumber(1);
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.transfer.sendTransactionAsync(receiver, amountToTransfer, { from: owner }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ const finalOwnerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const finalReceiverBalance = await zrxToken.balanceOf.callAsync(receiver);
+
+ const expectedFinalOwnerBalance = initOwnerBalance.minus(amountToTransfer);
+ const expectedFinalReceiverBalance = amountToTransfer;
+ expect(finalOwnerBalance).to.be.bignumber.equal(expectedFinalOwnerBalance);
+ expect(finalReceiverBalance).to.be.bignumber.equal(expectedFinalReceiverBalance);
+ });
+
+ it('should return true on a 0 value transfer', async () => {
+ const didReturnTrue = await zrxToken.transfer.callAsync(spender, new BigNumber(0), {
+ from: owner,
+ });
+ expect(didReturnTrue).to.be.true();
+ });
+ });
+
+ describe('transferFrom', () => {
+ it('should return false if owner has insufficient balance', async () => {
+ const ownerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const amountToTransfer = ownerBalance.plus(1);
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.approve.sendTransactionAsync(spender, amountToTransfer, {
+ from: owner,
+ gas: constants.MAX_TOKEN_APPROVE_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ const didReturnTrue = await zrxToken.transferFrom.callAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ });
+ expect(didReturnTrue).to.be.false();
+ });
+
+ it('should return false if spender has insufficient allowance', async () => {
+ const ownerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const amountToTransfer = ownerBalance;
+
+ const spenderAllowance = await zrxToken.allowance.callAsync(owner, spender);
+ const isSpenderAllowanceInsufficient = spenderAllowance.cmp(amountToTransfer) < 0;
+ expect(isSpenderAllowanceInsufficient).to.be.true();
+
+ const didReturnTrue = await zrxToken.transferFrom.callAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ });
+ expect(didReturnTrue).to.be.false();
+ });
+
+ it('should return true on a 0 value transfer', async () => {
+ const amountToTransfer = new BigNumber(0);
+ const didReturnTrue = await zrxToken.transferFrom.callAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ });
+ expect(didReturnTrue).to.be.true();
+ });
+
+ it('should not modify spender allowance if spender allowance is 2^256 - 1', async () => {
+ const initOwnerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const amountToTransfer = initOwnerBalance;
+ const initSpenderAllowance = MAX_UINT;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.approve.sendTransactionAsync(spender, initSpenderAllowance, {
+ from: owner,
+ gas: constants.MAX_TOKEN_APPROVE_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const newSpenderAllowance = await zrxToken.allowance.callAsync(owner, spender);
+ expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance);
+ });
+
+ it('should transfer the correct balances if spender has sufficient allowance', async () => {
+ const initOwnerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const initSpenderBalance = await zrxToken.balanceOf.callAsync(spender);
+ const amountToTransfer = initOwnerBalance;
+ const initSpenderAllowance = initOwnerBalance;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.approve.sendTransactionAsync(spender, initSpenderAllowance),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const newOwnerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const newSpenderBalance = await zrxToken.balanceOf.callAsync(spender);
+
+ expect(newOwnerBalance).to.be.bignumber.equal(0);
+ expect(newSpenderBalance).to.be.bignumber.equal(initSpenderBalance.plus(initOwnerBalance));
+ });
+
+ it('should modify allowance if spender has sufficient allowance less than 2^256 - 1', async () => {
+ const initOwnerBalance = await zrxToken.balanceOf.callAsync(owner);
+ const amountToTransfer = initOwnerBalance;
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.approve.sendTransactionAsync(spender, amountToTransfer),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+ await web3Wrapper.awaitTransactionSuccessAsync(
+ await zrxToken.transferFrom.sendTransactionAsync(owner, spender, amountToTransfer, {
+ from: spender,
+ gas: constants.MAX_TOKEN_TRANSFERFROM_GAS,
+ }),
+ constants.AWAIT_TRANSACTION_MINED_MS,
+ );
+
+ const newSpenderAllowance = await zrxToken.allowance.callAsync(owner, spender);
+ expect(newSpenderAllowance).to.be.bignumber.equal(0);
+ });
+ });
+});