From b58bf8259db7378b841e6695d99580027b4e2969 Mon Sep 17 00:00:00 2001 From: Amir Bandeali Date: Tue, 5 Dec 2017 12:45:08 -0800 Subject: Add tests for ERC20Token and EtherToken_v2 --- packages/contracts/test/ts/erc20Token.ts | 123 +++++++++++++++++++++++++++ packages/contracts/test/ts/ether_token_v2.ts | 52 ++++++++++- 2 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 packages/contracts/test/ts/erc20Token.ts (limited to 'packages/contracts/test/ts') diff --git a/packages/contracts/test/ts/erc20Token.ts b/packages/contracts/test/ts/erc20Token.ts new file mode 100644 index 000000000..e2282cbf3 --- /dev/null +++ b/packages/contracts/test/ts/erc20Token.ts @@ -0,0 +1,123 @@ +import {ZeroEx} from '0x.js'; +import {BigNumber} from 'bignumber.js'; +import * as chai from 'chai'; +import * as Web3 from 'web3'; + +import {Artifacts} from '../../util/artifacts'; +import {constants} from '../../util/constants'; +import {ContractInstance} from '../../util/types'; + +import {chaiSetup} from './utils/chai_setup'; + +const {DummyToken} = new Artifacts(artifacts); +const web3: Web3 = (global as any).web3; +chaiSetup.configure(); +const expect = chai.expect; + +contract('ERC20Token', (accounts: string[]) => { + const zeroEx = new ZeroEx(web3.currentProvider); + const owner = accounts[0]; + const spender = accounts[1]; + + const MAX_MINT_VALUE = new BigNumber(100000000000000000000); + let tokenAddress: string; + let token: ContractInstance; + + beforeEach(async () => { + token = await DummyToken.new({from: owner}); + await token.mint(MAX_MINT_VALUE, {from: owner}); + tokenAddress = token.address; + }); + + describe('transfer', () => { + it('should throw if owner has insufficient balance', async () => { + const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = ownerBalance.plus(1); + return expect(token.transfer.call(owner, spender, amountToTransfer, {from: spender})) + .to.be.rejectedWith(constants.REVERT); + }); + + it('should transfer balance from sender to receiver', async () => { + const receiver = spender; + const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = new BigNumber(1); + await zeroEx.token.transferAsync(tokenAddress, owner, receiver, amountToTransfer); + const finalOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const finalReceiverBalance = await zeroEx.token.getBalanceAsync(tokenAddress, 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.call(spender, 0, {from: owner}); + expect(didReturnTrue).to.be.true(); + }); + }); + + describe('transferFrom', () => { + it('should throw if owner has insufficient balance', async () => { + const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = ownerBalance.plus(1); + await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, amountToTransfer); + return expect(token.transferFrom.call(owner, spender, amountToTransfer, {from: spender})) + .to.be.rejectedWith(constants.REVERT); + }); + + it('should throw if spender has insufficient allowance', async () => { + const ownerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = ownerBalance; + + const spenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender); + const spenderAllowanceIsInsufficient = spenderAllowance.cmp(amountToTransfer) < 0; + expect(spenderAllowanceIsInsufficient).to.be.true(); + + return expect(token.transferFrom.call(owner, spender, amountToTransfer, {from: spender})) + .to.be.rejectedWith(constants.REVERT); + }); + + it('should return true on a 0 value transfer', async () => { + const amountToTransfer = 0; + const didReturnTrue = await token.transferFrom.call(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 zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = initOwnerBalance; + const initSpenderAllowance = zeroEx.token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; + await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance); + await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer); + + const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender); + expect(initSpenderAllowance).to.be.bignumber.equal(newSpenderAllowance); + }); + + it('should transfer the correct balances if spender has sufficient allowance', async () => { + const initOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = initOwnerBalance; + const initSpenderAllowance = initOwnerBalance; + await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance); + await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer); + + const newOwnerBalance = await zeroEx.token.getBalanceAsync(tokenAddress, owner); + const newSpenderBalance = await zeroEx.token.getBalanceAsync(tokenAddress, 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 zeroEx.token.getBalanceAsync(tokenAddress, owner); + const amountToTransfer = initOwnerBalance; + const initSpenderAllowance = initOwnerBalance; + await zeroEx.token.setAllowanceAsync(tokenAddress, owner, spender, initSpenderAllowance); + await zeroEx.token.transferFromAsync(tokenAddress, owner, spender, spender, amountToTransfer); + + const newSpenderAllowance = await zeroEx.token.getAllowanceAsync(tokenAddress, owner, spender); + expect(newSpenderAllowance).to.be.bignumber.equal(0); + }); + }); +}); diff --git a/packages/contracts/test/ts/ether_token_v2.ts b/packages/contracts/test/ts/ether_token_v2.ts index 857371578..0c352b522 100644 --- a/packages/contracts/test/ts/ether_token_v2.ts +++ b/packages/contracts/test/ts/ether_token_v2.ts @@ -8,7 +8,7 @@ import {Artifacts} from '../../util/artifacts'; import {chaiSetup} from './utils/chai_setup'; -const {EtherToken} = new Artifacts(artifacts); +const {EtherTokenV2} = new Artifacts(artifacts); chaiSetup.configure(); const expect = chai.expect; @@ -17,13 +17,14 @@ const expect = chai.expect; // with type `any` to a variable of type `Web3`. const web3: Web3 = (global as any).web3; -contract('EtherToken', (accounts: string[]) => { +contract('EtherTokenV2', (accounts: string[]) => { const account = accounts[0]; const gasPrice = ZeroEx.toBaseUnitAmount(new BigNumber(20), 9); let zeroEx: ZeroEx; let etherTokenAddress: string; - before(async () => { - etherTokenAddress = EtherToken.address; + beforeEach(async () => { + const etherToken = await EtherTokenV2.new(); + etherTokenAddress = etherToken.address; zeroEx = new ZeroEx(web3.currentProvider, { gasPrice, etherTokenContractAddress: etherTokenAddress, @@ -62,9 +63,32 @@ contract('EtherToken', (accounts: string[]) => { expect(finalEthBalance).to.be.bignumber.equal(initEthBalance.minus(ethToDeposit.plus(ethSpentOnGas))); expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.plus(ethToDeposit)); }); + + it('should log 1 event with correct arguments', async () => { + const ethToDeposit = new BigNumber(web3.toWei(1, 'ether')); + + const txHash = await zeroEx.etherToken.depositAsync(ethToDeposit, account); + const receipt = await zeroEx.awaitTransactionMinedAsync(txHash); + + const logs = receipt.logs; + expect(logs.length).to.equal(1); + + const expectedFrom = ZeroEx.NULL_ADDRESS; + const expectedTo = account; + const expectedValue = ethToDeposit; + const logArgs = logs[0].args; + expect(logArgs._from).to.equal(expectedFrom); + expect(logArgs._to).to.equal(expectedTo); + expect(logArgs._value).to.be.bignumber.equal(ethToDeposit); + }); }); describe('withdraw', () => { + beforeEach(async () => { + const ethToDeposit = new BigNumber(web3.toWei(1, 'ether')); + await zeroEx.etherToken.depositAsync(ethToDeposit, account); + }); + it('should throw if caller attempts to withdraw greater than caller balance', async () => { const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); const ethTokensToWithdraw = initEthTokenBalance.plus(1); @@ -89,6 +113,26 @@ contract('EtherToken', (accounts: string[]) => { .equal(initEthBalance.plus(ethTokensToWithdraw.minus(ethSpentOnGas))); expect(finalEthTokenBalance).to.be.bignumber.equal(initEthTokenBalance.minus(ethTokensToWithdraw)); }); + + it('should log 1 event with correct arguments', async () => { + const initEthTokenBalance = await zeroEx.token.getBalanceAsync(etherTokenAddress, account); + const initEthBalance = await getEthBalanceAsync(account); + const ethTokensToWithdraw = initEthTokenBalance; + expect(ethTokensToWithdraw).to.not.be.bignumber.equal(0); + const txHash = await zeroEx.etherToken.withdrawAsync(ethTokensToWithdraw, account); + const receipt = await zeroEx.awaitTransactionMinedAsync(txHash); + + const logs = receipt.logs; + expect(logs.length).to.equal(1); + + const expectedFrom = account; + const expectedTo = ZeroEx.NULL_ADDRESS; + const expectedValue = ethTokensToWithdraw; + const logArgs = logs[0].args; + expect(logArgs._from).to.equal(expectedFrom); + expect(logArgs._to).to.equal(expectedTo); + expect(logArgs._value).to.be.bignumber.equal(ethTokensToWithdraw); + }); }); describe('fallback', () => { -- cgit