diff options
Diffstat (limited to 'packages/contract-wrappers/test/ether_token_wrapper_test.ts')
-rw-r--r-- | packages/contract-wrappers/test/ether_token_wrapper_test.ts | 437 |
1 files changed, 0 insertions, 437 deletions
diff --git a/packages/contract-wrappers/test/ether_token_wrapper_test.ts b/packages/contract-wrappers/test/ether_token_wrapper_test.ts deleted file mode 100644 index cc2419aa2..000000000 --- a/packages/contract-wrappers/test/ether_token_wrapper_test.ts +++ /dev/null @@ -1,437 +0,0 @@ -import { ContractAddresses } from '@0x/contract-addresses'; -import { BlockchainLifecycle, callbackErrorReporter } from '@0x/dev-utils'; -import { DoneCallback } from '@0x/types'; -import { BigNumber } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; -import * as chai from 'chai'; -import 'mocha'; - -import { - BlockParamLiteral, - BlockRange, - ContractWrappers, - ContractWrappersError, - WETH9ApprovalEventArgs, - WETH9DepositEventArgs, - WETH9Events, - WETH9TransferEventArgs, - WETH9WithdrawalEventArgs, -} from '../src'; -import { DecodedLogEvent } from '../src/types'; - -import { chaiSetup } from './utils/chai_setup'; -import { constants } from './utils/constants'; -import { migrateOnceAsync } from './utils/migrate'; -import { provider, web3Wrapper } from './utils/web3_wrapper'; - -chaiSetup.configure(); -const expect = chai.expect; -const blockchainLifecycle = new BlockchainLifecycle(web3Wrapper); - -// Since the address depositing/withdrawing ETH/WETH also needs to pay gas costs for the transaction, -// a small amount of ETH will be used to pay this gas cost. We therefore check that the difference between -// the expected balance and actual balance (given the amount of ETH deposited), only deviates by the amount -// required to pay gas costs. -const MAX_REASONABLE_GAS_COST_IN_WEI = 62517; - -describe('EtherTokenWrapper', () => { - let contractWrappers: ContractWrappers; - let contractAddresses: ContractAddresses; - let userAddresses: string[]; - let addressWithETH: string; - let wethContractAddress: string; - let depositWeiAmount: BigNumber; - const decimalPlaces = 7; - let addressWithoutFunds: string; - const gasPrice = new BigNumber(1); - const transferAmount = new BigNumber(42); - const allowanceAmount = new BigNumber(42); - const depositAmount = new BigNumber(42); - const withdrawalAmount = new BigNumber(42); - before(async () => { - contractAddresses = await migrateOnceAsync(); - const config = { - gasPrice, - networkId: constants.TESTRPC_NETWORK_ID, - contractAddresses, - blockPollingIntervalMs: 10, - }; - contractWrappers = new ContractWrappers(provider, config); - userAddresses = await web3Wrapper.getAvailableAddressesAsync(); - addressWithETH = userAddresses[0]; - wethContractAddress = contractAddresses.etherToken; - depositWeiAmount = Web3Wrapper.toWei(new BigNumber(5)); - addressWithoutFunds = userAddresses[1]; - }); - beforeEach(async () => { - await blockchainLifecycle.startAsync(); - }); - afterEach(async () => { - await blockchainLifecycle.revertAsync(); - }); - describe('#getContractAddressIfExists', async () => { - it('should return contract address if connected to a known network', () => { - const contractAddressIfExists = contractAddresses.etherToken; - expect(contractAddressIfExists).to.not.be.undefined(); - }); - it('should throw if connected to a private network and contract addresses are not specified', () => { - const UNKNOWN_NETWORK_NETWORK_ID = 10; - expect( - () => - new ContractWrappers(provider, { - networkId: UNKNOWN_NETWORK_NETWORK_ID, - } as any), - ).to.throw(); - }); - }); - describe('#depositAsync', () => { - it('should successfully deposit ETH and issue Wrapped ETH tokens', async () => { - const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync( - wethContractAddress, - addressWithETH, - ); - expect(preETHBalance).to.be.bignumber.gt(0); - expect(preWETHBalance).to.be.bignumber.equal(0); - - const txHash = await contractWrappers.etherToken.depositAsync( - wethContractAddress, - depositWeiAmount, - addressWithETH, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - - const postETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync( - wethContractAddress, - addressWithETH, - ); - - expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(depositWeiAmount); - const remainingETHInWei = preETHBalance.minus(depositWeiAmount); - const gasCost = remainingETHInWei.minus(postETHBalanceInWei); - expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI); - }); - it('should throw if user has insufficient ETH balance for deposit', async () => { - const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - - const extraETHBalance = Web3Wrapper.toWei(new BigNumber(5)); - const overETHBalanceinWei = preETHBalance.plus(extraETHBalance); - - return expect( - contractWrappers.etherToken.depositAsync(wethContractAddress, overETHBalanceinWei, addressWithETH), - ).to.be.rejectedWith(ContractWrappersError.InsufficientEthBalanceForDeposit); - }); - }); - describe('#withdrawAsync', () => { - it('should successfully withdraw ETH in return for Wrapped ETH tokens', async () => { - const ETHBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - - await contractWrappers.etherToken.depositAsync(wethContractAddress, depositWeiAmount, addressWithETH); - - const expectedPreETHBalance = ETHBalanceInWei.minus(depositWeiAmount); - const preETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync( - wethContractAddress, - addressWithETH, - ); - let gasCost = expectedPreETHBalance.minus(preETHBalance); - expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI); - expect(preWETHBalance).to.be.bignumber.equal(depositWeiAmount); - - const txHash = await contractWrappers.etherToken.withdrawAsync( - wethContractAddress, - depositWeiAmount, - addressWithETH, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - - const postETHBalance = await web3Wrapper.getBalanceInWeiAsync(addressWithETH); - const postWETHBalanceInBaseUnits = await contractWrappers.erc20Token.getBalanceAsync( - wethContractAddress, - addressWithETH, - ); - - expect(postWETHBalanceInBaseUnits).to.be.bignumber.equal(0); - const expectedETHBalance = preETHBalance.plus(depositWeiAmount).integerValue(decimalPlaces); - gasCost = expectedETHBalance.minus(postETHBalance); - expect(gasCost).to.be.bignumber.lte(MAX_REASONABLE_GAS_COST_IN_WEI); - }); - it('should throw if user has insufficient WETH balance for withdrawal', async () => { - const preWETHBalance = await contractWrappers.erc20Token.getBalanceAsync( - wethContractAddress, - addressWithETH, - ); - expect(preWETHBalance).to.be.bignumber.equal(0); - - // tslint:disable-next-line:custom-no-magic-numbers - const overWETHBalance = preWETHBalance.plus(999999999); - - return expect( - contractWrappers.etherToken.withdrawAsync(wethContractAddress, overWETHBalance, addressWithETH), - ).to.be.rejectedWith(ContractWrappersError.InsufficientWEthBalanceForWithdrawal); - }); - }); - describe('#subscribe', () => { - const indexFilterValues = {}; - let etherTokenAddress: string; - before(async () => { - etherTokenAddress = contractAddresses.etherToken; - }); - afterEach(() => { - contractWrappers.etherToken.unsubscribeAll(); - }); - // Hack: Mocha does not allow a test to be both async and have a `done` callback - // Since we need to await the receipt of the event in the `subscribe` callback, - // we do need both. A hack is to make the top-level async fn w/ a done callback and then - // wrap the rest of the test in an async block - // Source: https://github.com/mochajs/mocha/issues/2407 - it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => { - (async () => { - const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<WETH9TransferEventArgs>) => { - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - expect(logEvent.log.logIndex).to.be.equal(0); - expect(logEvent.log.transactionIndex).to.be.equal(0); - expect(logEvent.log.blockNumber).to.be.a('number'); - const args = logEvent.log.args; - expect(args._from).to.be.equal(addressWithETH); - expect(args._to).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.bignumber.equal(transferAmount); - }, - ); - await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); - contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Transfer, - indexFilterValues, - callback, - ); - await contractWrappers.erc20Token.transferAsync( - etherTokenAddress, - addressWithETH, - addressWithoutFunds, - transferAmount, - ); - })().catch(done); - }); - it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => { - (async () => { - const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => { - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(addressWithETH); - expect(args._spender).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.bignumber.equal(allowanceAmount); - }, - ); - contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Approval, - indexFilterValues, - callback, - ); - await contractWrappers.erc20Token.setAllowanceAsync( - etherTokenAddress, - addressWithETH, - addressWithoutFunds, - allowanceAmount, - ); - })().catch(done); - }); - it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => { - (async () => { - const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<WETH9DepositEventArgs>) => { - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(addressWithETH); - expect(args._value).to.be.bignumber.equal(depositAmount); - }, - ); - contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Deposit, - indexFilterValues, - callback, - ); - await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); - })().catch(done); - }); - it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => { - (async () => { - const callback = callbackErrorReporter.reportNodeCallbackErrors(done)( - (logEvent: DecodedLogEvent<WETH9WithdrawalEventArgs>) => { - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(addressWithETH); - expect(args._value).to.be.bignumber.equal(depositAmount); - }, - ); - await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); - contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Withdrawal, - indexFilterValues, - callback, - ); - await contractWrappers.etherToken.withdrawAsync(etherTokenAddress, withdrawalAmount, addressWithETH); - })().catch(done); - }); - it('should cancel outstanding subscriptions when contractWrappers.unsubscribeAll is called', (done: DoneCallback) => { - (async () => { - const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }, - ); - contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Transfer, - indexFilterValues, - callbackNeverToBeCalled, - ); - const callbackToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)(); - contractWrappers.unsubscribeAll(); - await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); - contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Transfer, - indexFilterValues, - callbackToBeCalled, - ); - await contractWrappers.erc20Token.transferAsync( - etherTokenAddress, - addressWithETH, - addressWithoutFunds, - transferAmount, - ); - })().catch(done); - }); - it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { - (async () => { - const callbackNeverToBeCalled = callbackErrorReporter.reportNodeCallbackErrors(done)( - (_logEvent: DecodedLogEvent<WETH9ApprovalEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }, - ); - await contractWrappers.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); - const subscriptionToken = contractWrappers.etherToken.subscribe( - etherTokenAddress, - WETH9Events.Transfer, - indexFilterValues, - callbackNeverToBeCalled, - ); - contractWrappers.etherToken.unsubscribe(subscriptionToken); - await contractWrappers.erc20Token.transferAsync( - etherTokenAddress, - addressWithETH, - addressWithoutFunds, - transferAmount, - ); - done(); - })().catch(done); - }); - }); - describe('#getLogsAsync', () => { - let etherTokenAddress: string; - let erc20ProxyAddress: string; - let blockRange: BlockRange; - let txHash: string; - before(async () => { - addressWithETH = userAddresses[0]; - etherTokenAddress = contractAddresses.etherToken; - erc20ProxyAddress = contractWrappers.erc20Proxy.address; - // Start the block range after all migrations to avoid unexpected logs - const currentBlock: number = await web3Wrapper.getBlockNumberAsync(); - const fromBlock = currentBlock + 1; - blockRange = { - fromBlock, - toBlock: BlockParamLiteral.Latest, - }; - }); - it('should get logs with decoded args emitted by Approval', async () => { - txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( - etherTokenAddress, - addressWithETH, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - const eventName = WETH9Events.Approval; - const indexFilterValues = {}; - const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>( - etherTokenAddress, - eventName, - blockRange, - indexFilterValues, - ); - expect(logs).to.have.length(1); - const args = logs[0].args; - expect(logs[0].event).to.be.equal(eventName); - expect(args._owner).to.be.equal(addressWithETH); - expect(args._spender).to.be.equal(erc20ProxyAddress); - expect(args._value).to.be.bignumber.equal(contractWrappers.erc20Token.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); - }); - it('should get logs with decoded args emitted by Deposit', async () => { - await contractWrappers.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); - const eventName = WETH9Events.Deposit; - const indexFilterValues = {}; - const logs = await contractWrappers.etherToken.getLogsAsync<WETH9DepositEventArgs>( - etherTokenAddress, - eventName, - blockRange, - indexFilterValues, - ); - expect(logs).to.have.length(1); - const args = logs[0].args; - expect(logs[0].event).to.be.equal(eventName); - expect(args._owner).to.be.equal(addressWithETH); - expect(args._value).to.be.bignumber.equal(depositAmount); - }); - it('should only get the logs with the correct event name', async () => { - txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( - etherTokenAddress, - addressWithETH, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - const differentEventName = WETH9Events.Transfer; - const indexFilterValues = {}; - const logs = await contractWrappers.etherToken.getLogsAsync( - etherTokenAddress, - differentEventName, - blockRange, - indexFilterValues, - ); - expect(logs).to.have.length(0); - }); - it('should only get the logs with the correct indexed fields', async () => { - txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( - etherTokenAddress, - addressWithETH, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - txHash = await contractWrappers.erc20Token.setUnlimitedProxyAllowanceAsync( - etherTokenAddress, - addressWithoutFunds, - ); - await web3Wrapper.awaitTransactionSuccessAsync(txHash, constants.AWAIT_TRANSACTION_MINED_MS); - const eventName = WETH9Events.Approval; - const indexFilterValues = { - _owner: addressWithETH, - }; - const logs = await contractWrappers.etherToken.getLogsAsync<WETH9ApprovalEventArgs>( - etherTokenAddress, - eventName, - blockRange, - indexFilterValues, - ); - expect(logs).to.have.length(1); - const args = logs[0].args; - expect(args._owner).to.be.equal(addressWithETH); - }); - }); -}); |