diff options
author | Fabio Berger <me@fabioberger.com> | 2018-06-13 22:10:05 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-06-13 22:10:05 +0800 |
commit | b4fead9606ecc9655b2038fcef1c75217752f67d (patch) | |
tree | b363eee11085850328837004b41ff23c5d31efb6 /packages/contracts/test | |
parent | 61243b418e4d962cd8d8a1d7a49f04510b3c1c7f (diff) | |
parent | 4efd28c092e74b438d0397069c0c55cc90c537f2 (diff) | |
download | dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.tar dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.tar.gz dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.tar.bz2 dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.tar.lz dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.tar.xz dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.tar.zst dexon-sol-tools-b4fead9606ecc9655b2038fcef1c75217752f67d.zip |
Merge branch 'v2-prototype' into feature/combinatorial-testing
* v2-prototype: (26 commits)
Rename _coverageCollector -> _profilerCollector in TraceCollectionSubprovider
Refactor sol-cov to de-duplicate code for coverage and profiling
Rename popByte and popAddress
Hard code test addresses/bytes32 instead of generating pseudorandom ones
Update artifacts
Rename computeCoverageAsync -> computeSingleTraceCoverageAsync
Fix linter errors
Refactor sol-cov to avoid keeping traceInfo in memory
Unpop byte rather than making deep copy
Pass gas in to marketBuyOrdersNoThrow
Looks up the memory location of makerAssetData/takerAssetData
Make ZRX_PROXY_ID constant rather than popping it from ZRX_ASSET_DATA
Add tests for deepCopyBytes and missing write methods from LibBytes
Pop id from assetData before dispatching to AssetProxies
Upgrade solidity-parser-entlr 0.2.11 => 0.2.12
Fix import order
Fix typos
Add CHANGELOGs
Speed-up sol-cov
Increase delay when sending transactions during devnet startup
...
Diffstat (limited to 'packages/contracts/test')
-rw-r--r-- | packages/contracts/test/asset_proxy/decoder.ts | 21 | ||||
-rw-r--r-- | packages/contracts/test/asset_proxy/proxies.ts | 68 | ||||
-rw-r--r-- | packages/contracts/test/exchange/core.ts | 2 | ||||
-rw-r--r-- | packages/contracts/test/exchange/dispatcher.ts | 8 | ||||
-rw-r--r-- | packages/contracts/test/exchange/match_orders.ts | 2 | ||||
-rw-r--r-- | packages/contracts/test/exchange/transactions.ts | 2 | ||||
-rw-r--r-- | packages/contracts/test/exchange/wrapper.ts | 105 | ||||
-rw-r--r-- | packages/contracts/test/libraries/lib_bytes.ts | 264 |
8 files changed, 332 insertions, 140 deletions
diff --git a/packages/contracts/test/asset_proxy/decoder.ts b/packages/contracts/test/asset_proxy/decoder.ts index d4fae1601..875d55daa 100644 --- a/packages/contracts/test/asset_proxy/decoder.ts +++ b/packages/contracts/test/asset_proxy/decoder.ts @@ -42,33 +42,19 @@ describe('TestAssetDataDecoders', () => { }); describe('Asset Data Decoders', () => { - it('should correctly decode ERC20 asset data)', async () => { - const encodedAssetData = assetProxyUtils.encodeERC20AssetData(testAddress); - const expectedDecodedAssetData = assetProxyUtils.decodeERC20AssetData(encodedAssetData); - let decodedAssetProxyId: number; - let decodedTokenAddress: string; - [decodedAssetProxyId, decodedTokenAddress] = await testAssetProxyDecoder.publicDecodeERC20Data.callAsync( - encodedAssetData, - ); - expect(decodedAssetProxyId).to.be.equal(expectedDecodedAssetData.assetProxyId); - expect(decodedTokenAddress).to.be.equal(expectedDecodedAssetData.tokenAddress); - }); - it('should correctly decode ERC721 asset data', async () => { const tokenId = generatePseudoRandomSalt(); const encodedAssetData = assetProxyUtils.encodeERC721AssetData(testAddress, tokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); const expectedDecodedAssetData = assetProxyUtils.decodeERC721AssetData(encodedAssetData); - let decodedAssetProxyId: number; let decodedTokenAddress: string; let decodedTokenId: BigNumber; let decodedData: string; [ - decodedAssetProxyId, decodedTokenAddress, decodedTokenId, decodedData, - ] = await testAssetProxyDecoder.publicDecodeERC721Data.callAsync(encodedAssetData); - expect(decodedAssetProxyId).to.be.equal(expectedDecodedAssetData.assetProxyId); + ] = await testAssetProxyDecoder.publicDecodeERC721Data.callAsync(encodedAssetDataWithoutProxyId); expect(decodedTokenAddress).to.be.equal(expectedDecodedAssetData.tokenAddress); expect(decodedTokenId).to.be.bignumber.equal(expectedDecodedAssetData.tokenId); expect(decodedData).to.be.equal(expectedDecodedAssetData.receiverData); @@ -84,17 +70,14 @@ describe('TestAssetDataDecoders', () => { const receiverData = receiverDataFirst32Bytes + receiverDataExtraBytes; const encodedAssetData = assetProxyUtils.encodeERC721AssetData(testAddress, tokenId, receiverData); const expectedDecodedAssetData = assetProxyUtils.decodeERC721AssetData(encodedAssetData); - let decodedAssetProxyId: number; let decodedTokenAddress: string; let decodedTokenId: BigNumber; let decodedReceiverData: string; [ - decodedAssetProxyId, decodedTokenAddress, decodedTokenId, decodedReceiverData, ] = await testAssetProxyDecoder.publicDecodeERC721Data.callAsync(encodedAssetData); - expect(decodedAssetProxyId).to.be.equal(expectedDecodedAssetData.assetProxyId); expect(decodedTokenAddress).to.be.equal(expectedDecodedAssetData.tokenAddress); expect(decodedTokenId).to.be.bignumber.equal(expectedDecodedAssetData.tokenId); expect(decodedReceiverData).to.be.equal(expectedDecodedAssetData.receiverData); diff --git a/packages/contracts/test/asset_proxy/proxies.ts b/packages/contracts/test/asset_proxy/proxies.ts index 08376ccfb..9760d3b9c 100644 --- a/packages/contracts/test/asset_proxy/proxies.ts +++ b/packages/contracts/test/asset_proxy/proxies.ts @@ -96,12 +96,13 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer tokens', async () => { // Construct ERC20 asset data const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(10); await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, takerAddress, amount, @@ -122,12 +123,13 @@ describe('Asset Transfer Proxies', () => { it('should do nothing if transferring 0 amount of a token', async () => { // Construct ERC20 asset data const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(0); await web3Wrapper.awaitTransactionSuccessAsync( await erc20Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, takerAddress, amount, @@ -172,12 +174,19 @@ describe('Asset Transfer Proxies', () => { it('should throw if requesting address is not authorized', async () => { // Construct ERC20 asset data const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(10); return expectRevertOrAlwaysFailingTransactionAsync( - erc20Proxy.transferFrom.sendTransactionAsync(encodedAssetData, makerAddress, takerAddress, amount, { - from: notAuthorized, - }), + erc20Proxy.transferFrom.sendTransactionAsync( + encodedAssetDataWithoutProxyId, + makerAddress, + takerAddress, + amount, + { + from: notAuthorized, + }, + ), ); }); }); @@ -187,9 +196,10 @@ describe('Asset Transfer Proxies', () => { const erc20Balances = await erc20Wrapper.getBalancesAsync(); const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); const amount = new BigNumber(10); const numTransfers = 2; - const assetData = _.times(numTransfers, () => encodedAssetData); + const assetData = _.times(numTransfers, () => encodedAssetDataWithoutProxyId); const fromAddresses = _.times(numTransfers, () => makerAddress); const toAddresses = _.times(numTransfers, () => takerAddress); const amounts = _.times(numTransfers, () => amount); @@ -218,9 +228,10 @@ describe('Asset Transfer Proxies', () => { it('should throw if not called by an authorized address', async () => { const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); const amount = new BigNumber(10); const numTransfers = 2; - const assetData = _.times(numTransfers, () => encodedAssetData); + const assetData = _.times(numTransfers, () => encodedAssetDataWithoutProxyId); const fromAddresses = _.times(numTransfers, () => makerAddress); const toAddresses = _.times(numTransfers, () => takerAddress); const amounts = _.times(numTransfers, () => amount); @@ -244,6 +255,7 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer tokens', async () => { // Construct ERC721 asset data const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); @@ -251,7 +263,7 @@ describe('Asset Transfer Proxies', () => { const amount = new BigNumber(1); await web3Wrapper.awaitTransactionSuccessAsync( await erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, takerAddress, amount, @@ -267,13 +279,14 @@ describe('Asset Transfer Proxies', () => { it('should not call onERC721Received when transferring to a smart contract without receiver data', async () => { // Construct ERC721 asset data const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(1); const txHash = await erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, erc721Receiver.address, amount, @@ -298,13 +311,14 @@ describe('Asset Transfer Proxies', () => { erc721MakerTokenId, receiverData, ); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(1); const txHash = await erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, erc721Receiver.address, amount, @@ -333,6 +347,7 @@ describe('Asset Transfer Proxies', () => { erc721MakerTokenId, receiverData, ); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); @@ -340,7 +355,7 @@ describe('Asset Transfer Proxies', () => { const amount = new BigNumber(1); return expectRevertOrAlwaysFailingTransactionAsync( erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, erc20Proxy.address, // the ERC20 proxy does not have an ERC721 receiver amount, @@ -352,6 +367,7 @@ describe('Asset Transfer Proxies', () => { it('should throw if transferring 0 amount of a token', async () => { // Construct ERC721 asset data const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); @@ -359,7 +375,7 @@ describe('Asset Transfer Proxies', () => { const amount = new BigNumber(0); return expectRevertOrAlwaysFailingTransactionAsync( erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, takerAddress, amount, @@ -371,6 +387,7 @@ describe('Asset Transfer Proxies', () => { it('should throw if transferring > 1 amount of a token', async () => { // Construct ERC721 asset data const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Verify pre-condition const ownerMakerAsset = await erc721Token.ownerOf.callAsync(erc721MakerTokenId); expect(ownerMakerAsset).to.be.bignumber.equal(makerAddress); @@ -378,7 +395,7 @@ describe('Asset Transfer Proxies', () => { const amount = new BigNumber(500); return expectRevertOrAlwaysFailingTransactionAsync( erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, takerAddress, amount, @@ -390,6 +407,7 @@ describe('Asset Transfer Proxies', () => { it('should throw if allowances are too low', async () => { // Construct ERC721 asset data const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Remove transfer approval for makerAddress. await web3Wrapper.awaitTransactionSuccessAsync( await erc721Token.setApprovalForAll.sendTransactionAsync(erc721Proxy.address, false, { @@ -400,20 +418,27 @@ describe('Asset Transfer Proxies', () => { // Perform a transfer; expect this to fail. const amount = new BigNumber(1); return expectRevertOrAlwaysFailingTransactionAsync( - erc20Proxy.transferFrom.sendTransactionAsync(encodedAssetData, makerAddress, takerAddress, amount, { - from: notAuthorized, - }), + erc20Proxy.transferFrom.sendTransactionAsync( + encodedAssetDataWithoutProxyId, + makerAddress, + takerAddress, + amount, + { + from: notAuthorized, + }, + ), ); }); it('should throw if requesting address is not authorized', async () => { // Construct ERC721 asset data const encodedAssetData = assetProxyUtils.encodeERC721AssetData(erc721Token.address, erc721MakerTokenId); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(1); return expectRevertOrAlwaysFailingTransactionAsync( erc721Proxy.transferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, makerAddress, takerAddress, amount, @@ -430,8 +455,8 @@ describe('Asset Transfer Proxies', () => { const numTransfers = 2; const assetData = [ - assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdA), - assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdB), + assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdA).slice(0, -2), + assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdB).slice(0, -2), ]; const fromAddresses = _.times(numTransfers, () => makerAddress); const toAddresses = _.times(numTransfers, () => takerAddress); @@ -462,8 +487,8 @@ describe('Asset Transfer Proxies', () => { const numTransfers = 2; const assetData = [ - assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdA), - assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdB), + assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdA).slice(0, -2), + assetProxyUtils.encodeERC721AssetData(erc721Token.address, makerTokenIdB).slice(0, -2), ]; const fromAddresses = _.times(numTransfers, () => makerAddress); const toAddresses = _.times(numTransfers, () => takerAddress); @@ -484,3 +509,4 @@ describe('Asset Transfer Proxies', () => { }); }); // tslint:enable:no-unnecessary-type-assertion +// tslint:disable:max-file-line-count diff --git a/packages/contracts/test/exchange/core.ts b/packages/contracts/test/exchange/core.ts index 53b98c755..63c2fa6c0 100644 --- a/packages/contracts/test/exchange/core.ts +++ b/packages/contracts/test/exchange/core.ts @@ -87,7 +87,7 @@ describe('Exchange core', () => { artifacts.Exchange, provider, txDefaults, - assetProxyUtils.encodeERC20AssetData(zrxToken.address), + zrxToken.address, ); exchangeWrapper = new ExchangeWrapper(exchange, provider); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); diff --git a/packages/contracts/test/exchange/dispatcher.ts b/packages/contracts/test/exchange/dispatcher.ts index 9e113e47d..abbfd7ac7 100644 --- a/packages/contracts/test/exchange/dispatcher.ts +++ b/packages/contracts/test/exchange/dispatcher.ts @@ -276,12 +276,14 @@ describe('AssetProxyDispatcher', () => { ); // Construct metadata for ERC20 proxy const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(10); await web3Wrapper.awaitTransactionSuccessAsync( await assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, + AssetProxyId.ERC20, makerAddress, takerAddress, amount, @@ -302,11 +304,13 @@ describe('AssetProxyDispatcher', () => { it('should throw if dispatching to unregistered proxy', async () => { // Construct metadata for ERC20 proxy const encodedAssetData = assetProxyUtils.encodeERC20AssetData(zrxToken.address); + const encodedAssetDataWithoutProxyId = encodedAssetData.slice(0, -2); // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(10); return expectRevertOrAlwaysFailingTransactionAsync( assetProxyDispatcher.publicDispatchTransferFrom.sendTransactionAsync( - encodedAssetData, + encodedAssetDataWithoutProxyId, + AssetProxyId.ERC20, makerAddress, takerAddress, amount, diff --git a/packages/contracts/test/exchange/match_orders.ts b/packages/contracts/test/exchange/match_orders.ts index 18a46187f..b8dca04fd 100644 --- a/packages/contracts/test/exchange/match_orders.ts +++ b/packages/contracts/test/exchange/match_orders.ts @@ -96,7 +96,7 @@ describe('matchOrders', () => { artifacts.Exchange, provider, txDefaults, - assetProxyUtils.encodeERC20AssetData(zrxToken.address), + zrxToken.address, ); exchangeWrapper = new ExchangeWrapper(exchange, provider); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); diff --git a/packages/contracts/test/exchange/transactions.ts b/packages/contracts/test/exchange/transactions.ts index 12390ce01..21ff123e5 100644 --- a/packages/contracts/test/exchange/transactions.ts +++ b/packages/contracts/test/exchange/transactions.ts @@ -72,7 +72,7 @@ describe('Exchange transactions', () => { artifacts.Exchange, provider, txDefaults, - assetProxyUtils.encodeERC20AssetData(zrxToken.address), + zrxToken.address, ); exchangeWrapper = new ExchangeWrapper(exchange, provider); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); diff --git a/packages/contracts/test/exchange/wrapper.ts b/packages/contracts/test/exchange/wrapper.ts index b66cff90a..abba1ac4f 100644 --- a/packages/contracts/test/exchange/wrapper.ts +++ b/packages/contracts/test/exchange/wrapper.ts @@ -81,7 +81,7 @@ describe('Exchange wrappers', () => { artifacts.Exchange, provider, txDefaults, - assetProxyUtils.encodeERC20AssetData(zrxToken.address), + zrxToken.address, ); exchangeWrapper = new ExchangeWrapper(exchange, provider); await exchangeWrapper.registerAssetProxyAsync(AssetProxyId.ERC20, erc20Proxy.address, owner); @@ -712,6 +712,10 @@ describe('Exchange wrappers', () => { ); await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, { takerAssetFillAmount, + // HACK(albrow): We need to hardcode the gas estimate here because + // the Geth gas estimator doesn't work with the way we use + // delegatecall and swallow errors. + gas: 6000000, }); const newBalances = await erc20Wrapper.getBalancesAsync(); @@ -781,20 +785,49 @@ describe('Exchange wrappers', () => { expect(newBalances).to.be.deep.equal(erc20Balances); }); - it('should throw when a signedOrder does not use the same takerAssetAddress', async () => { + it('should not fill a signedOrder that does not use the same takerAssetAddress', async () => { signedOrders = [ orderFactory.newSignedOrder(), + orderFactory.newSignedOrder(), orderFactory.newSignedOrder({ takerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), }), - orderFactory.newSignedOrder(), ]; + const takerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18); + const filledSignedOrders = signedOrders.slice(0, -1); + _.forEach(filledSignedOrders, signedOrder => { + erc20Balances[makerAddress][defaultMakerAssetAddress] = erc20Balances[makerAddress][ + defaultMakerAssetAddress + ].minus(signedOrder.makerAssetAmount); + erc20Balances[makerAddress][defaultTakerAssetAddress] = erc20Balances[makerAddress][ + defaultTakerAssetAddress + ].add(signedOrder.takerAssetAmount); + erc20Balances[makerAddress][zrxToken.address] = erc20Balances[makerAddress][zrxToken.address].minus( + signedOrder.makerFee, + ); + erc20Balances[takerAddress][defaultMakerAssetAddress] = erc20Balances[takerAddress][ + defaultMakerAssetAddress + ].add(signedOrder.makerAssetAmount); + erc20Balances[takerAddress][defaultTakerAssetAddress] = erc20Balances[takerAddress][ + defaultTakerAssetAddress + ].minus(signedOrder.takerAssetAmount); + erc20Balances[takerAddress][zrxToken.address] = erc20Balances[takerAddress][zrxToken.address].minus( + signedOrder.takerFee, + ); + erc20Balances[feeRecipientAddress][zrxToken.address] = erc20Balances[feeRecipientAddress][ + zrxToken.address + ].add(signedOrder.makerFee.add(signedOrder.takerFee)); + }); + await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, { + takerAssetFillAmount, + // HACK(albrow): We need to hardcode the gas estimate here because + // the Geth gas estimator doesn't work with the way we use + // delegatecall and swallow errors. + gas: 600000, + }); - return expectRevertOrAlwaysFailingTransactionAsync( - exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, { - takerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18), - }), - ); + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances).to.be.deep.equal(erc20Balances); }); }); @@ -894,6 +927,10 @@ describe('Exchange wrappers', () => { ); await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, { makerAssetFillAmount, + // HACK(albrow): We need to hardcode the gas estimate here because + // the Geth gas estimator doesn't work with the way we use + // delegatecall and swallow errors. + gas: 600000, }); const newBalances = await erc20Wrapper.getBalancesAsync(); @@ -926,8 +963,8 @@ describe('Exchange wrappers', () => { ); }); - it('should fill all signedOrders if cannot fill entire takerAssetFillAmount', async () => { - const takerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18); + it('should fill all signedOrders if cannot fill entire makerAssetFillAmount', async () => { + const makerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18); _.forEach(signedOrders, signedOrder => { erc20Balances[makerAddress][defaultMakerAssetAddress] = erc20Balances[makerAddress][ defaultMakerAssetAddress @@ -951,8 +988,8 @@ describe('Exchange wrappers', () => { zrxToken.address ].add(signedOrder.makerFee.add(signedOrder.takerFee)); }); - await exchangeWrapper.marketSellOrdersNoThrowAsync(signedOrders, takerAddress, { - takerAssetFillAmount, + await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, { + makerAssetFillAmount, // HACK(albrow): We need to hardcode the gas estimate here because // the Geth gas estimator doesn't work with the way we use // delegatecall and swallow errors. @@ -963,20 +1000,50 @@ describe('Exchange wrappers', () => { expect(newBalances).to.be.deep.equal(erc20Balances); }); - it('should throw when a signedOrder does not use the same makerAssetAddress', async () => { + it('should not fill a signedOrder that does not use the same makerAssetAddress', async () => { signedOrders = [ orderFactory.newSignedOrder(), + orderFactory.newSignedOrder(), orderFactory.newSignedOrder({ makerAssetData: assetProxyUtils.encodeERC20AssetData(zrxToken.address), }), - orderFactory.newSignedOrder(), ]; - return expectRevertOrAlwaysFailingTransactionAsync( - exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, { - makerAssetFillAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(1000), 18), - }), - ); + const makerAssetFillAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(100000), 18); + const filledSignedOrders = signedOrders.slice(0, -1); + _.forEach(filledSignedOrders, signedOrder => { + erc20Balances[makerAddress][defaultMakerAssetAddress] = erc20Balances[makerAddress][ + defaultMakerAssetAddress + ].minus(signedOrder.makerAssetAmount); + erc20Balances[makerAddress][defaultTakerAssetAddress] = erc20Balances[makerAddress][ + defaultTakerAssetAddress + ].add(signedOrder.takerAssetAmount); + erc20Balances[makerAddress][zrxToken.address] = erc20Balances[makerAddress][zrxToken.address].minus( + signedOrder.makerFee, + ); + erc20Balances[takerAddress][defaultMakerAssetAddress] = erc20Balances[takerAddress][ + defaultMakerAssetAddress + ].add(signedOrder.makerAssetAmount); + erc20Balances[takerAddress][defaultTakerAssetAddress] = erc20Balances[takerAddress][ + defaultTakerAssetAddress + ].minus(signedOrder.takerAssetAmount); + erc20Balances[takerAddress][zrxToken.address] = erc20Balances[takerAddress][zrxToken.address].minus( + signedOrder.takerFee, + ); + erc20Balances[feeRecipientAddress][zrxToken.address] = erc20Balances[feeRecipientAddress][ + zrxToken.address + ].add(signedOrder.makerFee.add(signedOrder.takerFee)); + }); + await exchangeWrapper.marketBuyOrdersNoThrowAsync(signedOrders, takerAddress, { + makerAssetFillAmount, + // HACK(albrow): We need to hardcode the gas estimate here because + // the Geth gas estimator doesn't work with the way we use + // delegatecall and swallow errors. + gas: 600000, + }); + + const newBalances = await erc20Wrapper.getBalancesAsync(); + expect(newBalances).to.be.deep.equal(erc20Balances); }); }); diff --git a/packages/contracts/test/libraries/lib_bytes.ts b/packages/contracts/test/libraries/lib_bytes.ts index 2fefb7aeb..a31a4789c 100644 --- a/packages/contracts/test/libraries/lib_bytes.ts +++ b/packages/contracts/test/libraries/lib_bytes.ts @@ -4,6 +4,7 @@ import { BigNumber } from '@0xproject/utils'; import BN = require('bn.js'); import * as chai from 'chai'; import ethUtil = require('ethereumjs-util'); +import * as _ from 'lodash'; import { TestLibBytesContract } from '../../src/generated_contract_wrappers/test_lib_bytes'; import { artifacts } from '../../src/utils/artifacts'; @@ -27,8 +28,11 @@ describe('LibBytes', () => { const byteArrayLongerThan32BytesLastBytesSwapped = '0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abefcd'; let testAddress: string; + let testAddressB: string; const testBytes32 = '0x102030405060708090a0b0c0d0e0f0102030405060708090a0b0c0d0e0f01020'; + const testBytes32B = '0x534877abd8443578526845cdfef020047528759477fedef87346527659aced32'; const testUint256 = new BigNumber(testBytes32, 16); + const testUint256B = new BigNumber(testBytes32B, 16); let shortData: string; let shortTestBytes: string; let shortTestBytesAsBuffer: Buffer; @@ -49,6 +53,7 @@ describe('LibBytes', () => { // Setup accounts & addresses const accounts = await web3Wrapper.getAvailableAddressesAsync(); testAddress = accounts[1]; + testAddressB = accounts[2]; // Deploy LibBytes libBytes = await TestLibBytesContract.deployFrom0xArtifactAsync(artifacts.TestLibBytes, provider, txDefaults); // Verify lengths of test data @@ -86,16 +91,15 @@ describe('LibBytes', () => { await blockchainLifecycle.revertAsync(); }); - describe('popByte', () => { + describe('popLastByte', () => { it('should revert if length is 0', async () => { return expectRevertOrOtherErrorAsync( - libBytes.publicPopByte.callAsync(constants.NULL_BYTES), + libBytes.publicPopLastByte.callAsync(constants.NULL_BYTES), constants.LIB_BYTES_GREATER_THAN_ZERO_LENGTH_REQUIRED, ); }); - it('should pop the last byte from the input and return it', async () => { - const [newBytes, poppedByte] = await libBytes.publicPopByte.callAsync(byteArrayLongerThan32Bytes); + const [newBytes, poppedByte] = await libBytes.publicPopLastByte.callAsync(byteArrayLongerThan32Bytes); const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -2); const expectedPoppedByte = `0x${byteArrayLongerThan32Bytes.slice(-2)}`; expect(newBytes).to.equal(expectedNewBytes); @@ -103,16 +107,15 @@ describe('LibBytes', () => { }); }); - describe('popAddress', () => { + describe('popLast20Bytes', () => { it('should revert if length is less than 20', async () => { return expectRevertOrOtherErrorAsync( - libBytes.publicPopAddress.callAsync(byteArrayShorterThan20Bytes), + libBytes.publicPopLast20Bytes.callAsync(byteArrayShorterThan20Bytes), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED, ); }); - it('should pop the last 20 bytes from the input and return it', async () => { - const [newBytes, poppedAddress] = await libBytes.publicPopAddress.callAsync(byteArrayLongerThan32Bytes); + const [newBytes, poppedAddress] = await libBytes.publicPopLast20Bytes.callAsync(byteArrayLongerThan32Bytes); const expectedNewBytes = byteArrayLongerThan32Bytes.slice(0, -40); const expectedPoppedAddress = `0x${byteArrayLongerThan32Bytes.slice(-40)}`; expect(newBytes).to.equal(expectedNewBytes); @@ -128,7 +131,6 @@ describe('LibBytes', () => { ); return expect(areBytesEqual).to.be.true(); }); - it('should return true if byte arrays are equal (both arrays > 32 bytes)', async () => { const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( byteArrayLongerThan32Bytes, @@ -136,7 +138,6 @@ describe('LibBytes', () => { ); return expect(areBytesEqual).to.be.true(); }); - it('should return false if byte arrays are not equal (first array < 32 bytes, second array > 32 bytes)', async () => { const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( byteArrayShorterThan32Bytes, @@ -144,7 +145,6 @@ describe('LibBytes', () => { ); return expect(areBytesEqual).to.be.false(); }); - it('should return false if byte arrays are not equal (first array > 32 bytes, second array < 32 bytes)', async () => { const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( byteArrayLongerThan32Bytes, @@ -152,7 +152,6 @@ describe('LibBytes', () => { ); return expect(areBytesEqual).to.be.false(); }); - it('should return false if byte arrays are not equal (same length, but a byte in first word differs)', async () => { const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( byteArrayLongerThan32BytesFirstBytesSwapped, @@ -160,7 +159,6 @@ describe('LibBytes', () => { ); return expect(areBytesEqual).to.be.false(); }); - it('should return false if byte arrays are not equal (same length, but a byte in last word differs)', async () => { const areBytesEqual = await libBytes.publicAreBytesEqual.callAsync( byteArrayLongerThan32BytesLastBytesSwapped, @@ -170,15 +168,50 @@ describe('LibBytes', () => { }); }); + describe('deepCopyBytes', () => { + it('should revert if dest is shorter than source', async () => { + return expectRevertOrOtherErrorAsync( + libBytes.publicDeepCopyBytes.callAsync(byteArrayShorterThan32Bytes, byteArrayLongerThan32Bytes), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_SOURCE_BYTES_LENGTH_REQUIRED, + ); + }); + it('should overwrite dest with source if source and dest have equal length', async () => { + const zeroedByteArrayLongerThan32Bytes = `0x${_.repeat('0', byteArrayLongerThan32Bytes.length - 2)}`; + const zeroedBytesAfterCopy = await libBytes.publicDeepCopyBytes.callAsync( + zeroedByteArrayLongerThan32Bytes, + byteArrayLongerThan32Bytes, + ); + return expect(zeroedBytesAfterCopy).to.be.equal(byteArrayLongerThan32Bytes); + }); + it('should overwrite the leftmost len(source) bytes of dest if dest is larger than source', async () => { + const zeroedByteArrayLongerThan32Bytes = `0x${_.repeat('0', byteArrayLongerThan32Bytes.length * 2)}`; + const zeroedBytesAfterCopy = await libBytes.publicDeepCopyBytes.callAsync( + zeroedByteArrayLongerThan32Bytes, + byteArrayLongerThan32Bytes, + ); + const copiedBytes = zeroedBytesAfterCopy.slice(0, byteArrayLongerThan32Bytes.length); + return expect(copiedBytes).to.be.equal(byteArrayLongerThan32Bytes); + }); + it('should not overwrite the rightmost bytes of dest if dest is larger than source', async () => { + const zeroedByteArrayLongerThan32Bytes = `0x${_.repeat('0', byteArrayLongerThan32Bytes.length * 2)}`; + const zeroedBytesAfterCopy = await libBytes.publicDeepCopyBytes.callAsync( + zeroedByteArrayLongerThan32Bytes, + byteArrayLongerThan32Bytes, + ); + const expectedNotCopiedBytes = zeroedByteArrayLongerThan32Bytes.slice(byteArrayLongerThan32Bytes.length); + const notCopiedBytes = zeroedBytesAfterCopy.slice(byteArrayLongerThan32Bytes.length); + return expect(notCopiedBytes).to.be.equal(expectedNotCopiedBytes); + }); + }); + describe('readAddress', () => { - it('should successfully read address when the address takes up the whole array)', async () => { + it('should successfully read address when the address takes up the whole array', async () => { const byteArray = ethUtil.addHexPrefix(testAddress); const testAddressOffset = new BigNumber(0); const address = await libBytes.publicReadAddress.callAsync(byteArray, testAddressOffset); return expect(address).to.be.equal(testAddress); }); - - it('should successfully read address when it is offset in the array)', async () => { + it('should successfully read address when it is offset in the array', async () => { const addressByteArrayBuffer = ethUtil.toBuffer(testAddress); const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, addressByteArrayBuffer]); @@ -187,8 +220,7 @@ describe('LibBytes', () => { const address = await libBytes.publicReadAddress.callAsync(combinedByteArray, testAddressOffset); return expect(address).to.be.equal(testAddress); }); - - it('should fail if the byte array is too short to hold an address)', async () => { + it('should fail if the byte array is too short to hold an address', async () => { const shortByteArray = '0xabcdef'; const offset = new BigNumber(0); return expectRevertOrOtherErrorAsync( @@ -196,9 +228,8 @@ describe('LibBytes', () => { constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED, ); }); - - it('should fail if the length between the offset and end of the byte array is too short to hold an address)', async () => { - const byteArray = ethUtil.addHexPrefix(testAddress); + it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => { + const byteArray = testAddress; const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); return expectRevertOrOtherErrorAsync( libBytes.publicReadAddress.callAsync(byteArray, badOffset), @@ -207,43 +238,73 @@ describe('LibBytes', () => { }); }); - /// @TODO Implement test cases for writeAddress. Test template below. - /// Currently, the generated contract wrappers do not support this library's write methods. - /* describe('writeAddress', () => { - it('should successfully write address when the address takes up the whole array)', async () => {}); - it('should successfully write address when it is offset in the array)', async () => {}); - it('should fail if the byte array is too short to hold an address)', async () => {}); - it('should fail if the length between the offset and end of the byte array is too short to hold an address)', async () => {}); + it('should successfully write address when the address takes up the whole array', async () => { + const byteArray = testAddress; + const testAddressOffset = new BigNumber(0); + const newByteArray = await libBytes.publicWriteAddress.callAsync( + byteArray, + testAddressOffset, + testAddressB, + ); + return expect(newByteArray).to.be.equal(testAddressB); + }); + it('should successfully write address when it is offset in the array', async () => { + const addressByteArrayBuffer = ethUtil.toBuffer(testAddress); + const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); + const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, addressByteArrayBuffer]); + const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); + const testAddressOffset = new BigNumber(prefixByteArrayBuffer.byteLength); + const newByteArray = await libBytes.publicWriteAddress.callAsync( + combinedByteArray, + testAddressOffset, + testAddressB, + ); + const newByteArrayBuffer = ethUtil.toBuffer(newByteArray); + const addressFromOffsetBuffer = newByteArrayBuffer.slice(prefixByteArrayBuffer.byteLength); + const addressFromOffset = ethUtil.addHexPrefix(ethUtil.bufferToHex(addressFromOffsetBuffer)); + return expect(addressFromOffset).to.be.equal(testAddressB); + }); + it('should fail if the byte array is too short to hold an address', async () => { + const offset = new BigNumber(0); + return expectRevertOrOtherErrorAsync( + libBytes.publicWriteAddress.callAsync(byteArrayShorterThan20Bytes, offset, testAddress), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED, + ); + }); + it('should fail if the length between the offset and end of the byte array is too short to hold an address', async () => { + const byteArray = byteArrayLongerThan32Bytes; + const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); + return expectRevertOrOtherErrorAsync( + libBytes.publicWriteAddress.callAsync(byteArray, badOffset, testAddress), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_20_LENGTH_REQUIRED, + ); + }); }); - */ describe('readBytes32', () => { - it('should successfully read bytes32 when the bytes32 takes up the whole array)', async () => { + it('should successfully read bytes32 when the bytes32 takes up the whole array', async () => { const testBytes32Offset = new BigNumber(0); const bytes32 = await libBytes.publicReadBytes32.callAsync(testBytes32, testBytes32Offset); return expect(bytes32).to.be.equal(testBytes32); }); - it('should successfully read bytes32 when it is offset in the array)', async () => { const bytes32ByteArrayBuffer = ethUtil.toBuffer(testBytes32); const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, bytes32ByteArrayBuffer]); const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); - const testAddressOffset = new BigNumber(prefixByteArrayBuffer.byteLength); - const bytes32 = await libBytes.publicReadBytes32.callAsync(combinedByteArray, testAddressOffset); + const testBytes32Offset = new BigNumber(prefixByteArrayBuffer.byteLength); + const bytes32 = await libBytes.publicReadBytes32.callAsync(combinedByteArray, testBytes32Offset); return expect(bytes32).to.be.equal(testBytes32); }); - - it('should fail if the byte array is too short to hold a bytes32)', async () => { + it('should fail if the byte array is too short to hold a bytes32', async () => { const offset = new BigNumber(0); return expectRevertOrOtherErrorAsync( libBytes.publicReadBytes32.callAsync(byteArrayShorterThan32Bytes, offset), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); - - it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32)', async () => { + it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); return expectRevertOrOtherErrorAsync( libBytes.publicReadBytes32.callAsync(testBytes32, badOffset), @@ -252,19 +313,52 @@ describe('LibBytes', () => { }); }); - /// @TODO Implement test cases for writeBytes32. Test template below. - /// Currently, the generated contract wrappers do not support this library's write methods. - /* describe('writeBytes32', () => { - it('should successfully write bytes32 when the address takes up the whole array)', async () => {}); - it('should successfully write bytes32 when it is offset in the array)', async () => {}); - it('should fail if the byte array is too short to hold a bytes32)', async () => {}); - it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32)', async () => {}); + it('should successfully write bytes32 when the address takes up the whole array', async () => { + const byteArray = testBytes32; + const testBytes32Offset = new BigNumber(0); + const newByteArray = await libBytes.publicWriteBytes32.callAsync( + byteArray, + testBytes32Offset, + testBytes32B, + ); + return expect(newByteArray).to.be.equal(testBytes32B); + }); + it('should successfully write bytes32 when it is offset in the array', async () => { + const bytes32ByteArrayBuffer = ethUtil.toBuffer(testBytes32); + const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); + const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, bytes32ByteArrayBuffer]); + const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); + const testBytes32Offset = new BigNumber(prefixByteArrayBuffer.byteLength); + const newByteArray = await libBytes.publicWriteBytes32.callAsync( + combinedByteArray, + testBytes32Offset, + testBytes32B, + ); + const newByteArrayBuffer = ethUtil.toBuffer(newByteArray); + const bytes32FromOffsetBuffer = newByteArrayBuffer.slice(prefixByteArrayBuffer.byteLength); + const bytes32FromOffset = ethUtil.addHexPrefix(ethUtil.bufferToHex(bytes32FromOffsetBuffer)); + return expect(bytes32FromOffset).to.be.equal(testBytes32B); + }); + it('should fail if the byte array is too short to hold a bytes32', async () => { + const offset = new BigNumber(0); + return expectRevertOrOtherErrorAsync( + libBytes.publicWriteBytes32.callAsync(byteArrayShorterThan32Bytes, offset, testBytes32), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, + ); + }); + it('should fail if the length between the offset and end of the byte array is too short to hold a bytes32', async () => { + const byteArray = byteArrayLongerThan32Bytes; + const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); + return expectRevertOrOtherErrorAsync( + libBytes.publicWriteBytes32.callAsync(byteArray, badOffset, testBytes32), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, + ); + }); }); - */ describe('readUint256', () => { - it('should successfully read uint256 when the uint256 takes up the whole array)', async () => { + it('should successfully read uint256 when the uint256 takes up the whole array', async () => { const formattedTestUint256 = new BN(testUint256.toString(10)); const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256); const byteArray = ethUtil.bufferToHex(testUint256AsBuffer); @@ -272,8 +366,7 @@ describe('LibBytes', () => { const uint256 = await libBytes.publicReadUint256.callAsync(byteArray, testUint256Offset); return expect(uint256).to.bignumber.equal(testUint256); }); - - it('should successfully read uint256 when it is offset in the array)', async () => { + it('should successfully read uint256 when it is offset in the array', async () => { const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const formattedTestUint256 = new BN(testUint256.toString(10)); const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256); @@ -283,16 +376,14 @@ describe('LibBytes', () => { const uint256 = await libBytes.publicReadUint256.callAsync(combinedByteArray, testUint256Offset); return expect(uint256).to.bignumber.equal(testUint256); }); - - it('should fail if the byte array is too short to hold a uint256)', async () => { + it('should fail if the byte array is too short to hold a uint256', async () => { const offset = new BigNumber(0); return expectRevertOrOtherErrorAsync( libBytes.publicReadUint256.callAsync(byteArrayShorterThan32Bytes, offset), constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); - - it('should fail if the length between the offset and end of the byte array is too short to hold a uint256)', async () => { + it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => { const formattedTestUint256 = new BN(testUint256.toString(10)); const testUint256AsBuffer = ethUtil.toBuffer(formattedTestUint256); const byteArray = ethUtil.bufferToHex(testUint256AsBuffer); @@ -304,16 +395,53 @@ describe('LibBytes', () => { }); }); - /// @TODO Implement test cases for writeUint256. Test template below. - /// Currently, the generated contract wrappers do not support this library's write methods. - /* describe('writeUint256', () => { - it('should successfully write uint256 when the address takes up the whole array)', async () => {}); - it('should successfully write uint256 when it is offset in the array)', async () => {}); - it('should fail if the byte array is too short to hold a uint256)', async () => {}); - it('should fail if the length between the offset and end of the byte array is too short to hold a uint256)', async () => {}); + it('should successfully write uint256 when the address takes up the whole array', async () => { + const byteArray = testBytes32; + const testUint256Offset = new BigNumber(0); + const newByteArray = await libBytes.publicWriteUint256.callAsync( + byteArray, + testUint256Offset, + testUint256B, + ); + const newByteArrayAsUint256 = new BigNumber(newByteArray, 16); + return expect(newByteArrayAsUint256).to.be.bignumber.equal(testUint256B); + }); + it('should successfully write uint256 when it is offset in the array', async () => { + const bytes32ByteArrayBuffer = ethUtil.toBuffer(testBytes32); + const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); + const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, bytes32ByteArrayBuffer]); + const combinedByteArray = ethUtil.bufferToHex(combinedByteArrayBuffer); + const testUint256Offset = new BigNumber(prefixByteArrayBuffer.byteLength); + const newByteArray = await libBytes.publicWriteUint256.callAsync( + combinedByteArray, + testUint256Offset, + testUint256B, + ); + const newByteArrayBuffer = ethUtil.toBuffer(newByteArray); + const uint256FromOffsetBuffer = newByteArrayBuffer.slice(prefixByteArrayBuffer.byteLength); + const uint256FromOffset = new BigNumber( + ethUtil.addHexPrefix(ethUtil.bufferToHex(uint256FromOffsetBuffer)), + 16, + ); + return expect(uint256FromOffset).to.be.bignumber.equal(testUint256B); + }); + it('should fail if the byte array is too short to hold a uint256', async () => { + const offset = new BigNumber(0); + return expectRevertOrOtherErrorAsync( + libBytes.publicWriteUint256.callAsync(byteArrayShorterThan32Bytes, offset, testUint256), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, + ); + }); + it('should fail if the length between the offset and end of the byte array is too short to hold a uint256', async () => { + const byteArray = byteArrayLongerThan32Bytes; + const badOffset = new BigNumber(ethUtil.toBuffer(byteArray).byteLength); + return expectRevertOrOtherErrorAsync( + libBytes.publicWriteUint256.callAsync(byteArray, badOffset, testUint256), + constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, + ); + }); }); - */ describe('readFirst4', () => { // AssertionError: expected promise to be rejected with an error including 'revert' but it was fulfilled with '0x08c379a0' @@ -337,7 +465,6 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(shortTestBytes, testBytesOffset); return expect(bytes).to.be.equal(shortData); }); - it('should successfully read short, nested array of bytes when it is offset in the array', async () => { const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, shortTestBytesAsBuffer]); @@ -346,13 +473,11 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(combinedByteArray, testUint256Offset); return expect(bytes).to.be.equal(shortData); }); - it('should successfully read a nested array of bytes - one word in length - when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const bytes = await libBytes.publicReadBytes.callAsync(wordOfTestBytes, testBytesOffset); return expect(bytes).to.be.equal(wordOfData); }); - it('should successfully read a nested array of bytes - one word in length - when it is offset in the array', async () => { const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, wordOfTestBytesAsBuffer]); @@ -361,13 +486,11 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(combinedByteArray, testUint256Offset); return expect(bytes).to.be.equal(wordOfData); }); - it('should successfully read long, nested array of bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const bytes = await libBytes.publicReadBytes.callAsync(longTestBytes, testBytesOffset); return expect(bytes).to.be.equal(longData); }); - it('should successfully read long, nested array of bytes when it is offset in the array', async () => { const prefixByteArrayBuffer = ethUtil.toBuffer('0xabcdef'); const combinedByteArrayBuffer = Buffer.concat([prefixByteArrayBuffer, longTestBytesAsBuffer]); @@ -376,7 +499,6 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(combinedByteArray, testUint256Offset); return expect(bytes).to.be.equal(longData); }); - it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { // The length of the nested array is 32 bytes. By storing less than 32 bytes, a length cannot be read. const offset = new BigNumber(0); @@ -385,7 +507,6 @@ describe('LibBytes', () => { constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); - it('should fail if we store a nested byte array length, without a nested byte array', async () => { const offset = new BigNumber(0); return expectRevertOrOtherErrorAsync( @@ -393,7 +514,6 @@ describe('LibBytes', () => { constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED, ); }); - it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(byteArrayShorterThan32Bytes).byteLength); return expectRevertOrOtherErrorAsync( @@ -401,7 +521,6 @@ describe('LibBytes', () => { constants.LIB_BYTES_GREATER_OR_EQUAL_TO_32_LENGTH_REQUIRED, ); }); - it('should fail if the length between the offset and end of the byte array is too short to hold the nested byte array', async () => { const badOffset = new BigNumber(ethUtil.toBuffer(testBytes32).byteLength); return expectRevertOrOtherErrorAsync( @@ -419,7 +538,6 @@ describe('LibBytes', () => { const bytesRead = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(shortData); }); - it('should successfully write short, nested array of bytes when it is offset in the array', async () => { // Write a prefix to the array const prefixData = '0xabcdef'; @@ -436,7 +554,6 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(shortData); }); - it('should successfully write a nested array of bytes - one word in length - when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(wordOfTestBytesAsBuffer.byteLength)); @@ -444,7 +561,6 @@ describe('LibBytes', () => { const bytesRead = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(wordOfData); }); - it('should successfully write a nested array of bytes - one word in length - when it is offset in the array', async () => { // Write a prefix to the array const prefixData = '0xabcdef'; @@ -461,7 +577,6 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(wordOfData); }); - it('should successfully write a long, nested bytes when it takes up the whole array', async () => { const testBytesOffset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(longTestBytesAsBuffer.byteLength)); @@ -469,7 +584,6 @@ describe('LibBytes', () => { const bytesRead = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); return expect(bytesRead).to.be.equal(longData); }); - it('should successfully write long, nested array of bytes when it is offset in the array', async () => { // Write a prefix to the array const prefixData = '0xabcdef'; @@ -486,7 +600,6 @@ describe('LibBytes', () => { const bytes = await libBytes.publicReadBytes.callAsync(bytesWritten, testBytesOffset); return expect(bytes).to.be.equal(longData); }); - it('should fail if the byte array is too short to hold the length of a nested byte array', async () => { const offset = new BigNumber(0); const emptyByteArray = ethUtil.bufferToHex(new Buffer(1)); @@ -495,7 +608,6 @@ describe('LibBytes', () => { constants.LIB_BYTES_GREATER_OR_EQUAL_TO_NESTED_BYTES_LENGTH_REQUIRED, ); }); - it('should fail if the length between the offset and end of the byte array is too short to hold the length of a nested byte array)', async () => { const emptyByteArray = ethUtil.bufferToHex(new Buffer(shortTestBytesAsBuffer.byteLength)); const badOffset = new BigNumber(ethUtil.toBuffer(shortTestBytesAsBuffer).byteLength); |