diff --git a/contracts/asset-proxy/CHANGELOG.json b/contracts/asset-proxy/CHANGELOG.json index c601dcce07..00641fe214 100644 --- a/contracts/asset-proxy/CHANGELOG.json +++ b/contracts/asset-proxy/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "2.3.0-beta.1", + "changes": [ + { + "note": "ERC20Wrapper and ERC1155ProxyWrapper constructors now require an instance of DevUtilsContract", + "pr": 2034 + } + ] + }, { "version": "2.3.0-beta.0", "changes": [ diff --git a/contracts/asset-proxy/package.json b/contracts/asset-proxy/package.json index 4bd866af5b..14ebd47153 100644 --- a/contracts/asset-proxy/package.json +++ b/contracts/asset-proxy/package.json @@ -72,6 +72,7 @@ }, "dependencies": { "@0x/base-contract": "^5.5.0-beta.0", + "@0x/contracts-dev-utils": "^0.1.0-beta.0", "@0x/contracts-erc1155": "^1.2.0-beta.0", "@0x/contracts-erc20": "^2.3.0-beta.0", "@0x/contracts-erc721": "^2.2.0-beta.0", diff --git a/contracts/asset-proxy/test/erc1155_proxy.ts b/contracts/asset-proxy/test/erc1155_proxy.ts index c06f351e23..82c410a184 100644 --- a/contracts/asset-proxy/test/erc1155_proxy.ts +++ b/contracts/asset-proxy/test/erc1155_proxy.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { artifacts as erc1155Artifacts, DummyERC1155ReceiverBatchTokenReceivedEventArgs, @@ -15,7 +16,6 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId, RevertReason } from '@0x/types'; import { BigNumber, SafeMathRevertErrors } from '@0x/utils'; import * as chai from 'chai'; @@ -23,7 +23,7 @@ import { LogWithDecodedArgs } from 'ethereum-types'; import * as ethUtil from 'ethereumjs-util'; import * as _ from 'lodash'; -import { artifacts, ERC1155ProxyContract, ERC1155ProxyWrapper } from '../src'; +import { artifacts, ERC1155ProxyContract, ERC1155ProxyWrapper, IAssetDataContract } from '../src'; chaiSetup.configure(); const expect = chai.expect; @@ -59,6 +59,8 @@ describe('ERC1155Proxy', () => { // tokens let fungibleTokens: BigNumber[]; let nonFungibleTokensOwnedBySpender: BigNumber[]; + // devUtils for encoding and decoding assetData + let devUtils: DevUtilsContract; // tests before(async () => { await blockchainLifecycle.startAsync(); @@ -95,6 +97,8 @@ describe('ERC1155Proxy', () => { tokenBalances.nonFungible[spender][erc1155Contract.address][nonFungibleTokenAsString][0]; nonFungibleTokensOwnedBySpender.push(nonFungibleTokenHeldBySpender); }); + // set up devUtils + devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider, { from: owner }); }); beforeEach(async () => { await blockchainLifecycle.startAsync(); @@ -630,7 +634,7 @@ describe('ERC1155Proxy', () => { return value.times(valueMultiplier); }); const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -732,18 +736,16 @@ describe('ERC1155Proxy', () => { const tokensToTransfer = [new BigNumber(1), new BigNumber(2)]; const valuesToTransfer = tokensToTransfer; const valueMultiplier = new BigNumber(2); - const assetData = assetDataUtils.encodeERC1155AssetData( - erc1155ContractAddress, - tokensToTransfer, - valuesToTransfer, - receiverCallbackData, - ); - // remove the function selector and contract address from check, as these change on each test - const offsetToTokenIds = 74; - const assetDataWithoutContractAddress = assetData.substr(offsetToTokenIds); - const expectedAssetDataWithoutContractAddress = + + // hand encode optimized assetData because our tooling (based on LibAssetData.sol/encodeERC1155AssetData) does not use optimized encoding + const assetDataContract = new IAssetDataContract(constants.NULL_ADDRESS, provider); + const selector = assetDataContract.ERC1155Assets.getSelector(); + const assetDataWithoutContractAddress = '0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040102030400000000000000000000000000000000000000000000000000000000'; - expect(assetDataWithoutContractAddress).to.be.equal(expectedAssetDataWithoutContractAddress); + const assetData = `${selector}000000000000000000000000${erc1155ContractAddress.substr( + 2, + )}${assetDataWithoutContractAddress}`; + ///// Step 4/5 ///// // Transfer token IDs [1, 2] and amounts [1, 2] with a multiplier of 2; // the expected trade will be token IDs [1, 2] and amounts [2, 4] @@ -845,7 +847,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [new BigNumber(2), new BigNumber(2)]; const valueMultiplier = new BigNumber(2); // create callback data that is the encoded version of `valuesToTransfer` - const generatedAssetData = assetDataUtils.encodeERC1155AssetData( + const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -967,7 +969,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [new BigNumber(1), new BigNumber(2)]; const valueMultiplier = new BigNumber(2); // create callback data that is the encoded version of `valuesToTransfer` - const generatedAssetData = assetDataUtils.encodeERC1155AssetData( + const generatedAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1030,7 +1032,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1077,7 +1079,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1128,7 +1130,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1179,7 +1181,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1230,7 +1232,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1282,7 +1284,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1329,7 +1331,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1380,7 +1382,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1427,7 +1429,7 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, @@ -1478,13 +1480,13 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, receiverCallbackData, ); - const txData = erc1155ProxyWrapper.getTransferFromAbiEncodedTxData( + const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync( spender, receiverContract, erc1155Contract.address, @@ -1509,13 +1511,13 @@ describe('ERC1155Proxy', () => { const valuesToTransfer = [fungibleValueToTransferLarge]; const valueMultiplier = valueMultiplierSmall; const erc1155ContractAddress = erc1155Wrapper.getContract().address; - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155ContractAddress, tokensToTransfer, valuesToTransfer, receiverCallbackData, ); - const txData = erc1155ProxyWrapper.getTransferFromAbiEncodedTxData( + const txData = await erc1155ProxyWrapper.getTransferFromAbiEncodedTxDataAsync( spender, receiverContract, erc1155Contract.address, diff --git a/contracts/asset-proxy/test/proxies.ts b/contracts/asset-proxy/test/proxies.ts index 20a00b98e3..232b085086 100644 --- a/contracts/asset-proxy/test/proxies.ts +++ b/contracts/asset-proxy/test/proxies.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155'; import { artifacts as erc20Artifacts, @@ -22,7 +23,6 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId, RevertReason } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -56,6 +56,7 @@ describe('Asset Transfer Proxies', () => { let fromAddress: string; let toAddress: string; + let devUtils: DevUtilsContract; let erc20TokenA: DummyERC20TokenContract; let erc20TokenB: DummyERC20TokenContract; let erc721TokenA: DummyERC721TokenContract; @@ -91,6 +92,7 @@ describe('Asset Transfer Proxies', () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); const usedAddresses = ([owner, notAuthorized, authorized, fromAddress, toAddress] = _.slice(accounts, 0, 5)); + devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner); erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner); @@ -230,7 +232,7 @@ describe('Asset Transfer Proxies', () => { describe('transferFrom', () => { it('should successfully transfer tokens', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // Perform a transfer from fromAddress to toAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(10); @@ -260,7 +262,7 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer tokens that do not return a value', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address); // Perform a transfer from fromAddress to toAddress const initialFromBalance = await noReturnErc20Token.balanceOf.callAsync(fromAddress); const initialToBalance = await noReturnErc20Token.balanceOf.callAsync(toAddress); @@ -289,7 +291,9 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer tokens and ignore extra assetData', async () => { // Construct ERC20 asset data const extraData = '0102030405060708'; - const encodedAssetData = `${assetDataUtils.encodeERC20AssetData(erc20TokenA.address)}${extraData}`; + const encodedAssetData = `${await devUtils.encodeERC20AssetData.callAsync( + erc20TokenA.address, + )}${extraData}`; // Perform a transfer from fromAddress to toAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(10); @@ -319,7 +323,7 @@ describe('Asset Transfer Proxies', () => { it('should do nothing if transferring 0 amount of a token', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // Perform a transfer from fromAddress to toAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); const amount = new BigNumber(0); @@ -349,7 +353,7 @@ describe('Asset Transfer Proxies', () => { it('should revert if allowances are too low', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // Create allowance less than transfer amount. Set allowance on proxy. const allowance = new BigNumber(0); const amount = new BigNumber(10); @@ -378,7 +382,7 @@ describe('Asset Transfer Proxies', () => { it('should revert if allowances are too low and token does not return a value', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address); // Create allowance less than transfer amount. Set allowance on proxy. const allowance = new BigNumber(0); const amount = new BigNumber(10); @@ -410,7 +414,7 @@ describe('Asset Transfer Proxies', () => { it('should revert if caller is not authorized', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // Perform a transfer from fromAddress to toAddress const amount = new BigNumber(10); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( @@ -434,7 +438,9 @@ describe('Asset Transfer Proxies', () => { it('should revert if token returns more than 32 bytes', async () => { // Construct ERC20 asset data - const encodedAssetData = assetDataUtils.encodeERC20AssetData(multipleReturnErc20Token.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync( + multipleReturnErc20Token.address, + ); const amount = new BigNumber(10); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( encodedAssetData, @@ -481,7 +487,10 @@ describe('Asset Transfer Proxies', () => { describe('transferFrom', () => { it('should successfully transfer tokens', async () => { // Construct ERC721 asset data - const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); // Verify pre-condition const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); expect(ownerFromAsset).to.be.equal(fromAddress); @@ -509,7 +518,7 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer tokens and ignore extra assetData', async () => { // Construct ERC721 asset data const extraData = '0102030405060708'; - const encodedAssetData = `${assetDataUtils.encodeERC721AssetData( + const encodedAssetData = `${await devUtils.encodeERC721AssetData.callAsync( erc721TokenA.address, erc721AFromTokenId, )}${extraData}`; @@ -539,7 +548,10 @@ describe('Asset Transfer Proxies', () => { it('should not call onERC721Received when transferring to a smart contract', async () => { // Construct ERC721 asset data - const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); // Verify pre-condition const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); expect(ownerFromAsset).to.be.equal(fromAddress); @@ -569,7 +581,10 @@ describe('Asset Transfer Proxies', () => { it('should revert if transferring 0 amount of a token', async () => { // Construct ERC721 asset data - const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); // Verify pre-condition const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); expect(ownerFromAsset).to.be.equal(fromAddress); @@ -595,7 +610,10 @@ describe('Asset Transfer Proxies', () => { it('should revert if transferring > 1 amount of a token', async () => { // Construct ERC721 asset data - const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); // Verify pre-condition const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); expect(ownerFromAsset).to.be.equal(fromAddress); @@ -621,7 +639,10 @@ describe('Asset Transfer Proxies', () => { it('should revert if allowances are too low', async () => { // Construct ERC721 asset data - const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); // Verify pre-condition const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); expect(ownerFromAsset).to.be.equal(fromAddress); @@ -655,7 +676,10 @@ describe('Asset Transfer Proxies', () => { it('should revert if caller is not authorized', async () => { // Construct ERC721 asset data - const encodedAssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const encodedAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); // Verify pre-condition const ownerFromAsset = await erc721TokenA.ownerOf.callAsync(erc721AFromTokenId); expect(ownerFromAsset).to.be.equal(fromAddress); @@ -702,10 +726,10 @@ describe('Asset Transfer Proxies', () => { it('should transfer a single ERC20 token', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const amounts = [erc20Amount]; const nestedAssetData = [erc20AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -733,7 +757,7 @@ describe('Asset Transfer Proxies', () => { it('should dispatch an ERC20 transfer when input amount is 0', async () => { const inputAmount = constants.ZERO_AMOUNT; const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const amounts = [erc20Amount]; const nestedAssetData = [erc20AssetData]; const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData); @@ -764,11 +788,11 @@ describe('Asset Transfer Proxies', () => { const inputAmount = new BigNumber(1); const erc20Amount1 = new BigNumber(10); const erc20Amount2 = new BigNumber(20); - const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const amounts = [erc20Amount1, erc20Amount2]; const nestedAssetData = [erc20AssetData1, erc20AssetData2]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -797,11 +821,11 @@ describe('Asset Transfer Proxies', () => { const inputAmount = new BigNumber(1); const erc20Amount1 = new BigNumber(10); const erc20Amount2 = new BigNumber(20); - const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); const amounts = [erc20Amount1, erc20Amount2]; const nestedAssetData = [erc20AssetData1, erc20AssetData2]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -836,10 +860,13 @@ describe('Asset Transfer Proxies', () => { it('should transfer a single ERC721 token', async () => { const inputAmount = new BigNumber(1); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc721Amount]; const nestedAssetData = [erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -862,8 +889,11 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer multiple of the same ERC721 token', async () => { const erc721Balances = await erc721Wrapper.getBalancesAsync(); const erc721AFromTokenId2 = erc721Balances[fromAddress][erc721TokenA.address][1]; - const erc721AssetData1 = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); - const erc721AssetData2 = assetDataUtils.encodeERC721AssetData( + const erc721AssetData1 = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); + const erc721AssetData2 = await devUtils.encodeERC721AssetData.callAsync( erc721TokenA.address, erc721AFromTokenId2, ); @@ -871,7 +901,7 @@ describe('Asset Transfer Proxies', () => { const erc721Amount = new BigNumber(1); const amounts = [erc721Amount, erc721Amount]; const nestedAssetData = [erc721AssetData1, erc721AssetData2]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -897,13 +927,19 @@ describe('Asset Transfer Proxies', () => { expect(newOwnerFromAsset2).to.be.equal(toAddress); }); it('should successfully transfer multiple different ERC721 tokens', async () => { - const erc721AssetData1 = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); - const erc721AssetData2 = assetDataUtils.encodeERC721AssetData(erc721TokenB.address, erc721BFromTokenId); + const erc721AssetData1 = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); + const erc721AssetData2 = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenB.address, + erc721BFromTokenId, + ); const inputAmount = new BigNumber(1); const erc721Amount = new BigNumber(1); const amounts = [erc721Amount, erc721Amount]; const nestedAssetData = [erc721AssetData1, erc721AssetData2]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -944,7 +980,7 @@ describe('Asset Transfer Proxies', () => { ]; await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances); // encode erc1155 asset data - const erc1155AssetData = assetDataUtils.encodeERC1155AssetData( + const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, tokensToTransfer, valuesToTransfer, @@ -954,7 +990,7 @@ describe('Asset Transfer Proxies', () => { const multiAssetAmount = new BigNumber(5); const amounts = [valueMultiplier]; const nestedAssetData = [erc1155AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1000,7 +1036,7 @@ describe('Asset Transfer Proxies', () => { ]; await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances); // encode erc1155 asset data - const erc1155AssetData = assetDataUtils.encodeERC1155AssetData( + const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, tokensToTransfer, valuesToTransfer, @@ -1010,7 +1046,7 @@ describe('Asset Transfer Proxies', () => { const multiAssetAmount = new BigNumber(5); const amounts = [valueMultiplier]; const nestedAssetData = [erc1155AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1064,7 +1100,7 @@ describe('Asset Transfer Proxies', () => { ]; await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances); // encode erc1155 asset data - const erc1155AssetData = assetDataUtils.encodeERC1155AssetData( + const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, tokensToTransfer, valuesToTransfer, @@ -1074,7 +1110,7 @@ describe('Asset Transfer Proxies', () => { const multiAssetAmount = new BigNumber(1); const amounts = [valueMultiplier]; const nestedAssetData = [erc1155AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1121,13 +1157,13 @@ describe('Asset Transfer Proxies', () => { await erc1155Wrapper.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances); await erc1155Wrapper2.assertBalancesAsync(tokenHolders, tokensToTransfer, expectedInitialBalances); // encode erc1155 asset data - const erc1155AssetData1 = assetDataUtils.encodeERC1155AssetData( + const erc1155AssetData1 = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, tokensToTransfer, valuesToTransfer, receiverCallbackData, ); - const erc1155AssetData2 = assetDataUtils.encodeERC1155AssetData( + const erc1155AssetData2 = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract2.address, tokensToTransfer, valuesToTransfer, @@ -1137,7 +1173,7 @@ describe('Asset Transfer Proxies', () => { const multiAssetAmount = new BigNumber(5); const amounts = [valueMultiplier, valueMultiplier]; const nestedAssetData = [erc1155AssetData1, erc1155AssetData2]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1168,15 +1204,18 @@ describe('Asset Transfer Proxies', () => { // setup test parameters const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const erc1155TokenHolders = [fromAddress, toAddress]; const erc1155TokensToTransfer = erc1155FungibleTokens.slice(0, 1); const erc1155ValuesToTransfer = [new BigNumber(25)]; const erc1155Amount = new BigNumber(23); const erc1155ReceiverCallbackData = '0x0102030405'; - const erc1155AssetData = assetDataUtils.encodeERC1155AssetData( + const erc1155AssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, erc1155TokensToTransfer, erc1155ValuesToTransfer, @@ -1184,7 +1223,7 @@ describe('Asset Transfer Proxies', () => { ); const amounts = [erc20Amount, erc721Amount, erc1155Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData, erc1155AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1239,12 +1278,15 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer a combination of ERC20 and ERC721 tokens', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1276,13 +1318,19 @@ describe('Asset Transfer Proxies', () => { it('should successfully transfer tokens and ignore extra assetData', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; const extraData = '0102030405060708090001020304050607080900010203040506070809000102'; - const assetData = `${assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData)}${extraData}`; + const assetData = `${await devUtils.encodeMultiAssetData.callAsync( + amounts, + nestedAssetData, + )}${extraData}`; const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1315,11 +1363,11 @@ describe('Asset Transfer Proxies', () => { const inputAmount = new BigNumber(100); const erc20Amount1 = new BigNumber(10); const erc20Amount2 = new BigNumber(20); - const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); const amounts = [erc20Amount1, erc20Amount2]; const nestedAssetData = [erc20AssetData1, erc20AssetData2]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1355,19 +1403,25 @@ describe('Asset Transfer Proxies', () => { const inputAmount = new BigNumber(1); const erc20Amount1 = new BigNumber(10); const erc20Amount2 = new BigNumber(20); - const erc20AssetData1 = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const erc20AssetData1 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); const erc721Amount = new BigNumber(1); const erc721Balances = await erc721Wrapper.getBalancesAsync(); const erc721AFromTokenId2 = erc721Balances[fromAddress][erc721TokenA.address][1]; const erc721BFromTokenId2 = erc721Balances[fromAddress][erc721TokenB.address][1]; - const erc721AssetData1 = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); - const erc721AssetData2 = assetDataUtils.encodeERC721AssetData( + const erc721AssetData1 = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); + const erc721AssetData2 = await devUtils.encodeERC721AssetData.callAsync( erc721TokenA.address, erc721AFromTokenId2, ); - const erc721AssetData3 = assetDataUtils.encodeERC721AssetData(erc721TokenB.address, erc721BFromTokenId); - const erc721AssetData4 = assetDataUtils.encodeERC721AssetData( + const erc721AssetData3 = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenB.address, + erc721BFromTokenId, + ); + const erc721AssetData4 = await devUtils.encodeERC721AssetData.callAsync( erc721TokenB.address, erc721BFromTokenId2, ); @@ -1380,7 +1434,7 @@ describe('Asset Transfer Proxies', () => { erc721AssetData3, erc721AssetData4, ]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1432,13 +1486,16 @@ describe('Asset Transfer Proxies', () => { it('should revert if a single transfer fails', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // 2 is an invalid erc721 amount const erc721Amount = new BigNumber(2); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1457,15 +1514,17 @@ describe('Asset Transfer Proxies', () => { it('should revert if an AssetProxy is not registered', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const invalidProxyId = '0x12345678'; const invalidErc721AssetData = `${invalidProxyId}${erc721AssetData.slice(10)}`; const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, invalidErc721AssetData]; - // HACK: This is used to get around validation built into assetDataUtils - const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1484,12 +1543,14 @@ describe('Asset Transfer Proxies', () => { it('should revert if the length of `amounts` does not match the length of `nestedAssetData`', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - // HACK: This is used to get around validation built into assetDataUtils - const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1508,10 +1569,10 @@ describe('Asset Transfer Proxies', () => { it('should revert if amounts multiplication results in an overflow', async () => { const inputAmount = new BigNumber(2).pow(128); const erc20Amount = new BigNumber(2).pow(128); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const amounts = [erc20Amount]; const nestedAssetData = [erc20AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1530,13 +1591,12 @@ describe('Asset Transfer Proxies', () => { it('should revert if an element of `nestedAssetData` is < 4 bytes long', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); const erc721AssetData = '0x123456'; const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - // HACK: This is used to get around validation built into assetDataUtils - const assetData = assetDataInterface.MultiAsset.getABIEncodedTransactionData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1555,12 +1615,15 @@ describe('Asset Transfer Proxies', () => { it('should revert if caller is not authorized', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1579,12 +1642,15 @@ describe('Asset Transfer Proxies', () => { it('should revert if asset data overflows beyond the bounds of calldata', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1609,12 +1675,15 @@ describe('Asset Transfer Proxies', () => { it('should revert if asset data resolves to a location beyond the bounds of calldata', async () => { const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const data = assetProxyInterface.transferFrom.getABIEncodedTransactionData( assetData, fromAddress, @@ -1640,12 +1709,15 @@ describe('Asset Transfer Proxies', () => { // setup test parameters const inputAmount = new BigNumber(1); const erc20Amount = new BigNumber(10); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const erc721Amount = new BigNumber(1); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721TokenA.address, erc721AFromTokenId); + const erc721AssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721TokenA.address, + erc721AFromTokenId, + ); const amounts = [erc20Amount, erc721Amount]; const nestedAssetData = [erc20AssetData, erc721AssetData]; - const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData); + const assetData = await devUtils.encodeMultiAssetData.callAsync(amounts, nestedAssetData); const extraData = '01'; const assetDataWithExtraData = `${assetData}${extraData}`; const badData = assetProxyInterface.transferFrom.getABIEncodedTransactionData( diff --git a/contracts/asset-proxy/test/static_call_proxy.ts b/contracts/asset-proxy/test/static_call_proxy.ts index 09db4ebe82..743cc476a3 100644 --- a/contracts/asset-proxy/test/static_call_proxy.ts +++ b/contracts/asset-proxy/test/static_call_proxy.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { chaiSetup, constants, @@ -8,7 +9,6 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId, RevertReason } from '@0x/types'; import { AbiEncoder, BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -25,6 +25,7 @@ describe('StaticCallProxy', () => { let fromAddress: string; let toAddress: string; + let devUtils: DevUtilsContract; let staticCallProxy: IAssetProxyContract; let staticCallTarget: TestStaticCallTargetContract; @@ -43,6 +44,7 @@ describe('StaticCallProxy', () => { txDefaults, artifacts, ); + devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); staticCallProxy = new IAssetProxyContract( staticCallProxyWithoutTransferFrom.address, provider, @@ -86,7 +88,7 @@ describe('StaticCallProxy', () => { it('should revert if assetData lies outside the bounds of calldata', async () => { const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -114,9 +116,11 @@ describe('StaticCallProxy', () => { it('should revert if the length of assetData is less than 100 bytes', async () => { const staticCallData = constants.NULL_BYTES; const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils - .encodeStaticCallAssetData(staticCallTarget.address, staticCallData, expectedResultHash) - .slice(0, -128); + const assetData = (await devUtils.encodeStaticCallAssetData.callAsync( + staticCallTarget.address, + staticCallData, + expectedResultHash, + )).slice(0, -128); const assetDataByteLen = (assetData.length - 2) / 2; expect((assetDataByteLen - 4) % 32).to.equal(0); await expectTransactionFailedWithoutReasonAsync( @@ -126,7 +130,7 @@ describe('StaticCallProxy', () => { it('should revert if the offset to `staticCallData` points to outside of assetData', async () => { const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -147,7 +151,7 @@ describe('StaticCallProxy', () => { it('should revert if the callTarget attempts to write to state', async () => { const staticCallData = staticCallTarget.updateState.getABIEncodedTransactionData(); const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -159,7 +163,7 @@ describe('StaticCallProxy', () => { it('should revert with data provided by the callTarget if the staticcall reverts', async () => { const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1)); const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -173,7 +177,7 @@ describe('StaticCallProxy', () => { const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0)); const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -186,7 +190,7 @@ describe('StaticCallProxy', () => { it('should be successful if a function call with no inputs and no outputs is successful', async () => { const staticCallData = staticCallTarget.noInputFunction.getABIEncodedTransactionData(); const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -196,14 +200,18 @@ describe('StaticCallProxy', () => { it('should be successful if the staticCallTarget is not a contract and no return value is expected', async () => { const staticCallData = '0x0102030405060708'; const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData(toAddress, staticCallData, expectedResultHash); + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( + toAddress, + staticCallData, + expectedResultHash, + ); await staticCallProxy.transferFrom.awaitTransactionSuccessAsync(assetData, fromAddress, toAddress, amount); }); it('should be successful if a function call with one static input returns the correct value', async () => { const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1)); const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -214,7 +222,7 @@ describe('StaticCallProxy', () => { const dynamicInput = '0x0102030405060708'; const staticCallData = staticCallTarget.dynamicInputFunction.getABIEncodedTransactionData(dynamicInput); const expectedResultHash = constants.KECCAK256_NULL; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -237,7 +245,7 @@ describe('StaticCallProxy', () => { const expectedResultHash = ethUtil.bufferToHex( ethUtil.sha3(ethUtil.toBuffer(encodedExpectedResultWithOffset)), ); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, diff --git a/contracts/asset-proxy/test/utils/erc1155_proxy_wrapper.ts b/contracts/asset-proxy/test/utils/erc1155_proxy_wrapper.ts index 78c154df19..5bc707af41 100644 --- a/contracts/asset-proxy/test/utils/erc1155_proxy_wrapper.ts +++ b/contracts/asset-proxy/test/utils/erc1155_proxy_wrapper.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { artifacts as erc1155Artifacts, ERC1155MintableContract, Erc1155Wrapper } from '@0x/contracts-erc1155'; import { constants, @@ -7,7 +8,6 @@ import { LogDecoder, txDefaults, } from '@0x/contracts-test-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import { Provider, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; @@ -26,6 +26,7 @@ export class ERC1155ProxyWrapper { private readonly _logDecoder: LogDecoder; private readonly _dummyTokenWrappers: Erc1155Wrapper[]; private readonly _assetProxyInterface: IAssetProxyContract; + private readonly _devUtils: DevUtilsContract; private _proxyContract?: ERC1155ProxyContract; private _proxyIdIfExists?: string; private _initialTokenIdsByOwner: ERC1155HoldingsByOwner = { fungible: {}, nonFungible: {} }; @@ -37,6 +38,7 @@ export class ERC1155ProxyWrapper { this._logDecoder = new LogDecoder(this._web3Wrapper, allArtifacts); this._dummyTokenWrappers = []; this._assetProxyInterface = new IAssetProxyContract(constants.NULL_ADDRESS, provider); + this._devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); this._tokenOwnerAddresses = tokenOwnerAddresses; this._contractOwnerAddress = contractOwnerAddress; this._fungibleTokenIds = []; @@ -95,7 +97,7 @@ export class ERC1155ProxyWrapper { * @param extraData extra data to append to `transferFrom` transaction. Optional. * @return abi encoded tx data. */ - public getTransferFromAbiEncodedTxData( + public async getTransferFromAbiEncodedTxDataAsync( from: string, to: string, contractAddress: string, @@ -105,11 +107,11 @@ export class ERC1155ProxyWrapper { receiverCallbackData: string, authorizedSender: string, assetData_?: string, - ): string { + ): Promise { this._validateProxyContractExistsOrThrow(); const assetData = assetData_ === undefined - ? assetDataUtils.encodeERC1155AssetData( + ? await this._devUtils.encodeERC1155AssetData.callAsync( contractAddress, tokensToTransfer, valuesToTransfer, @@ -169,7 +171,7 @@ export class ERC1155ProxyWrapper { this._validateProxyContractExistsOrThrow(); const assetData = assetData_ === undefined - ? assetDataUtils.encodeERC1155AssetData( + ? await this._devUtils.encodeERC1155AssetData.callAsync( contractAddress, tokensToTransfer, valuesToTransfer, diff --git a/contracts/asset-proxy/test/utils/erc20_wrapper.ts b/contracts/asset-proxy/test/utils/erc20_wrapper.ts index 2076040bd8..52e8d43142 100644 --- a/contracts/asset-proxy/test/utils/erc20_wrapper.ts +++ b/contracts/asset-proxy/test/utils/erc20_wrapper.ts @@ -1,6 +1,6 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20'; import { constants, ERC20BalancesByOwner, txDefaults } from '@0x/contracts-test-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { BigNumber } from '@0x/utils'; import { ZeroExProvider } from 'ethereum-types'; import * as _ from 'lodash'; @@ -12,6 +12,7 @@ export class ERC20Wrapper { private readonly _contractOwnerAddress: string; private readonly _provider: ZeroExProvider; private readonly _dummyTokenContracts: DummyERC20TokenContract[]; + private readonly _devUtils: DevUtilsContract; private _proxyContract?: ERC20ProxyContract; private _proxyIdIfExists?: string; /** @@ -26,6 +27,7 @@ export class ERC20Wrapper { this._provider = provider; this._tokenOwnerAddresses = tokenOwnerAddresses; this._contractOwnerAddress = contractOwnerAddress; + this._devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); } public async deployDummyTokensAsync( numberToDeploy: number, @@ -80,24 +82,27 @@ export class ERC20Wrapper { } } public async getBalanceAsync(userAddress: string, assetData: string): Promise { - const tokenContract = this._getTokenContractFromAssetData(assetData); + const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData); const balance = new BigNumber(await tokenContract.balanceOf.callAsync(userAddress)); return balance; } public async setBalanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise { - const tokenContract = this._getTokenContractFromAssetData(assetData); - await tokenContract.setBalance.awaitTransactionSuccessAsync(userAddress, amount, { - from: this._contractOwnerAddress, - }); + const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData); + await tokenContract.setBalance.awaitTransactionSuccessAsync( + userAddress, + amount, + { from: this._contractOwnerAddress }, + { pollingIntervalMs: constants.AWAIT_TRANSACTION_MINED_MS }, + ); } public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise { - const tokenContract = this._getTokenContractFromAssetData(assetData); + const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData); const proxyAddress = (this._proxyContract as ERC20ProxyContract).address; const allowance = new BigNumber(await tokenContract.allowance.callAsync(userAddress, proxyAddress)); return allowance; } public async setAllowanceAsync(userAddress: string, assetData: string, amount: BigNumber): Promise { - const tokenContract = this._getTokenContractFromAssetData(assetData); + const tokenContract = await this._getTokenContractFromAssetDataAsync(assetData); const proxyAddress = (this._proxyContract as ERC20ProxyContract).address; await tokenContract.approve.awaitTransactionSuccessAsync(proxyAddress, amount, { from: userAddress }); } @@ -141,9 +146,8 @@ export class ERC20Wrapper { const tokenAddresses = _.map(this._dummyTokenContracts, dummyTokenContract => dummyTokenContract.address); return tokenAddresses; } - private _getTokenContractFromAssetData(assetData: string): DummyERC20TokenContract { - const erc20ProxyData = assetDataUtils.decodeERC20AssetData(assetData); - const tokenAddress = erc20ProxyData.tokenAddress; + private async _getTokenContractFromAssetDataAsync(assetData: string): Promise { + const [proxyId, tokenAddress] = await this._devUtils.decodeERC20AssetData.callAsync(assetData); // tslint:disable-line:no-unused-variable const tokenContractIfExists = _.find(this._dummyTokenContracts, c => c.address === tokenAddress); if (tokenContractIfExists === undefined) { throw new Error(`Token: ${tokenAddress} was not deployed through ERC20Wrapper`); diff --git a/contracts/coordinator/package.json b/contracts/coordinator/package.json index 037ea6909f..332a09f7fa 100644 --- a/contracts/coordinator/package.json +++ b/contracts/coordinator/package.json @@ -49,6 +49,11 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/extensions/README.md", "devDependencies": { "@0x/abi-gen": "^4.3.0-beta.0", + "@0x/contracts-asset-proxy": "^2.3.0-beta.0", + "@0x/contracts-dev-utils": "^0.1.0-beta.0", + "@0x/contracts-erc20": "^2.3.0-beta.0", + "@0x/contracts-exchange": "^2.2.0-beta.0", + "@0x/order-utils": "^8.5.0-beta.0", "@0x/contracts-gen": "^1.1.0-beta.0", "@0x/contracts-test-utils": "^3.2.0-beta.0", "@0x/dev-utils": "^2.4.0-beta.0", @@ -61,6 +66,7 @@ "chai-as-promised": "^7.1.0", "chai-bignumber": "^3.0.0", "dirty-chai": "^2.0.1", + "lodash": "^4.17.11", "make-promises-safe": "^1.1.0", "mocha": "^6.2.0", "npm-run-all": "^4.1.2", @@ -72,19 +78,12 @@ }, "dependencies": { "@0x/base-contract": "^5.5.0-beta.0", - "@0x/contracts-asset-proxy": "^2.3.0-beta.0", - "@0x/contracts-erc20": "^2.3.0-beta.0", - "@0x/contracts-exchange": "^2.2.0-beta.0", - "@0x/contracts-exchange-libs": "^3.1.0-beta.0", - "@0x/contracts-utils": "^3.3.0-beta.0", - "@0x/order-utils": "^8.5.0-beta.0", "@0x/types": "^2.5.0-beta.0", "@0x/typescript-typings": "^4.4.0-beta.0", "@0x/utils": "^4.6.0-beta.0", "@0x/web3-wrapper": "^6.1.0-beta.0", "ethereum-types": "^2.2.0-beta.0", - "ethereumjs-util": "^5.1.1", - "lodash": "^4.17.11" + "ethereumjs-util": "^5.1.1" }, "publishConfig": { "access": "public" diff --git a/contracts/dev-utils/CHANGELOG.json b/contracts/dev-utils/CHANGELOG.json index b2bafed5a6..ede1ff78b4 100644 --- a/contracts/dev-utils/CHANGELOG.json +++ b/contracts/dev-utils/CHANGELOG.json @@ -1,4 +1,17 @@ [ + { + "version": "0.1.0-beta.1", + "changes": [ + { + "note": "Add `encodeStaticCallAssetData` and `decodeStaticCallAssetData` in LibAssetData", + "pr": 2034 + }, + { + "note": "Add `revertIfInvalidAssetData` in LibAssetData", + "pr": 2034 + } + ] + }, { "version": "0.1.0-beta.0", "changes": [ diff --git a/contracts/dev-utils/contracts/src/LibAssetData.sol b/contracts/dev-utils/contracts/src/LibAssetData.sol index 6b140ab2d1..2fda7a18de 100644 --- a/contracts/dev-utils/contracts/src/LibAssetData.sol +++ b/contracts/dev-utils/contracts/src/LibAssetData.sol @@ -316,6 +316,29 @@ contract LibAssetData { return (balances, allowances); } + /// @dev Decode AssetProxy identifier + /// @param assetData AssetProxy-compliant asset data describing an ERC-20, ERC-721, ERC1155, or MultiAsset asset. + /// @return The AssetProxy identifier + function decodeAssetProxyId(bytes memory assetData) + public + pure + returns ( + bytes4 assetProxyId + ) + { + assetProxyId = assetData.readBytes4(0); + + require( + assetProxyId == IAssetData(address(0)).ERC20Token.selector || + assetProxyId == IAssetData(address(0)).ERC721Token.selector || + assetProxyId == IAssetData(address(0)).ERC1155Assets.selector || + assetProxyId == IAssetData(address(0)).MultiAsset.selector || + assetProxyId == IAssetData(address(0)).StaticCall.selector, + "WRONG_PROXY_ID" + ); + return assetProxyId; + } + /// @dev Encode ERC-20 asset data into the format described in the AssetProxy contract specification. /// @param tokenAddress The address of the ERC-20 contract hosting the asset to be traded. /// @return AssetProxy-compliant data describing the asset. @@ -330,7 +353,7 @@ contract LibAssetData { /// @dev Decode ERC-20 asset data from the format described in the AssetProxy contract specification. /// @param assetData AssetProxy-compliant asset data describing an ERC-20 asset. - /// @return The ERC-20 AssetProxy identifier, and the address of the ERC-20 + /// @return The AssetProxy identifier, and the address of the ERC-20 /// contract hosting this asset. function decodeERC20AssetData(bytes memory assetData) public @@ -515,4 +538,75 @@ contract LibAssetData { ); // solhint-enable indent } + + /// @dev Encode StaticCall asset data into the format described in the AssetProxy contract specification. + /// @param staticCallTargetAddress Target address of StaticCall. + /// @param staticCallData Data that will be passed to staticCallTargetAddress in the StaticCall. + /// @param expectedReturnDataHash Expected Keccak-256 hash of the StaticCall return data. + /// @return AssetProxy-compliant asset data describing the set of assets. + function encodeStaticCallAssetData( + address staticCallTargetAddress, + bytes memory staticCallData, + bytes32 expectedReturnDataHash + ) + public + pure + returns (bytes memory assetData) + { + assetData = abi.encodeWithSelector( + IAssetData(address(0)).StaticCall.selector, + staticCallTargetAddress, + staticCallData, + expectedReturnDataHash + ); + return assetData; + } + + /// @dev Decode StaticCall asset data from the format described in the AssetProxy contract specification. + /// @param assetData AssetProxy-compliant asset data describing a StaticCall asset + /// @return The StaticCall AssetProxy identifier, the target address of the StaticCAll, the data to be + /// passed to the target address, and the expected Keccak-256 hash of the static call return data. + function decodeStaticCallAssetData(bytes memory assetData) + public + pure + returns ( + bytes4 assetProxyId, + address staticCallTargetAddress, + bytes memory staticCallData, + bytes32 expectedReturnDataHash + ) + { + assetProxyId = assetData.readBytes4(0); + + require( + assetProxyId == IAssetData(address(0)).StaticCall.selector, + "WRONG_PROXY_ID" + ); + + (staticCallTargetAddress, staticCallData, expectedReturnDataHash) = abi.decode( + assetData.slice(4, assetData.length), + (address, bytes, bytes32) + ); + } + + function revertIfInvalidAssetData(bytes memory assetData) + public + pure + { + bytes4 assetProxyId = assetData.readBytes4(0); + + if (assetProxyId == IAssetData(address(0)).ERC20Token.selector) { + decodeERC20AssetData(assetData); + } else if (assetProxyId == IAssetData(address(0)).ERC721Token.selector) { + decodeERC721AssetData(assetData); + } else if (assetProxyId == IAssetData(address(0)).ERC1155Assets.selector) { + decodeERC1155AssetData(assetData); + } else if (assetProxyId == IAssetData(address(0)).MultiAsset.selector) { + decodeMultiAssetData(assetData); + } else if (assetProxyId == IAssetData(address(0)).StaticCall.selector) { + decodeStaticCallAssetData(assetData); + } else { + revert("WRONG_PROXY_ID"); + } + } } diff --git a/contracts/exchange-forwarder/package.json b/contracts/exchange-forwarder/package.json index 70aa454cfb..f7d0ce0d89 100644 --- a/contracts/exchange-forwarder/package.json +++ b/contracts/exchange-forwarder/package.json @@ -72,6 +72,7 @@ "dependencies": { "@0x/base-contract": "^5.5.0-beta.0", "@0x/contracts-asset-proxy": "^2.3.0-beta.0", + "@0x/contracts-dev-utils": "^0.1.0-beta.0", "@0x/contracts-erc20": "^2.3.0-beta.0", "@0x/contracts-erc721": "^2.2.0-beta.0", "@0x/contracts-exchange": "^2.2.0-beta.0", diff --git a/contracts/exchange/CHANGELOG.json b/contracts/exchange/CHANGELOG.json index 741ff3f973..50212acccd 100644 --- a/contracts/exchange/CHANGELOG.json +++ b/contracts/exchange/CHANGELOG.json @@ -1,4 +1,25 @@ [ + { + "version": "2.2.0-beta.1", + "changes": [ + { + "note": "LocalBalanceStore.create and constructor now require an instance of DevUtilsContract", + "pr": 2304 + }, + { + "note": "In LocalBalanceStore, `transferAsset` is now `transferAssetAsync`", + "pr": 2304 + }, + { + "note": "Test utility classes AssetWrapper, MatchOrderTester, and OrderFactoryFromScenario constructors now require an instance of DevUtilsContract", + "pr": 2304 + }, + { + "note": "In OrderFactoryFromScenario, `generateOrder` is now `generateOrderAsync`", + "pr": 2304 + } + ] + }, { "version": "2.2.0-beta.0", "changes": [ diff --git a/contracts/exchange/package.json b/contracts/exchange/package.json index 0c2d9b033c..b32c36e5c6 100644 --- a/contracts/exchange/package.json +++ b/contracts/exchange/package.json @@ -76,6 +76,7 @@ "dependencies": { "@0x/base-contract": "^5.5.0-beta.0", "@0x/contracts-asset-proxy": "^2.3.0-beta.0", + "@0x/contracts-dev-utils": "^0.1.0-beta.0", "@0x/contracts-erc1155": "^1.2.0-beta.0", "@0x/contracts-erc20": "^2.3.0-beta.0", "@0x/contracts-erc721": "^2.2.0-beta.0", diff --git a/contracts/exchange/test/assertion_wrappers/fill_order_wrapper.ts b/contracts/exchange/test/assertion_wrappers/fill_order_wrapper.ts index 242a0ab8e7..0c6e552f3b 100644 --- a/contracts/exchange/test/assertion_wrappers/fill_order_wrapper.ts +++ b/contracts/exchange/test/assertion_wrappers/fill_order_wrapper.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { ReferenceFunctions as LibReferenceFunctions } from '@0x/contracts-exchange-libs'; import { constants, @@ -24,68 +25,8 @@ import { } from '../../src'; export class FillOrderWrapper { - private readonly _exchange: ExchangeContract; private readonly _blockchainBalanceStore: BlockchainBalanceStore; - /** - * Locally simulates filling an order. - * @param txReceipt Transaction receipt from the actual fill, needed to update eth balance - * @param signedOrder The order being filled. - * @param takerAddress Address of taker (the address who matched the two orders) - * @param opts Optionally specifies the amount to fill. - * @param initBalanceStore Account balances prior to the fill. - * @return The expected account balances, fill results, and fill events. - */ - public static simulateFillOrder( - txReceipt: TransactionReceiptWithDecodedLogs, - signedOrder: SignedOrder, - takerAddress: string, - initBalanceStore: BalanceStore, - opts: { takerAssetFillAmount?: BigNumber } = {}, - ): [FillResults, FillEventArgs, BalanceStore] { - const balanceStore = LocalBalanceStore.create(initBalanceStore); - const takerAssetFillAmount = - opts.takerAssetFillAmount !== undefined ? opts.takerAssetFillAmount : signedOrder.takerAssetAmount; - // TODO(jalextowle): Change this if the integration tests take protocol fees into account. - const fillResults = LibReferenceFunctions.calculateFillResults( - signedOrder, - takerAssetFillAmount, - constants.ZERO_AMOUNT, - constants.ZERO_AMOUNT, - ); - const fillEvent = FillOrderWrapper.simulateFillEvent(signedOrder, takerAddress, fillResults); - // Taker -> Maker - balanceStore.transferAsset( - takerAddress, - signedOrder.makerAddress, - fillResults.takerAssetFilledAmount, - signedOrder.takerAssetData, - ); - // Maker -> Taker - balanceStore.transferAsset( - signedOrder.makerAddress, - takerAddress, - fillResults.makerAssetFilledAmount, - signedOrder.makerAssetData, - ); - // Taker -> Fee Recipient - balanceStore.transferAsset( - takerAddress, - signedOrder.feeRecipientAddress, - fillResults.takerFeePaid, - signedOrder.takerFeeAssetData, - ); - // Maker -> Fee Recipient - balanceStore.transferAsset( - signedOrder.makerAddress, - signedOrder.feeRecipientAddress, - fillResults.makerFeePaid, - signedOrder.makerFeeAssetData, - ); - balanceStore.burnGas(txReceipt.from, constants.DEFAULT_GAS_PRICE * txReceipt.gasUsed); - return [fillResults, fillEvent, balanceStore]; - } - /** * Simulates the event emitted by the exchange contract when an order is filled. */ @@ -119,6 +60,65 @@ export class FillOrderWrapper { return events.map(event => _.pick(event, fieldsOfInterest)) as FillEventArgs[]; } + /** + * Locally simulates filling an order. + * @param txReceipt Transaction receipt from the actual fill, needed to update eth balance + * @param signedOrder The order being filled. + * @param takerAddress Address of taker (the address who matched the two orders) + * @param opts Optionally specifies the amount to fill. + * @param initBalanceStore Account balances prior to the fill. + * @return The expected account balances, fill results, and fill events. + */ + public async simulateFillOrderAsync( + txReceipt: TransactionReceiptWithDecodedLogs, + signedOrder: SignedOrder, + takerAddress: string, + initBalanceStore: BalanceStore, + opts: { takerAssetFillAmount?: BigNumber } = {}, + ): Promise<[FillResults, FillEventArgs, BalanceStore]> { + const balanceStore = LocalBalanceStore.create(this._devUtils, initBalanceStore); + const takerAssetFillAmount = + opts.takerAssetFillAmount !== undefined ? opts.takerAssetFillAmount : signedOrder.takerAssetAmount; + // TODO(jalextowle): Change this if the integration tests take protocol fees into account. + const fillResults = LibReferenceFunctions.calculateFillResults( + signedOrder, + takerAssetFillAmount, + constants.ZERO_AMOUNT, + constants.ZERO_AMOUNT, + ); + const fillEvent = FillOrderWrapper.simulateFillEvent(signedOrder, takerAddress, fillResults); + // Taker -> Maker + await balanceStore.transferAssetAsync( + takerAddress, + signedOrder.makerAddress, + fillResults.takerAssetFilledAmount, + signedOrder.takerAssetData, + ); + // Maker -> Taker + await balanceStore.transferAssetAsync( + signedOrder.makerAddress, + takerAddress, + fillResults.makerAssetFilledAmount, + signedOrder.makerAssetData, + ); + // Taker -> Fee Recipient + await balanceStore.transferAssetAsync( + takerAddress, + signedOrder.feeRecipientAddress, + fillResults.takerFeePaid, + signedOrder.takerFeeAssetData, + ); + // Maker -> Fee Recipient + await balanceStore.transferAssetAsync( + signedOrder.makerAddress, + signedOrder.feeRecipientAddress, + fillResults.makerFeePaid, + signedOrder.makerFeeAssetData, + ); + balanceStore.burnGas(txReceipt.from, constants.DEFAULT_GAS_PRICE * txReceipt.gasUsed); + return [fillResults, fillEvent, balanceStore]; + } + /** * Constructor. * @param exchangeContract Instance of the deployed exchange contract. @@ -127,12 +127,12 @@ export class FillOrderWrapper { * @param tokenIds The tokenIds of ERC721 and ERC1155 assets to assert the balances of. */ public constructor( - exchangeContract: ExchangeContract, + private readonly _exchange: ExchangeContract, + private readonly _devUtils: DevUtilsContract, tokenOwnersByName: TokenOwnersByName, tokenContractsByName: Partial, tokenIds: Partial, ) { - this._exchange = exchangeContract; this._blockchainBalanceStore = new BlockchainBalanceStore(tokenOwnersByName, tokenContractsByName, tokenIds); } @@ -168,7 +168,7 @@ export class FillOrderWrapper { simulatedFillResults, simulatedFillEvent, simulatedFinalBalanceStore, - ] = FillOrderWrapper.simulateFillOrder(txReceipt, signedOrder, from, this._blockchainBalanceStore, opts); + ] = await this.simulateFillOrderAsync(txReceipt, signedOrder, from, this._blockchainBalanceStore, opts); // Assert state transition expect(simulatedFillResults, 'Fill Results').to.be.deep.equal(fillResults); expect(simulatedFillEvent, 'Fill Events').to.be.deep.equal(fillEvent); diff --git a/contracts/exchange/test/balance_stores/local_balance_store.ts b/contracts/exchange/test/balance_stores/local_balance_store.ts index 4474af5025..458777a871 100644 --- a/contracts/exchange/test/balance_stores/local_balance_store.ts +++ b/contracts/exchange/test/balance_stores/local_balance_store.ts @@ -1,5 +1,5 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { constants, Numberish } from '@0x/contracts-test-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; @@ -12,8 +12,8 @@ export class LocalBalanceStore extends BalanceStore { * Creates a new balance store based on an existing one. * @param sourceBalanceStore Existing balance store whose values should be copied. */ - public static create(sourceBalanceStore?: BalanceStore): LocalBalanceStore { - const localBalanceStore = new LocalBalanceStore(); + public static create(devUtils: DevUtilsContract, sourceBalanceStore?: BalanceStore): LocalBalanceStore { + const localBalanceStore = new LocalBalanceStore(devUtils); if (sourceBalanceStore !== undefined) { localBalanceStore.cloneFrom(sourceBalanceStore); } @@ -26,6 +26,7 @@ export class LocalBalanceStore extends BalanceStore { * be initialized via `create`. */ protected constructor( + private readonly _devUtils: DevUtilsContract, tokenOwnersByName: TokenOwnersByName = {}, tokenContractsByName: Partial = {}, ) { @@ -71,27 +72,33 @@ export class LocalBalanceStore extends BalanceStore { * @param amount Amount of asset(s) to transfer * @param assetData Asset data of assets being transferred. */ - public transferAsset(fromAddress: string, toAddress: string, amount: BigNumber, assetData: string): void { + public async transferAssetAsync( + fromAddress: string, + toAddress: string, + amount: BigNumber, + assetData: string, + ): Promise { if (fromAddress === toAddress) { return; } - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); + const assetProxyId = await this._devUtils.decodeAssetProxyId.callAsync(assetData); switch (assetProxyId) { case AssetProxyId.ERC20: { - const erc20AssetData = assetDataUtils.decodeERC20AssetData(assetData); - const assetAddress = erc20AssetData.tokenAddress; - _.update(this._balances.erc20, [fromAddress, assetAddress], balance => balance.minus(amount)); - _.update(this._balances.erc20, [toAddress, assetAddress], balance => + // tslint:disable-next-line:no-unused-variable + const [proxyId, tokenAddress] = await this._devUtils.decodeERC20AssetData.callAsync(assetData); + _.update(this._balances.erc20, [fromAddress, tokenAddress], balance => balance.minus(amount)); + _.update(this._balances.erc20, [toAddress, tokenAddress], balance => (balance || constants.ZERO_AMOUNT).plus(amount), ); break; } case AssetProxyId.ERC721: { - const erc721AssetData = assetDataUtils.decodeERC721AssetData(assetData); - const assetAddress = erc721AssetData.tokenAddress; - const tokenId = erc721AssetData.tokenId; - const fromTokens = _.get(this._balances.erc721, [fromAddress, assetAddress], []); - const toTokens = _.get(this._balances.erc721, [toAddress, assetAddress], []); + // tslint:disable-next-line:no-unused-variable + const [proxyId, tokenAddress, tokenId] = await this._devUtils.decodeERC721AssetData.callAsync( + assetData, + ); + const fromTokens = _.get(this._balances.erc721, [fromAddress, tokenAddress], []); + const toTokens = _.get(this._balances.erc721, [toAddress, tokenAddress], []); if (amount.gte(1)) { const tokenIndex = _.findIndex(fromTokens as BigNumber[], t => t.eq(tokenId)); if (tokenIndex !== -1) { @@ -100,25 +107,29 @@ export class LocalBalanceStore extends BalanceStore { toTokens.sort(); } } - _.set(this._balances.erc721, [fromAddress, assetAddress], fromTokens); - _.set(this._balances.erc721, [toAddress, assetAddress], toTokens); + _.set(this._balances.erc721, [fromAddress, tokenAddress], fromTokens); + _.set(this._balances.erc721, [toAddress, tokenAddress], toTokens); break; } case AssetProxyId.ERC1155: { - const erc1155AssetData = assetDataUtils.decodeERC1155AssetData(assetData); - const assetAddress = erc1155AssetData.tokenAddress; + const [ + proxyId, // tslint:disable-line:no-unused-variable + tokenAddress, + tokenIds, + tokenValues, + ] = await this._devUtils.decodeERC1155AssetData.callAsync(assetData); const fromBalances = { // tslint:disable-next-line:no-inferred-empty-object-type - fungible: _.get(this._balances.erc1155, [fromAddress, assetAddress, 'fungible'], {}), - nonFungible: _.get(this._balances.erc1155, [fromAddress, assetAddress, 'nonFungible'], []), + fungible: _.get(this._balances.erc1155, [fromAddress, tokenAddress, 'fungible'], {}), + nonFungible: _.get(this._balances.erc1155, [fromAddress, tokenAddress, 'nonFungible'], []), }; const toBalances = { // tslint:disable-next-line:no-inferred-empty-object-type - fungible: _.get(this._balances.erc1155, [toAddress, assetAddress, 'fungible'], {}), - nonFungible: _.get(this._balances.erc1155, [toAddress, assetAddress, 'nonFungible'], []), + fungible: _.get(this._balances.erc1155, [toAddress, tokenAddress, 'fungible'], {}), + nonFungible: _.get(this._balances.erc1155, [toAddress, tokenAddress, 'nonFungible'], []), }; - for (const [i, tokenId] of erc1155AssetData.tokenIds.entries()) { - const tokenValue = erc1155AssetData.tokenValues[i]; + for (const [i, tokenId] of tokenIds.entries()) { + const tokenValue = tokenValues[i]; const tokenAmount = amount.times(tokenValue); if (tokenAmount.gt(0)) { const tokenIndex = _.findIndex(fromBalances.nonFungible as BigNumber[], t => t.eq(tokenId)); @@ -138,16 +149,18 @@ export class LocalBalanceStore extends BalanceStore { } } } - _.set(this._balances.erc1155, [fromAddress, assetAddress], fromBalances); - _.set(this._balances.erc1155, [toAddress, assetAddress], toBalances); + _.set(this._balances.erc1155, [fromAddress, tokenAddress], fromBalances); + _.set(this._balances.erc1155, [toAddress, tokenAddress], toBalances); break; } case AssetProxyId.MultiAsset: { - const multiAssetData = assetDataUtils.decodeMultiAssetData(assetData); - for (const i of _.times(multiAssetData.amounts.length)) { - const nestedAmount = amount.times(multiAssetData.amounts[i]); - const nestedAssetData = multiAssetData.nestedAssetData[i]; - this.transferAsset(fromAddress, toAddress, nestedAmount, nestedAssetData); + // tslint:disable-next-line:no-unused-variable + const [proxyId, amounts, nestedAssetData] = await this._devUtils.decodeMultiAssetData.callAsync( + assetData, + ); + for (const [i, amt] of amounts.entries()) { + const nestedAmount = amount.times(amt); + await this.transferAssetAsync(fromAddress, toAddress, nestedAmount, nestedAssetData[i]); } break; } diff --git a/contracts/exchange/test/core.ts b/contracts/exchange/test/core.ts index 2ee5a2b5e5..55da2bd13b 100644 --- a/contracts/exchange/test/core.ts +++ b/contracts/exchange/test/core.ts @@ -10,6 +10,7 @@ import { StaticCallProxyContract, TestStaticCallTargetContract, } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { ERC1155MintableContract } from '@0x/contracts-erc1155'; import { artifacts as erc20Artifacts, @@ -32,7 +33,7 @@ import { txDefaults, web3Wrapper, } from '@0x/contracts-test-utils'; -import { assetDataUtils, ExchangeRevertErrors, LibMathRevertErrors, orderHashUtils } from '@0x/order-utils'; +import { ExchangeRevertErrors, LibMathRevertErrors, orderHashUtils } from '@0x/order-utils'; import { RevertReason, SignatureType, SignedOrder } from '@0x/types'; import { BigNumber, providerUtils, StringRevertError } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -59,6 +60,7 @@ blockchainTests.resets('Exchange core', () => { let takerAddress: string; let feeRecipientAddress: string; + let devUtils: DevUtilsContract; let erc20TokenA: DummyERC20TokenContract; let erc20TokenB: DummyERC20TokenContract; let feeToken: DummyERC20TokenContract; @@ -100,6 +102,7 @@ blockchainTests.resets('Exchange core', () => { const accounts = await web3Wrapper.getAvailableAddressesAsync(); const usedAddresses = ([owner, makerAddress, takerAddress, feeRecipientAddress] = _.slice(accounts, 0, 4)); + devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner); erc721Wrapper = new ERC721Wrapper(provider, usedAddresses, owner); erc1155ProxyWrapper = new ERC1155ProxyWrapper(provider, usedAddresses, owner); @@ -213,10 +216,10 @@ blockchainTests.resets('Exchange core', () => { ...constants.STATIC_ORDER_PARAMS, makerAddress, feeRecipientAddress, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultFeeAssetAddress), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultFeeAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerAssetAddress), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultFeeAssetAddress), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultFeeAssetAddress), exchangeAddress: exchange.address, chainId, }; @@ -239,6 +242,7 @@ blockchainTests.resets('Exchange core', () => { }; fillOrderWrapper = new FillOrderWrapper( exchange, + devUtils, { makerAddress, takerAddress, feeRecipientAddress }, tokenContracts, tokenIds, @@ -421,9 +425,9 @@ blockchainTests.resets('Exchange core', () => { describe('Fill transfer ordering', () => { it('should allow the maker to exchange assets received by the taker', async () => { // Set maker/taker assetData to the same asset - const takerAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const takerAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const takerAssetAmount = new BigNumber(1); - const makerAssetData = assetDataUtils.encodeMultiAssetData([takerAssetAmount], [takerAssetData]); + const makerAssetData = await devUtils.encodeMultiAssetData.callAsync([takerAssetAmount], [takerAssetData]); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData, takerAssetData, @@ -439,7 +443,7 @@ blockchainTests.resets('Exchange core', () => { await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress); }); it('should allow the taker to pay fees with an asset that received by the maker', async () => { - const makerAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const makerAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); signedOrder = await orderFactory.newSignedOrderAsync({ takerFeeAssetData: makerAssetData, makerFee: constants.ZERO_AMOUNT, @@ -452,7 +456,7 @@ blockchainTests.resets('Exchange core', () => { await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress); }); it('should allow the maker to pay fees with an asset that received by the taker', async () => { - const takerAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const takerAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); signedOrder = await orderFactory.newSignedOrderAsync({ makerFeeAssetData: takerAssetData, makerFee: new BigNumber(1), @@ -479,7 +483,7 @@ blockchainTests.resets('Exchange core', () => { }); it('should transfer the correct amounts when makerAssetAmount === takerAssetAmount', async () => { signedOrder = await orderFactory.newSignedOrderAsync({ - makerAssetData: assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18), }); @@ -487,7 +491,7 @@ blockchainTests.resets('Exchange core', () => { }); it('should transfer the correct amounts when makerAssetAmount > takerAssetAmount', async () => { signedOrder = await orderFactory.newSignedOrderAsync({ - makerAssetData: assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18), }); @@ -495,7 +499,7 @@ blockchainTests.resets('Exchange core', () => { }); it('should transfer the correct amounts when makerAssetAmount < takerAssetAmount', async () => { signedOrder = await orderFactory.newSignedOrderAsync({ - makerAssetData: assetDataUtils.encodeERC20AssetData(noReturnErc20Token.address), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(noReturnErc20Token.address), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), 18), }); @@ -672,8 +676,8 @@ blockchainTests.resets('Exchange core', () => { signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(1), takerAssetAmount: new BigNumber(1), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), - takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, makerAssetId), + takerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, takerAssetId), }); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); // Verify pre-conditions @@ -699,8 +703,8 @@ blockchainTests.resets('Exchange core', () => { signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(1), takerAssetAmount: new BigNumber(1), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), - takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, makerAssetId), + takerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, takerAssetId), }); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); // Verify pre-conditions @@ -726,8 +730,8 @@ blockchainTests.resets('Exchange core', () => { signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(2), takerAssetAmount: new BigNumber(1), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), - takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, makerAssetId), + takerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, takerAssetId), }); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); // Verify pre-conditions @@ -753,8 +757,8 @@ blockchainTests.resets('Exchange core', () => { signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(1), takerAssetAmount: new BigNumber(500), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), - takerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, makerAssetId), + takerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, takerAssetId), }); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); // Verify pre-conditions @@ -779,8 +783,8 @@ blockchainTests.resets('Exchange core', () => { signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetAmount: new BigNumber(1), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), 18), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, makerAssetId), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerAssetAddress), }); // Call Exchange const takerAssetFillAmount = signedOrder.takerAssetAmount.div(2); @@ -798,12 +802,12 @@ blockchainTests.resets('Exchange core', () => { it('should allow multiple assets to be exchanged for a single asset', async () => { const makerAmounts = [new BigNumber(10), new BigNumber(20)]; const makerNestedAssetData = [ - assetDataUtils.encodeERC20AssetData(erc20TokenA.address), - assetDataUtils.encodeERC20AssetData(erc20TokenB.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address), ]; - const makerAssetData = assetDataUtils.encodeMultiAssetData(makerAmounts, makerNestedAssetData); + const makerAssetData = await devUtils.encodeMultiAssetData.callAsync(makerAmounts, makerNestedAssetData); const makerAssetAmount = new BigNumber(1); - const takerAssetData = assetDataUtils.encodeERC20AssetData(feeToken.address); + const takerAssetData = await devUtils.encodeERC20AssetData.callAsync(feeToken.address); const takerAssetAmount = new BigNumber(10); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData, @@ -818,18 +822,18 @@ blockchainTests.resets('Exchange core', () => { it('should allow multiple assets to be exchanged for multiple assets', async () => { const makerAmounts = [new BigNumber(10), new BigNumber(20)]; const makerNestedAssetData = [ - assetDataUtils.encodeERC20AssetData(erc20TokenA.address), - assetDataUtils.encodeERC20AssetData(erc20TokenB.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address), ]; - const makerAssetData = assetDataUtils.encodeMultiAssetData(makerAmounts, makerNestedAssetData); + const makerAssetData = await devUtils.encodeMultiAssetData.callAsync(makerAmounts, makerNestedAssetData); const makerAssetAmount = new BigNumber(1); const takerAmounts = [new BigNumber(10), new BigNumber(1)]; const takerAssetId = erc721TakerAssetIds[0]; const takerNestedAssetData = [ - assetDataUtils.encodeERC20AssetData(feeToken.address), - assetDataUtils.encodeERC721AssetData(erc721Token.address, takerAssetId), + await devUtils.encodeERC20AssetData.callAsync(feeToken.address), + await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, takerAssetId), ]; - const takerAssetData = assetDataUtils.encodeMultiAssetData(takerAmounts, takerNestedAssetData); + const takerAssetData = await devUtils.encodeMultiAssetData.callAsync(takerAmounts, takerNestedAssetData); const takerAssetAmount = new BigNumber(1); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData, @@ -844,12 +848,12 @@ blockchainTests.resets('Exchange core', () => { it('should allow an order selling multiple assets to be partially filled', async () => { const makerAmounts = [new BigNumber(10), new BigNumber(20)]; const makerNestedAssetData = [ - assetDataUtils.encodeERC20AssetData(erc20TokenA.address), - assetDataUtils.encodeERC20AssetData(erc20TokenB.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address), ]; - const makerAssetData = assetDataUtils.encodeMultiAssetData(makerAmounts, makerNestedAssetData); + const makerAssetData = await devUtils.encodeMultiAssetData.callAsync(makerAmounts, makerNestedAssetData); const makerAssetAmount = new BigNumber(30); - const takerAssetData = assetDataUtils.encodeERC20AssetData(feeToken.address); + const takerAssetData = await devUtils.encodeERC20AssetData.callAsync(feeToken.address); const takerAssetAmount = new BigNumber(10); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData, @@ -866,12 +870,12 @@ blockchainTests.resets('Exchange core', () => { it('should allow an order buying multiple assets to be partially filled', async () => { const takerAmounts = [new BigNumber(10), new BigNumber(20)]; const takerNestedAssetData = [ - assetDataUtils.encodeERC20AssetData(erc20TokenA.address), - assetDataUtils.encodeERC20AssetData(erc20TokenB.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address), + await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address), ]; - const takerAssetData = assetDataUtils.encodeMultiAssetData(takerAmounts, takerNestedAssetData); + const takerAssetData = await devUtils.encodeMultiAssetData.callAsync(takerAmounts, takerNestedAssetData); const takerAssetAmount = new BigNumber(30); - const makerAssetData = assetDataUtils.encodeERC20AssetData(feeToken.address); + const makerAssetData = await devUtils.encodeERC20AssetData.callAsync(feeToken.address); const makerAssetAmount = new BigNumber(10); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData, @@ -897,13 +901,13 @@ blockchainTests.resets('Exchange core', () => { const makerAssetAmount = new BigNumber(1); const takerAssetAmount = new BigNumber(1); const receiverCallbackData = '0x'; - const makerAssetData = assetDataUtils.encodeERC1155AssetData( + const makerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, makerAssetsToTransfer, makerValuesToTransfer, receiverCallbackData, ); - const takerAssetData = assetDataUtils.encodeERC1155AssetData( + const takerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, takerAssetsToTransfer, takerValuesToTransfer, @@ -932,13 +936,13 @@ blockchainTests.resets('Exchange core', () => { const makerAssetAmount = new BigNumber(1); const takerAssetAmount = new BigNumber(1); const receiverCallbackData = '0x'; - const makerAssetData = assetDataUtils.encodeERC1155AssetData( + const makerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, makerAssetsToTransfer, makerValuesToTransfer, receiverCallbackData, ); - const takerAssetData = assetDataUtils.encodeERC1155AssetData( + const takerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, takerAssetsToTransfer, takerValuesToTransfer, @@ -966,13 +970,13 @@ blockchainTests.resets('Exchange core', () => { const makerAssetAmount = new BigNumber(1); const takerAssetAmount = new BigNumber(1); const receiverCallbackData = '0x'; - const makerAssetData = assetDataUtils.encodeERC1155AssetData( + const makerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, makerAssetsToTransfer, makerValuesToTransfer, receiverCallbackData, ); - const takerAssetData = assetDataUtils.encodeERC1155AssetData( + const takerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, takerAssetsToTransfer, takerValuesToTransfer, @@ -1006,13 +1010,13 @@ blockchainTests.resets('Exchange core', () => { const makerAssetAmount = new BigNumber(1); const takerAssetAmount = new BigNumber(1); const receiverCallbackData = '0x'; - const makerAssetData = assetDataUtils.encodeERC1155AssetData( + const makerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, makerAssetsToTransfer, makerValuesToTransfer, receiverCallbackData, ); - const takerAssetData = assetDataUtils.encodeERC1155AssetData( + const takerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, takerAssetsToTransfer, takerValuesToTransfer, @@ -1051,13 +1055,13 @@ blockchainTests.resets('Exchange core', () => { const makerAssetAmount = new BigNumber(10); const takerAssetAmount = new BigNumber(20); const receiverCallbackData = '0x'; - const makerAssetData = assetDataUtils.encodeERC1155AssetData( + const makerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, makerAssetsToTransfer, makerValuesToTransfer, receiverCallbackData, ); - const takerAssetData = assetDataUtils.encodeERC1155AssetData( + const takerAssetData = await devUtils.encodeERC1155AssetData.callAsync( erc1155Contract.address, takerAssetsToTransfer, takerValuesToTransfer, @@ -1088,7 +1092,7 @@ blockchainTests.resets('Exchange core', () => { }); it('should revert if the staticcall is unsuccessful', async () => { const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1)); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, constants.KECCAK256_NULL, @@ -1107,7 +1111,7 @@ blockchainTests.resets('Exchange core', () => { const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData( constants.ZERO_AMOUNT, ); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, constants.KECCAK256_NULL, @@ -1117,14 +1121,14 @@ blockchainTests.resets('Exchange core', () => { }); it('should revert if the staticcall is unsuccessful using the MultiAssetProxy', async () => { const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData(new BigNumber(1)); - const staticCallAssetData = assetDataUtils.encodeStaticCallAssetData( + const staticCallAssetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, constants.KECCAK256_NULL, ); - const assetData = assetDataUtils.encodeMultiAssetData( + const assetData = await devUtils.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], - [assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), staticCallAssetData], + [await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), staticCallAssetData], ); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: assetData }); const orderHashHex = orderHashUtils.getOrderHashHex(signedOrder); @@ -1140,14 +1144,14 @@ blockchainTests.resets('Exchange core', () => { const staticCallData = staticCallTarget.assertEvenNumber.getABIEncodedTransactionData( constants.ZERO_AMOUNT, ); - const staticCallAssetData = assetDataUtils.encodeStaticCallAssetData( + const staticCallAssetData = await devUtils.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, constants.KECCAK256_NULL, ); - const assetData = assetDataUtils.encodeMultiAssetData( + const assetData = await devUtils.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], - [assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), staticCallAssetData], + [await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), staticCallAssetData], ); signedOrder = await orderFactory.newSignedOrderAsync({ makerAssetData: assetData }); await fillOrderWrapper.fillOrderAndAssertEffectsAsync(signedOrder, takerAddress); diff --git a/contracts/exchange/test/dispatcher.ts b/contracts/exchange/test/dispatcher.ts index e82a738efa..067f3e2fac 100644 --- a/contracts/exchange/test/dispatcher.ts +++ b/contracts/exchange/test/dispatcher.ts @@ -5,6 +5,7 @@ import { ERC721ProxyContract, ERC721Wrapper, } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { chaiSetup, @@ -16,7 +17,7 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils, ExchangeRevertErrors } from '@0x/order-utils'; +import { ExchangeRevertErrors } from '@0x/order-utils'; import { AssetProxyId, RevertReason } from '@0x/types'; import { BigNumber, OwnableRevertErrors, StringRevertError } from '@0x/utils'; import * as chai from 'chai'; @@ -50,6 +51,7 @@ describe('AssetProxyDispatcher', () => { let erc20Wrapper: ERC20Wrapper; let erc721Wrapper: ERC721Wrapper; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); before(async () => { await blockchainLifecycle.startAsync(); }); @@ -191,7 +193,7 @@ describe('AssetProxyDispatcher', () => { from: owner, }); // Construct metadata for ERC20 proxy - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); @@ -220,7 +222,7 @@ describe('AssetProxyDispatcher', () => { from: owner, }); // Construct metadata for ERC20 proxy - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); // Perform a transfer from makerAddress to takerAddress const erc20Balances = await erc20Wrapper.getBalancesAsync(); @@ -240,7 +242,8 @@ describe('AssetProxyDispatcher', () => { it('should revert if dispatching to unregistered proxy', async () => { // Construct metadata for ERC20 proxy - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + // Perform a transfer from makerAddress to takerAddress const amount = new BigNumber(10); const expectedError = new ExchangeRevertErrors.AssetProxyDispatchError( @@ -263,7 +266,7 @@ describe('AssetProxyDispatcher', () => { await assetProxyDispatcher.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address, { from: owner, }); - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address).slice(0, 8); + const encodedAssetData = (await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address)).slice(0, 8); const amount = new BigNumber(1); const expectedError = new ExchangeRevertErrors.AssetProxyDispatchError( ExchangeRevertErrors.AssetProxyDispatchErrorCode.InvalidAssetDataLength, @@ -286,7 +289,7 @@ describe('AssetProxyDispatcher', () => { from: owner, }); // Shave off the last byte - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address).slice(0, 72); + const encodedAssetData = (await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address)).slice(0, 72); const amount = new BigNumber(1); const expectedError = new ExchangeRevertErrors.AssetProxyDispatchError( ExchangeRevertErrors.AssetProxyDispatchErrorCode.InvalidAssetDataLength, @@ -311,7 +314,7 @@ describe('AssetProxyDispatcher', () => { await erc20TokenA.approve.awaitTransactionSuccessAsync(erc20Proxy.address, constants.ZERO_AMOUNT, { from: makerAddress, }); - const encodedAssetData = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); + const encodedAssetData = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); const amount = new BigNumber(1); const nestedError = new StringRevertError(RevertReason.TransferFailed).encode(); const expectedError = new ExchangeRevertErrors.AssetProxyTransferError( @@ -335,8 +338,8 @@ describe('AssetProxyDispatcher', () => { await assetProxyDispatcher.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address, { from: owner, }); - const assetDataA = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const assetDataB = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const assetDataA = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const assetDataB = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); await erc20TokenB.approve.awaitTransactionSuccessAsync(erc20Proxy.address, constants.ZERO_AMOUNT, { from: makerAddress, }); @@ -356,8 +359,8 @@ describe('AssetProxyDispatcher', () => { return expect(tx).to.revertWith(expectedError); }); it('should forward the revert reason from the underlying failed transfer', async () => { - const assetDataA = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const assetDataB = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const assetDataA = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const assetDataB = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); const transferIndexAsBytes32 = '0x0000000000000000000000000000000000000000000000000000000000000000'; const expectedError = new ExchangeRevertErrors.AssetProxyDispatchError( ExchangeRevertErrors.AssetProxyDispatchErrorCode.UnknownAssetProxy, @@ -376,8 +379,8 @@ describe('AssetProxyDispatcher', () => { await assetProxyDispatcher.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address, { from: owner, }); - const assetDataA = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const assetDataB = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const assetDataA = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const assetDataB = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); const tx = assetProxyDispatcher.simulateDispatchTransferFromCalls.sendTransactionAsync( [assetDataA, assetDataB], [makerAddress, makerAddress], @@ -390,8 +393,8 @@ describe('AssetProxyDispatcher', () => { await assetProxyDispatcher.registerAssetProxy.awaitTransactionSuccessAsync(erc20Proxy.address, { from: owner, }); - const assetDataA = assetDataUtils.encodeERC20AssetData(erc20TokenA.address); - const assetDataB = assetDataUtils.encodeERC20AssetData(erc20TokenB.address); + const assetDataA = await devUtils.encodeERC20AssetData.callAsync(erc20TokenA.address); + const assetDataB = await devUtils.encodeERC20AssetData.callAsync(erc20TokenB.address); const balances = await erc20Wrapper.getBalancesAsync(); try { await assetProxyDispatcher.simulateDispatchTransferFromCalls.awaitTransactionSuccessAsync( diff --git a/contracts/exchange/test/match_orders.ts b/contracts/exchange/test/match_orders.ts index c2d1a09bb3..e05aad4316 100644 --- a/contracts/exchange/test/match_orders.ts +++ b/contracts/exchange/test/match_orders.ts @@ -8,6 +8,7 @@ import { ERC721Wrapper, MultiAssetProxyContract, } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { ERC1155Contract as ERC1155TokenContract, Erc1155Wrapper as ERC1155Wrapper } from '@0x/contracts-erc1155'; import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { DummyERC721TokenContract } from '@0x/contracts-erc721'; @@ -22,7 +23,7 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils'; +import { ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils'; import { OrderStatus, SignedOrder } from '@0x/types'; import { BigNumber, providerUtils } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -82,6 +83,7 @@ describe('matchOrders', () => { let matchOrderTester: MatchOrderTester; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider, txDefaults); before(async () => { await blockchainLifecycle.startAsync(); }); @@ -177,10 +179,10 @@ describe('matchOrders', () => { const defaultOrderParamsLeft = { ...constants.STATIC_ORDER_PARAMS, makerAddress: makerAddressLeft, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultFeeTokenAddress), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultFeeTokenAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultFeeTokenAddress), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultFeeTokenAddress), feeRecipientAddress: feeRecipientAddressLeft, exchangeAddress: exchange.address, chainId, @@ -188,10 +190,10 @@ describe('matchOrders', () => { const defaultOrderParamsRight = { ...constants.STATIC_ORDER_PARAMS, makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultFeeTokenAddress), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultFeeTokenAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultFeeTokenAddress), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultFeeTokenAddress), feeRecipientAddress: feeRecipientAddressRight, exchangeAddress: exchange.address, chainId, @@ -201,7 +203,13 @@ describe('matchOrders', () => { const privateKeyRight = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(makerAddressRight)]; orderFactoryRight = new OrderFactory(privateKeyRight, defaultOrderParamsRight); // Create match order tester - matchOrderTester = new MatchOrderTester(exchangeWrapper, erc20Wrapper, erc721Wrapper, erc1155ProxyWrapper); + matchOrderTester = new MatchOrderTester( + exchangeWrapper, + erc20Wrapper, + erc721Wrapper, + erc1155ProxyWrapper, + devUtils, + ); tokenBalances = await matchOrderTester.getBalancesAsync(); }); beforeEach(async () => { @@ -338,8 +346,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(83, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(49, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -392,8 +400,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(89, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -443,8 +451,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(83, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(49, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -492,8 +500,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(89, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -537,8 +545,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(2126, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1063, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -1162,7 +1170,7 @@ describe('matchOrders', () => { const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ makerAssetAmount: Web3Wrapper.toBaseUnitAmount(5, 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), feeRecipientAddress: makerAddressLeft, }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ @@ -1259,7 +1267,7 @@ describe('matchOrders', () => { takerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(2, 18), }); @@ -1286,7 +1294,7 @@ describe('matchOrders', () => { it('should revert if the right maker asset is not equal to the left taker asset', async () => { // Create orders to match const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(5, 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), }); @@ -1440,8 +1448,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(87, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(48, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -1528,8 +1536,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(89, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -1579,8 +1587,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(87, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(48, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -1625,8 +1633,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(89, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -1670,8 +1678,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(89, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -1789,8 +1797,8 @@ describe('matchOrders', () => { }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(2126, 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(1063, 0), feeRecipientAddress: feeRecipientAddressRight, @@ -2243,7 +2251,7 @@ describe('matchOrders', () => { const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ makerAssetAmount: Web3Wrapper.toBaseUnitAmount(5, 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), feeRecipientAddress: makerAddressLeft, }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ @@ -2340,7 +2348,7 @@ describe('matchOrders', () => { takerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(2, 18), }); @@ -2367,7 +2375,7 @@ describe('matchOrders', () => { it('should revert if the right maker asset is not equal to the left taker asset', async () => { // Create orders to match const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(5, 18), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(10, 18), }); @@ -2675,11 +2683,11 @@ describe('matchOrders', () => { let nameToERC1155NonFungibleAsset: { [name: string]: [string, BigNumber] }; let nameToMultiAssetAsset: { [name: string]: [BigNumber[], string[]] }; - function getAssetData(assetType: AssetType): string { - const encodeERC20AssetData = assetDataUtils.encodeERC20AssetData; - const encodeERC721AssetData = assetDataUtils.encodeERC721AssetData; - const encodeERC1155AssetData = assetDataUtils.encodeERC1155AssetData; - const encodeMultiAssetData = assetDataUtils.encodeMultiAssetData; + async function getAssetDataAsync(assetType: AssetType): Promise { + const encodeERC20AssetData = await devUtils.encodeERC20AssetData.callAsync; + const encodeERC721AssetData = await devUtils.encodeERC721AssetData.callAsync; + const encodeERC1155AssetData = await devUtils.encodeERC1155AssetData.callAsync; + const encodeMultiAssetData = await devUtils.encodeMultiAssetData.callAsync; if (nameToERC20Asset[assetType] !== undefined) { const tokenAddress = nameToERC20Asset[assetType]; return encodeERC20AssetData(tokenAddress); @@ -2744,8 +2752,8 @@ describe('matchOrders', () => { MULTI_ASSET_A: [ [ONE, TWO], [ - assetDataUtils.encodeERC20AssetData(erc20Tokens[0].address), - assetDataUtils.encodeERC1155AssetData( + await devUtils.encodeERC20AssetData.callAsync(erc20Tokens[0].address), + await devUtils.encodeERC1155AssetData.callAsync( defaultERC1155AssetAddress, [erc1155FungibleTokens[0]], [ONE], @@ -2756,8 +2764,8 @@ describe('matchOrders', () => { MULTI_ASSET_B: [ [ONE, TWO], [ - assetDataUtils.encodeERC20AssetData(erc20Tokens[1].address), - assetDataUtils.encodeERC1155AssetData( + await devUtils.encodeERC20AssetData.callAsync(erc20Tokens[1].address), + await devUtils.encodeERC1155AssetData.callAsync( defaultERC1155AssetAddress, [erc1155FungibleTokens[1]], [ONE], @@ -2768,8 +2776,8 @@ describe('matchOrders', () => { MULTI_ASSET_C: [ [ONE, TWO], [ - assetDataUtils.encodeERC20AssetData(erc20Tokens[2].address), - assetDataUtils.encodeERC1155AssetData( + await devUtils.encodeERC20AssetData.callAsync(erc20Tokens[2].address), + await devUtils.encodeERC1155AssetData.callAsync( defaultERC1155AssetAddress, [erc1155FungibleTokens[2]], [ONE], @@ -2780,8 +2788,8 @@ describe('matchOrders', () => { MULTI_ASSET_D: [ [ONE, TWO], [ - assetDataUtils.encodeERC20AssetData(erc20Tokens[3].address), - assetDataUtils.encodeERC1155AssetData( + await devUtils.encodeERC20AssetData.callAsync(erc20Tokens[3].address), + await devUtils.encodeERC1155AssetData.callAsync( erc1155Token.address, [erc1155FungibleTokens[3]], [ONE], @@ -2825,20 +2833,20 @@ describe('matchOrders', () => { ? leftMakerAssetAmount.minus(rightTakerAssetAmount) : Web3Wrapper.toBaseUnitAmount(0, 0); const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ - makerAssetData: getAssetData(combo.leftMaker), - takerAssetData: getAssetData(combo.rightMaker), - makerFeeAssetData: getAssetData(combo.leftMakerFee), - takerFeeAssetData: getAssetData(combo.leftTakerFee), + makerAssetData: await getAssetDataAsync(combo.leftMaker), + takerAssetData: await getAssetDataAsync(combo.rightMaker), + makerFeeAssetData: await getAssetDataAsync(combo.leftMakerFee), + takerFeeAssetData: await getAssetDataAsync(combo.leftTakerFee), makerAssetAmount: leftMakerAssetAmount, takerAssetAmount: leftTakerAssetAmount, makerFee: leftMakerFeeAssetAmount, takerFee: leftTakerFeeAssetAmount, }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ - makerAssetData: getAssetData(combo.rightMaker), - takerAssetData: getAssetData(combo.leftMaker), - makerFeeAssetData: getAssetData(combo.rightMakerFee), - takerFeeAssetData: getAssetData(combo.rightTakerFee), + makerAssetData: await getAssetDataAsync(combo.rightMaker), + takerAssetData: await getAssetDataAsync(combo.leftMaker), + makerFeeAssetData: await getAssetDataAsync(combo.rightMakerFee), + takerFeeAssetData: await getAssetDataAsync(combo.rightTakerFee), makerAssetAmount: rightMakerAssetAmount, takerAssetAmount: rightTakerAssetAmount, makerFee: rightMakerFeeAssetAmount, @@ -2911,20 +2919,20 @@ describe('matchOrders', () => { ? rightMakerAssetAmount.minus(leftTakerAssetAmount) : Web3Wrapper.toBaseUnitAmount(0, 0); const signedOrderLeft = await orderFactoryLeft.newSignedOrderAsync({ - makerAssetData: getAssetData(combo.leftMaker), - takerAssetData: getAssetData(combo.rightMaker), - makerFeeAssetData: getAssetData(combo.leftMakerFee), - takerFeeAssetData: getAssetData(combo.leftTakerFee), + makerAssetData: await getAssetDataAsync(combo.leftMaker), + takerAssetData: await getAssetDataAsync(combo.rightMaker), + makerFeeAssetData: await getAssetDataAsync(combo.leftMakerFee), + takerFeeAssetData: await getAssetDataAsync(combo.leftTakerFee), makerAssetAmount: leftMakerAssetAmount, takerAssetAmount: leftTakerAssetAmount, makerFee: leftMakerFeeAssetAmount, takerFee: leftTakerFeeAssetAmount, }); const signedOrderRight = await orderFactoryRight.newSignedOrderAsync({ - makerAssetData: getAssetData(combo.rightMaker), - takerAssetData: getAssetData(combo.leftMaker), - makerFeeAssetData: getAssetData(combo.rightMakerFee), - takerFeeAssetData: getAssetData(combo.rightTakerFee), + makerAssetData: await getAssetDataAsync(combo.rightMaker), + takerAssetData: await getAssetDataAsync(combo.leftMaker), + makerFeeAssetData: await getAssetDataAsync(combo.rightMakerFee), + takerFeeAssetData: await getAssetDataAsync(combo.rightTakerFee), makerAssetAmount: rightMakerAssetAmount, takerAssetAmount: rightTakerAssetAmount, makerFee: rightMakerFeeAssetAmount, diff --git a/contracts/exchange/test/signature_validator.ts b/contracts/exchange/test/signature_validator.ts index e62b15827f..33aec898fb 100644 --- a/contracts/exchange/test/signature_validator.ts +++ b/contracts/exchange/test/signature_validator.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { blockchainTests, constants, @@ -10,13 +11,7 @@ import { randomAddress, TransactionFactory, } from '@0x/contracts-test-utils'; -import { - assetDataUtils, - ExchangeRevertErrors, - orderHashUtils, - signatureUtils, - transactionHashUtils, -} from '@0x/order-utils'; +import { ExchangeRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils'; import { SignatureType, SignedOrder, SignedZeroExTransaction } from '@0x/types'; import { BigNumber, StringRevertError } from '@0x/utils'; import { LogWithDecodedArgs } from 'ethereum-types'; @@ -42,6 +37,7 @@ blockchainTests.resets('MixinSignatureValidator', env => { let signerPrivateKey: Buffer; let notSignerAddress: string; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, env.provider, env.txDefaults); const eip1271Data = new IEIP1271DataContract(constants.NULL_ADDRESS, env.provider, env.txDefaults); before(async () => { chainId = await env.getChainIdAsync(); @@ -174,7 +170,9 @@ blockchainTests.resets('MixinSignatureValidator', env => { it('should return true when SignatureType=EthSign and signature is valid', async () => { // Create EthSign signature const hashHex = getCurrentHashHex(); - const orderHashWithEthSignPrefixHex = signatureUtils.addSignedMessagePrefix(hashHex); + const orderHashWithEthSignPrefixHex = ethUtil.bufferToHex( + ethUtil.hashPersonalMessage(ethUtil.toBuffer(hashHex)), + ); const signatureHex = hexConcat( signDataHex(orderHashWithEthSignPrefixHex, signerPrivateKey), SignatureType.EthSign, @@ -429,10 +427,10 @@ blockchainTests.resets('MixinSignatureValidator', env => { ...constants.STATIC_ORDER_PARAMS, makerAddress, feeRecipientAddress: randomAddress(), - makerAssetData: assetDataUtils.encodeERC20AssetData(randomAddress()), - takerAssetData: assetDataUtils.encodeERC20AssetData(randomAddress()), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(randomAddress()), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(randomAddress()), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(randomAddress()), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(randomAddress()), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(randomAddress()), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(randomAddress()), makerFee: constants.ZERO_AMOUNT, takerFee: constants.ZERO_AMOUNT, exchangeAddress: signatureValidator.address, diff --git a/contracts/exchange/test/transactions.ts b/contracts/exchange/test/transactions.ts index 13379a4ba0..00e932dbe6 100644 --- a/contracts/exchange/test/transactions.ts +++ b/contracts/exchange/test/transactions.ts @@ -1,5 +1,6 @@ // tslint:disable: max-file-line-count import { ERC20ProxyContract, ERC20Wrapper } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { artifacts as erc20Artifacts, DummyERC20TokenContract } from '@0x/contracts-erc20'; import { blockchainTests, @@ -10,7 +11,7 @@ import { OrderFactory, TransactionFactory, } from '@0x/contracts-test-utils'; -import { assetDataUtils, ExchangeRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils'; +import { ExchangeRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils'; import { FillResults, OrderStatus } from '@0x/types'; import { AbiEncoder, BigNumber } from '@0x/utils'; import { LogWithDecodedArgs, MethodAbi } from 'ethereum-types'; @@ -66,6 +67,7 @@ blockchainTests.resets('Exchange transactions', env => { let takerPrivateKey: Buffer; let taker2PrivateKey: Buffer; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, env.provider, env.txDefaults); before(async () => { chainId = await env.getChainIdAsync(); const accounts = await env.getAccountAddressesAsync(); @@ -110,10 +112,10 @@ blockchainTests.resets('Exchange transactions', env => { ...constants.STATIC_ORDER_PARAMS, makerAddress, feeRecipientAddress, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerTokenAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerTokenAddress), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerFeeTokenAddress), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerFeeTokenAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultMakerTokenAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerTokenAddress), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultMakerFeeTokenAddress), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerFeeTokenAddress), exchangeAddress: exchangeInstance.address, chainId, }; diff --git a/contracts/exchange/test/utils/asset_wrapper.ts b/contracts/exchange/test/utils/asset_wrapper.ts index 9c560dc6c7..fe1ffd8739 100644 --- a/contracts/exchange/test/utils/asset_wrapper.ts +++ b/contracts/exchange/test/utils/asset_wrapper.ts @@ -1,10 +1,10 @@ import { AbstractAssetWrapper, constants } from '@0x/contracts-test-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId } from '@0x/types'; import { BigNumber, errorUtils } from '@0x/utils'; import * as _ from 'lodash'; import { ERC1155ProxyWrapper, ERC20Wrapper, ERC721Wrapper } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; interface ProxyIdToAssetWrappers { [proxyId: string]: AbstractAssetWrapper; @@ -19,17 +19,20 @@ const ZERO_NFT_UNIT = new BigNumber(0); */ export class AssetWrapper { private readonly _proxyIdToAssetWrappers: ProxyIdToAssetWrappers; - private readonly _burnerAddress: string; - constructor(assetWrappers: AbstractAssetWrapper[], burnerAddress: string) { + + constructor( + assetWrappers: AbstractAssetWrapper[], + private readonly _burnerAddress: string, + private readonly _devUtils: DevUtilsContract, + ) { this._proxyIdToAssetWrappers = {}; - this._burnerAddress = burnerAddress; _.each(assetWrappers, assetWrapper => { const proxyId = assetWrapper.getProxyId(); this._proxyIdToAssetWrappers[proxyId] = assetWrapper; }); } public async getBalanceAsync(userAddress: string, assetData: string): Promise { - const proxyId = assetDataUtils.decodeAssetProxyId(assetData); + const proxyId = await this._devUtils.decodeAssetProxyId.callAsync(assetData); switch (proxyId) { case AssetProxyId.ERC20: { // tslint:disable-next-line:no-unnecessary-type-assertion @@ -40,33 +43,38 @@ export class AssetWrapper { case AssetProxyId.ERC721: { // tslint:disable-next-line:no-unnecessary-type-assertion const assetWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper; - const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData); - const isOwner = await assetWrapper.isOwnerAsync( - userAddress, - assetProxyData.tokenAddress, - assetProxyData.tokenId, + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, tokenAddress, tokenId] = await this._devUtils.decodeERC721AssetData.callAsync( + assetData, ); + const isOwner = await assetWrapper.isOwnerAsync(userAddress, tokenAddress, tokenId); const balance = isOwner ? ONE_NFT_UNIT : ZERO_NFT_UNIT; return balance; } case AssetProxyId.ERC1155: { // tslint:disable-next-line:no-unnecessary-type-assertion const assetProxyWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC1155ProxyWrapper; - const assetProxyData = assetDataUtils.decodeERC1155AssetData(assetData); - const assetWrapper = assetProxyWrapper.getContractWrapper(assetProxyData.tokenAddress); + const [ + // tslint:disable-next-line:no-unused-variable + assetProxyAddress, + tokenAddress, + tokenIds, + ] = await this._devUtils.decodeERC1155AssetData.callAsync(assetData); + const assetWrapper = assetProxyWrapper.getContractWrapper(tokenAddress); const balances = await Promise.all( - _.map(assetProxyData.tokenIds).map(tokenId => assetWrapper.getBalanceAsync(userAddress, tokenId)), + _.map(tokenIds).map(tokenId => assetWrapper.getBalanceAsync(userAddress, tokenId)), ); return BigNumber.min(...balances); } case AssetProxyId.MultiAsset: { - const assetProxyData = assetDataUtils.decodeMultiAssetData(assetData); - const nestedBalances = await Promise.all( - assetProxyData.nestedAssetData.map(async nestedAssetData => - this.getBalanceAsync(userAddress, nestedAssetData), - ), + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, amounts, nestedAssetData] = await this._devUtils.decodeMultiAssetData.callAsync( + assetData, ); - const scaledBalances = _.zip(assetProxyData.amounts, nestedBalances).map(([amount, balance]) => + const nestedBalances = await Promise.all( + nestedAssetData.map(async _nestedAssetData => this.getBalanceAsync(userAddress, _nestedAssetData)), + ); + const scaledBalances = _.zip(amounts, nestedBalances).map(([amount, balance]) => (balance as BigNumber).div(amount as BigNumber).integerValue(BigNumber.ROUND_HALF_UP), ); return BigNumber.min(...scaledBalances); @@ -76,7 +84,7 @@ export class AssetWrapper { } } public async setBalanceAsync(userAddress: string, assetData: string, desiredBalance: BigNumber): Promise { - const proxyId = assetDataUtils.decodeAssetProxyId(assetData); + const proxyId = await this._devUtils.decodeAssetProxyId.callAsync(assetData); switch (proxyId) { case AssetProxyId.ERC20: { // tslint:disable-next-line:no-unnecessary-type-assertion @@ -91,36 +99,23 @@ export class AssetWrapper { case AssetProxyId.ERC721: { // tslint:disable-next-line:no-unnecessary-type-assertion const erc721Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper; - const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData); - const doesTokenExist = erc721Wrapper.doesTokenExistAsync( - assetProxyData.tokenAddress, - assetProxyData.tokenId, + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, tokenAddress, tokenId] = await this._devUtils.decodeERC721AssetData.callAsync( + assetData, ); + const doesTokenExist = erc721Wrapper.doesTokenExistAsync(tokenAddress, tokenId); if (!doesTokenExist && desiredBalance.gte(1)) { - await erc721Wrapper.mintAsync(assetProxyData.tokenAddress, assetProxyData.tokenId, userAddress); + await erc721Wrapper.mintAsync(tokenAddress, tokenId, userAddress); return; } else if (!doesTokenExist && desiredBalance.lt(1)) { return; // noop } - const tokenOwner = await erc721Wrapper.ownerOfAsync( - assetProxyData.tokenAddress, - assetProxyData.tokenId, - ); + const tokenOwner = await erc721Wrapper.ownerOfAsync(tokenAddress, tokenId); if (userAddress !== tokenOwner && desiredBalance.gte(1)) { - await erc721Wrapper.transferFromAsync( - assetProxyData.tokenAddress, - assetProxyData.tokenId, - tokenOwner, - userAddress, - ); + await erc721Wrapper.transferFromAsync(tokenAddress, tokenId, tokenOwner, userAddress); } else if (tokenOwner === userAddress && desiredBalance.lt(1)) { // Burn token - await erc721Wrapper.transferFromAsync( - assetProxyData.tokenAddress, - assetProxyData.tokenId, - tokenOwner, - this._burnerAddress, - ); + await erc721Wrapper.transferFromAsync(tokenAddress, tokenId, tokenOwner, this._burnerAddress); return; } else if ( (userAddress !== tokenOwner && desiredBalance.lt(1)) || @@ -133,15 +128,21 @@ export class AssetWrapper { case AssetProxyId.ERC1155: { // tslint:disable-next-line:no-unnecessary-type-assertion const assetProxyWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC1155ProxyWrapper; - const assetProxyData = assetDataUtils.decodeERC1155AssetData(assetData); - const assetWrapper = assetProxyWrapper.getContractWrapper(assetProxyData.tokenAddress); - const tokenValuesSum = BigNumber.sum(...assetProxyData.tokenValues); - let tokenValueRatios = assetProxyData.tokenValues; + const [ + // tslint:disable-next-line:no-unused-variable + assetProxyAddress, + tokenAddress, + tokenIds, + tokenValues, + ] = await this._devUtils.decodeERC1155AssetData.callAsync(assetData); + const assetWrapper = assetProxyWrapper.getContractWrapper(tokenAddress); + const tokenValuesSum = BigNumber.sum(...tokenValues); + let tokenValueRatios = tokenValues; if (!tokenValuesSum.eq(0)) { - tokenValueRatios = assetProxyData.tokenValues.map(v => v.div(tokenValuesSum)); + tokenValueRatios = tokenValues.map(v => v.div(tokenValuesSum)); } - for (const i of _.times(assetProxyData.tokenIds.length)) { - const tokenId = assetProxyData.tokenIds[i]; + for (const i of _.times(tokenIds.length)) { + const tokenId = tokenIds[i]; const tokenValueRatio = tokenValueRatios[i]; const scaledDesiredBalance = desiredBalance.times(tokenValueRatio); const isFungible = await assetWrapper.isFungibleItemAsync(tokenId); @@ -195,16 +196,18 @@ export class AssetWrapper { break; } case AssetProxyId.MultiAsset: { - const assetProxyData = assetDataUtils.decodeMultiAssetData(assetData); - const amountsSum = BigNumber.sum(...assetProxyData.amounts); - let assetAmountRatios = assetProxyData.amounts; + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, amounts, nestedAssetData] = await this._devUtils.decodeMultiAssetData.callAsync( + assetData, + ); + const amountsSum = BigNumber.sum(...amounts); + let assetAmountRatios = amounts; if (!amountsSum.eq(0)) { - assetAmountRatios = assetProxyData.amounts.map(amt => amt.div(amountsSum)); + assetAmountRatios = amounts.map(amt => amt.div(amountsSum)); } - for (const i of _.times(assetProxyData.amounts.length)) { - const nestedAssetData = assetProxyData.nestedAssetData[i]; + for (const i of _.times(amounts.length)) { const assetAmountRatio = assetAmountRatios[i]; - await this.setBalanceAsync(userAddress, nestedAssetData, desiredBalance.times(assetAmountRatio)); + await this.setBalanceAsync(userAddress, nestedAssetData[i], desiredBalance.times(assetAmountRatio)); } break; } @@ -217,7 +220,7 @@ export class AssetWrapper { assetData: string, desiredBalance: BigNumber, ): Promise { - const proxyId = assetDataUtils.decodeAssetProxyId(assetData); + const proxyId = await this._devUtils.decodeAssetProxyId.callAsync(assetData); switch (proxyId) { case AssetProxyId.ERC20: case AssetProxyId.ERC721: @@ -232,7 +235,7 @@ export class AssetWrapper { } } public async getProxyAllowanceAsync(userAddress: string, assetData: string): Promise { - const proxyId = assetDataUtils.decodeAssetProxyId(assetData); + const proxyId = await this._devUtils.decodeAssetProxyId.callAsync(assetData); switch (proxyId) { case AssetProxyId.ERC20: { // tslint:disable-next-line:no-unnecessary-type-assertion @@ -243,30 +246,27 @@ export class AssetWrapper { case AssetProxyId.ERC721: { // tslint:disable-next-line:no-unnecessary-type-assertion const assetWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper; - const erc721ProxyData = assetDataUtils.decodeERC721AssetData(assetData); - const isProxyApprovedForAll = await assetWrapper.isProxyApprovedForAllAsync( - userAddress, - erc721ProxyData.tokenAddress, + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, tokenAddress, tokenId] = await this._devUtils.decodeERC721AssetData.callAsync( + assetData, ); + const isProxyApprovedForAll = await assetWrapper.isProxyApprovedForAllAsync(userAddress, tokenAddress); if (isProxyApprovedForAll) { return constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; } - const isProxyApproved = await assetWrapper.isProxyApprovedAsync( - erc721ProxyData.tokenAddress, - erc721ProxyData.tokenId, - ); + const isProxyApproved = await assetWrapper.isProxyApprovedAsync(tokenAddress, tokenId); const allowance = isProxyApproved ? ONE_NFT_UNIT : ZERO_NFT_UNIT; return allowance; } case AssetProxyId.ERC1155: { // tslint:disable-next-line:no-unnecessary-type-assertion const assetProxyWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC1155ProxyWrapper; - const assetProxyData = assetDataUtils.decodeERC1155AssetData(assetData); - const isApprovedForAll = await assetProxyWrapper.isProxyApprovedForAllAsync( - userAddress, - assetProxyData.tokenAddress, + // tslint:disable-next-line:no-unused-variable + const [assetProxyAddress, tokenAddress] = await this._devUtils.decodeERC1155AssetData.callAsync( + assetData, ); + const isApprovedForAll = await assetProxyWrapper.isProxyApprovedForAllAsync(userAddress, tokenAddress); if (!isApprovedForAll) { // ERC1155 is all or nothing. return constants.ZERO_AMOUNT; @@ -274,10 +274,13 @@ export class AssetWrapper { return constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS; } case AssetProxyId.MultiAsset: { - const assetProxyData = assetDataUtils.decodeMultiAssetData(assetData); + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, amounts, nestedAssetData] = await this._devUtils.decodeMultiAssetData.callAsync( + assetData, + ); const allowances = await Promise.all( - assetProxyData.nestedAssetData.map(async nestedAssetData => - this.getProxyAllowanceAsync(userAddress, nestedAssetData), + nestedAssetData.map(async _nestedAssetData => + this.getProxyAllowanceAsync(userAddress, _nestedAssetData), ), ); return BigNumber.min(...allowances); @@ -291,7 +294,7 @@ export class AssetWrapper { assetData: string, desiredAllowance: BigNumber, ): Promise { - const proxyId = assetDataUtils.decodeAssetProxyId(assetData); + const proxyId = await this._devUtils.decodeAssetProxyId.callAsync(assetData); switch (proxyId) { case AssetProxyId.ERC20: { // tslint:disable-next-line:no-unnecessary-type-assertion @@ -311,46 +314,32 @@ export class AssetWrapper { } // tslint:disable-next-line:no-unnecessary-type-assertion const erc721Wrapper = this._proxyIdToAssetWrappers[proxyId] as ERC721Wrapper; - const assetProxyData = assetDataUtils.decodeERC721AssetData(assetData); + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, tokenAddress, tokenId] = await this._devUtils.decodeERC721AssetData.callAsync( + assetData, + ); - const doesTokenExist = await erc721Wrapper.doesTokenExistAsync( - assetProxyData.tokenAddress, - assetProxyData.tokenId, - ); + const doesTokenExist = await erc721Wrapper.doesTokenExistAsync(tokenAddress, tokenId); if (!doesTokenExist) { - throw new Error( - `Cannot setProxyAllowance on non-existent token: ${assetProxyData.tokenAddress} ${ - assetProxyData.tokenId - }`, - ); + throw new Error(`Cannot setProxyAllowance on non-existent token: ${tokenAddress} ${tokenId}`); } - const isProxyApprovedForAll = await erc721Wrapper.isProxyApprovedForAllAsync( - userAddress, - assetProxyData.tokenAddress, - ); + const isProxyApprovedForAll = await erc721Wrapper.isProxyApprovedForAllAsync(userAddress, tokenAddress); if (!isProxyApprovedForAll && desiredAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) { const isApproved = true; - await erc721Wrapper.approveProxyForAllAsync(assetProxyData.tokenAddress, userAddress, isApproved); + await erc721Wrapper.approveProxyForAllAsync(tokenAddress, userAddress, isApproved); } else if (isProxyApprovedForAll && desiredAllowance.eq(0)) { const isApproved = false; - await erc721Wrapper.approveProxyForAllAsync(assetProxyData.tokenAddress, userAddress, isApproved); + await erc721Wrapper.approveProxyForAllAsync(tokenAddress, userAddress, isApproved); } else if (isProxyApprovedForAll && desiredAllowance.eq(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS)) { return; // Noop } - const isProxyApproved = await erc721Wrapper.isProxyApprovedAsync( - assetProxyData.tokenAddress, - assetProxyData.tokenId, - ); + const isProxyApproved = await erc721Wrapper.isProxyApprovedAsync(tokenAddress, tokenId); if (!isProxyApproved && desiredAllowance.eq(1)) { - await erc721Wrapper.approveProxyAsync(assetProxyData.tokenAddress, assetProxyData.tokenId); + await erc721Wrapper.approveProxyAsync(tokenAddress, tokenId); } else if (isProxyApproved && desiredAllowance.eq(0)) { // Remove approval - await erc721Wrapper.approveAsync( - constants.NULL_ADDRESS, - assetProxyData.tokenAddress, - assetProxyData.tokenId, - ); + await erc721Wrapper.approveAsync(constants.NULL_ADDRESS, tokenAddress, tokenId); } else if ( (!isProxyApproved && desiredAllowance.eq(0)) || (isProxyApproved && desiredAllowance.eq(1)) @@ -362,7 +351,10 @@ export class AssetWrapper { case AssetProxyId.ERC1155: { // tslint:disable-next-line:no-unnecessary-type-assertion const assetProxyWrapper = this._proxyIdToAssetWrappers[proxyId] as ERC1155ProxyWrapper; - const assetProxyData = assetDataUtils.decodeERC1155AssetData(assetData); + // tslint:disable-next-line:no-unused-variable + const [assetProxyAddress, tokenAddress] = await this._devUtils.decodeERC1155AssetData.callAsync( + assetData, + ); // ERC1155 allowances are all or nothing. const shouldApprovedForAll = desiredAllowance.gt(0); const currentAllowance = await this.getProxyAllowanceAsync(userAddress, assetData); @@ -371,19 +363,18 @@ export class AssetWrapper { } else if (!shouldApprovedForAll && currentAllowance.eq(constants.ZERO_AMOUNT)) { // Nothing to do. } else { - assetProxyWrapper.setProxyAllowanceForAllAsync( - userAddress, - assetProxyData.tokenAddress, - shouldApprovedForAll, - ); + assetProxyWrapper.setProxyAllowanceForAllAsync(userAddress, tokenAddress, shouldApprovedForAll); } break; } case AssetProxyId.MultiAsset: { - const assetProxyData = assetDataUtils.decodeMultiAssetData(assetData); + // tslint:disable-next-line:no-unused-variable + const [assetProxyId, amounts, nestedAssetData] = await this._devUtils.decodeMultiAssetData.callAsync( + assetData, + ); await Promise.all( - assetProxyData.nestedAssetData.map(async nestedAssetData => - this.setProxyAllowanceAsync(userAddress, nestedAssetData, desiredAllowance), + nestedAssetData.map(async _nestedAssetData => + this.setProxyAllowanceAsync(userAddress, _nestedAssetData, desiredAllowance), ), ); break; diff --git a/contracts/exchange/test/utils/fill_order_combinatorial_utils.ts b/contracts/exchange/test/utils/fill_order_combinatorial_utils.ts index bee9116bc4..006088efea 100644 --- a/contracts/exchange/test/utils/fill_order_combinatorial_utils.ts +++ b/contracts/exchange/test/utils/fill_order_combinatorial_utils.ts @@ -5,6 +5,7 @@ import { ERC721Wrapper, MultiAssetProxyContract, } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { constants, expect, LogDecoder, orderUtils, signingUtils } from '@0x/contracts-test-utils'; import { BalanceAndProxyAllowanceLazyStore, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils'; import { FillResults, Order, SignatureType, SignedOrder } from '@0x/types'; @@ -106,7 +107,8 @@ export async function fillOrderCombinatorialUtilsFactoryAsync( {}, ); - const assetWrapper = new AssetWrapper([erc20Wrapper, erc721Wrapper, erc1155Wrapper], burnerAddress); + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); + const assetWrapper = new AssetWrapper([erc20Wrapper, erc721Wrapper, erc1155Wrapper], burnerAddress, devUtils); const exchangeContract = await ExchangeContract.deployFrom0xArtifactAsync( artifacts.Exchange, @@ -156,6 +158,7 @@ export async function fillOrderCombinatorialUtilsFactoryAsync( await multiAssetProxy.registerAssetProxy.awaitTransactionSuccessAsync(erc1155Proxy.address, { from: ownerAddress }); const orderFactory = new OrderFactoryFromScenario( + devUtils, userAddresses, erc20EighteenDecimalTokens.map(token => token.address), erc20FiveDecimalTokens.map(token => token.address), @@ -457,7 +460,7 @@ export class FillOrderCombinatorialUtils { fillErrorIfExists?: FillOrderError, ): Promise { const lazyStore = new BalanceAndProxyAllowanceLazyStore(this.balanceAndProxyAllowanceFetcher); - const signedOrder = await this._generateSignedOrder(fillScenario.orderScenario); + const signedOrder = await this._generateSignedOrderAsync(fillScenario.orderScenario); const takerAssetFillAmount = getTakerAssetFillAmount(signedOrder, fillScenario); await this._modifyTraderStateAsync(fillScenario, signedOrder, takerAssetFillAmount); @@ -484,8 +487,8 @@ export class FillOrderCombinatorialUtils { ); } - private _generateSignedOrder(orderScenario: OrderScenario): SignedOrder { - const order = this.orderFactory.generateOrder(orderScenario); + private async _generateSignedOrderAsync(orderScenario: OrderScenario): Promise { + const order = await this.orderFactory.generateOrderAsync(orderScenario); const orderHashBuff = orderHashUtils.getOrderHashBuffer(order); const signature = signingUtils.signMessage(orderHashBuff, this.makerPrivateKey, SignatureType.EthSign); const signedOrder = { diff --git a/contracts/exchange/test/utils/match_order_tester.ts b/contracts/exchange/test/utils/match_order_tester.ts index 1aa156ccb5..3fe9ff906a 100644 --- a/contracts/exchange/test/utils/match_order_tester.ts +++ b/contracts/exchange/test/utils/match_order_tester.ts @@ -1,6 +1,7 @@ import { ERC1155ProxyWrapper, ERC20Wrapper, ERC721Wrapper } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { constants, ERC1155HoldingsByOwner, expect, OrderStatus } from '@0x/contracts-test-utils'; -import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { orderHashUtils } from '@0x/order-utils'; import { AssetProxyId, BatchMatchedFillResults, FillResults, MatchedFillResults, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { LogWithDecodedArgs, TransactionReceiptWithDecodedLogs } from 'ethereum-types'; @@ -111,14 +112,6 @@ export type MatchOrdersAsyncCall = ( ) => Promise; export class MatchOrderTester { - public exchangeWrapper: ExchangeWrapper; - public erc20Wrapper: ERC20Wrapper; - public erc721Wrapper: ERC721Wrapper; - public erc1155ProxyWrapper: ERC1155ProxyWrapper; - public batchMatchOrdersCallAsync?: BatchMatchOrdersAsyncCall; - public batchMatchOrdersWithMaximalFillCallAsync?: BatchMatchOrdersAsyncCall; - public matchOrdersCallAsync?: MatchOrdersAsyncCall; - public matchOrdersWithMaximalFillCallAsync?: MatchOrdersAsyncCall; private readonly _initialTokenBalancesPromise: Promise; /** @@ -137,23 +130,16 @@ export class MatchOrderTester { * `ExchangeWrapper.matchOrdersAsync()`. */ constructor( - exchangeWrapper: ExchangeWrapper, - erc20Wrapper: ERC20Wrapper, - erc721Wrapper: ERC721Wrapper, - erc1155ProxyWrapper: ERC1155ProxyWrapper, - batchMatchOrdersCallAsync?: BatchMatchOrdersAsyncCall, - batchMatchOrdersWithMaximalFillCallAsync?: BatchMatchOrdersAsyncCall, - matchOrdersCallAsync?: MatchOrdersAsyncCall, - matchOrdersWithMaximalFillCallAsync?: MatchOrdersAsyncCall, + public exchangeWrapper: ExchangeWrapper, + public erc20Wrapper: ERC20Wrapper, + public erc721Wrapper: ERC721Wrapper, + public erc1155ProxyWrapper: ERC1155ProxyWrapper, + protected _devUtils: DevUtilsContract, + public batchMatchOrdersCallAsync?: BatchMatchOrdersAsyncCall, + public batchMatchOrdersWithMaximalFillCallAsync?: BatchMatchOrdersAsyncCall, + public matchOrdersCallAsync?: MatchOrdersAsyncCall, + public matchOrdersWithMaximalFillCallAsync?: MatchOrdersAsyncCall, ) { - this.exchangeWrapper = exchangeWrapper; - this.erc20Wrapper = erc20Wrapper; - this.erc721Wrapper = erc721Wrapper; - this.erc1155ProxyWrapper = erc1155ProxyWrapper; - this.batchMatchOrdersCallAsync = batchMatchOrdersCallAsync; - this.batchMatchOrdersWithMaximalFillCallAsync = batchMatchOrdersWithMaximalFillCallAsync; - this.matchOrdersCallAsync = matchOrdersCallAsync; - this.matchOrdersWithMaximalFillCallAsync = matchOrdersWithMaximalFillCallAsync; this._initialTokenBalancesPromise = this.getBalancesAsync(); } @@ -215,12 +201,13 @@ export class MatchOrderTester { ); } // Simulate the batch order match. - const expectedBatchMatchResults = simulateBatchMatchOrders( + const expectedBatchMatchResults = await simulateBatchMatchOrdersAsync( orders, takerAddress, _initialTokenBalances, matchPairs, expectedTransferAmounts, + this._devUtils, ); const expectedResults = convertToBatchMatchResults(expectedBatchMatchResults); expect(actualBatchMatchResults).to.be.eql(expectedResults); @@ -282,11 +269,12 @@ export class MatchOrderTester { transactionReceipt = await this._executeMatchOrdersAsync(orders.leftOrder, orders.rightOrder, takerAddress); } // Simulate the fill. - const expectedMatchResults = simulateMatchOrders( + const expectedMatchResults = await simulateMatchOrdersAsync( orders, takerAddress, _initialTokenBalances, toFullMatchTransferAmounts(expectedTransferAmounts), + this._devUtils, ); const expectedResults = convertToMatchResults(expectedMatchResults); expect(actualMatchResults).to.be.eql(expectedResults); @@ -403,13 +391,14 @@ function toFullMatchTransferAmounts(partial: Partial): Mat * @param transferAmounts Amounts to transfer during the simulation. * @return The new account balances and fill events that occurred during the match. */ -function simulateBatchMatchOrders( +async function simulateBatchMatchOrdersAsync( orders: BatchMatchedOrders, takerAddress: string, tokenBalances: TokenBalances, matchPairs: Array<[number, number]>, transferAmounts: Array>, -): BatchMatchResults { + devUtils: DevUtilsContract, +): Promise { // Initialize variables let leftIdx = 0; let rightIdx = 0; @@ -465,11 +454,12 @@ function simulateBatchMatchOrders( // Add the latest match to the batch match results batchMatchResults.matches.push( - simulateMatchOrders( + await simulateMatchOrdersAsync( matchedOrders, takerAddress, tokenBalances, toFullMatchTransferAmounts(transferAmounts[i]), + devUtils, ), ); @@ -525,12 +515,13 @@ function simulateBatchMatchOrders( * @param transferAmounts Amounts to transfer during the simulation. * @return The new account balances and fill events that occurred during the match. */ -function simulateMatchOrders( +async function simulateMatchOrdersAsync( orders: MatchedOrders, takerAddress: string, tokenBalances: TokenBalances, transferAmounts: MatchTransferAmounts, -): MatchResults { + devUtils: DevUtilsContract, +): Promise { // prettier-ignore const matchResults = { orders: { @@ -549,72 +540,80 @@ function simulateMatchOrders( balances: _.cloneDeep(tokenBalances), }; // Right maker asset -> left maker - transferAsset( + await transferAssetAsync( orders.rightOrder.makerAddress, orders.leftOrder.makerAddress, transferAmounts.rightMakerAssetBoughtByLeftMakerAmount, orders.rightOrder.makerAssetData, matchResults, + devUtils, ); if (orders.leftOrder.makerAddress !== orders.leftOrder.feeRecipientAddress) { // Left maker fees - transferAsset( + await transferAssetAsync( orders.leftOrder.makerAddress, orders.leftOrder.feeRecipientAddress, transferAmounts.leftMakerFeeAssetPaidByLeftMakerAmount, orders.leftOrder.makerFeeAssetData, matchResults, + devUtils, ); } // Left maker asset -> right maker - transferAsset( + await transferAssetAsync( orders.leftOrder.makerAddress, orders.rightOrder.makerAddress, transferAmounts.leftMakerAssetBoughtByRightMakerAmount, orders.leftOrder.makerAssetData, matchResults, + devUtils, ); if (orders.rightOrder.makerAddress !== orders.rightOrder.feeRecipientAddress) { // Right maker fees - transferAsset( + await transferAssetAsync( orders.rightOrder.makerAddress, orders.rightOrder.feeRecipientAddress, transferAmounts.rightMakerFeeAssetPaidByRightMakerAmount, orders.rightOrder.makerFeeAssetData, matchResults, + devUtils, ); } // Left taker profit - transferAsset( + await transferAssetAsync( orders.leftOrder.makerAddress, takerAddress, transferAmounts.leftMakerAssetReceivedByTakerAmount, orders.leftOrder.makerAssetData, matchResults, + devUtils, ); // Right taker profit - transferAsset( + await transferAssetAsync( orders.rightOrder.makerAddress, takerAddress, transferAmounts.rightMakerAssetReceivedByTakerAmount, orders.rightOrder.makerAssetData, matchResults, + devUtils, ); // Left taker fees - transferAsset( + await transferAssetAsync( takerAddress, orders.leftOrder.feeRecipientAddress, transferAmounts.leftTakerFeeAssetPaidByTakerAmount, orders.leftOrder.takerFeeAssetData, matchResults, + devUtils, ); // Right taker fees - transferAsset( + await transferAssetAsync( takerAddress, orders.rightOrder.feeRecipientAddress, transferAmounts.rightTakerFeeAssetPaidByTakerAmount, orders.rightOrder.takerFeeAssetData, matchResults, + devUtils, ); return matchResults; @@ -624,18 +623,19 @@ function simulateMatchOrders( * Simulates a transfer of assets from `fromAddress` to `toAddress` * by updating `matchResults`. */ -function transferAsset( +async function transferAssetAsync( fromAddress: string, toAddress: string, amount: BigNumber, assetData: string, matchResults: MatchResults, -): void { - const assetProxyId = assetDataUtils.decodeAssetProxyId(assetData); + devUtils: DevUtilsContract, +): Promise { + const assetProxyId = await devUtils.decodeAssetProxyId.callAsync(assetData); switch (assetProxyId) { case AssetProxyId.ERC20: { - const erc20AssetData = assetDataUtils.decodeERC20AssetData(assetData); - const assetAddress = erc20AssetData.tokenAddress; + // tslint:disable-next-line:no-unused-variable + const [proxyId, assetAddress] = await devUtils.decodeERC20AssetData.callAsync(assetData); // tslint:disable-line-no-unused-variable const fromBalances = matchResults.balances.erc20[fromAddress]; const toBalances = matchResults.balances.erc20[toAddress]; fromBalances[assetAddress] = fromBalances[assetAddress].minus(amount); @@ -643,9 +643,8 @@ function transferAsset( break; } case AssetProxyId.ERC721: { - const erc721AssetData = assetDataUtils.decodeERC721AssetData(assetData); - const assetAddress = erc721AssetData.tokenAddress; - const tokenId = erc721AssetData.tokenId; + // tslint:disable-next-line:no-unused-variable + const [proxyId, assetAddress, tokenId] = await devUtils.decodeERC721AssetData.callAsync(assetData); // tslint:disable-line-no-unused-variable const fromTokens = matchResults.balances.erc721[fromAddress][assetAddress]; const toTokens = matchResults.balances.erc721[toAddress][assetAddress]; if (amount.gte(1)) { @@ -658,13 +657,15 @@ function transferAsset( break; } case AssetProxyId.ERC1155: { - const erc1155AssetData = assetDataUtils.decodeERC1155AssetData(assetData); - const assetAddress = erc1155AssetData.tokenAddress; + // tslint:disable-next-line:no-unused-variable + const [proxyId, assetAddress, tokenIds, tokenValues] = await devUtils.decodeERC1155AssetData.callAsync( + assetData, + ); const fromBalances = matchResults.balances.erc1155[fromAddress][assetAddress]; const toBalances = matchResults.balances.erc1155[toAddress][assetAddress]; - for (const i of _.times(erc1155AssetData.tokenIds.length)) { - const tokenId = erc1155AssetData.tokenIds[i]; - const tokenValue = erc1155AssetData.tokenValues[i]; + for (const i of _.times(tokenIds.length)) { + const tokenId = tokenIds[i]; + const tokenValue = tokenValues[i]; const tokenAmount = amount.times(tokenValue); if (tokenAmount.gt(0)) { const tokenIndex = _.findIndex(fromBalances.nonFungible, t => t.eq(tokenId)); @@ -683,11 +684,19 @@ function transferAsset( break; } case AssetProxyId.MultiAsset: { - const multiAssetData = assetDataUtils.decodeMultiAssetData(assetData); - for (const i of _.times(multiAssetData.amounts.length)) { - const nestedAmount = amount.times(multiAssetData.amounts[i]); - const nestedAssetData = multiAssetData.nestedAssetData[i]; - transferAsset(fromAddress, toAddress, nestedAmount, nestedAssetData, matchResults); + // tslint:disable-next-line:no-unused-variable + const [proxyId, amounts, nestedAssetData] = await devUtils.decodeMultiAssetData.callAsync(assetData); // tslint:disable-line-no-unused-variable + for (const i of _.times(amounts.length)) { + const nestedAmount = amount.times(amounts[i]); + const _nestedAssetData = nestedAssetData[i]; + await transferAssetAsync( + fromAddress, + toAddress, + nestedAmount, + _nestedAssetData, + matchResults, + devUtils, + ); } break; } diff --git a/contracts/exchange/test/utils/order_factory_from_scenario.ts b/contracts/exchange/test/utils/order_factory_from_scenario.ts index a5fedd7575..b25a5a85ab 100644 --- a/contracts/exchange/test/utils/order_factory_from_scenario.ts +++ b/contracts/exchange/test/utils/order_factory_from_scenario.ts @@ -1,5 +1,6 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { constants, ERC1155HoldingsByOwner, ERC721TokenIdsByOwner } from '@0x/contracts-test-utils'; -import { assetDataUtils, generatePseudoRandomSalt } from '@0x/order-utils'; +import { generatePseudoRandomSalt } from '@0x/order-utils'; import { Order } from '@0x/types'; import { BigNumber, errorUtils } from '@0x/utils'; import * as _ from 'lodash'; @@ -32,40 +33,22 @@ const ONE_NFT_UNIT = new BigNumber(1); const ZERO_UNITS = new BigNumber(0); export class OrderFactoryFromScenario { - private readonly _userAddresses: string[]; - private readonly _erc20EighteenDecimalTokenAddresses: string[]; - private readonly _erc20FiveDecimalTokenAddresses: string[]; - private readonly _erc20ZeroDecimalTokenAddresses: string[]; - private readonly _erc721TokenAddress: string; - private readonly _erc1155TokenAddress: string; - private readonly _erc721Balances: ERC721TokenIdsByOwner; - private readonly _erc1155Holdings: ERC1155HoldingsByOwner; - private readonly _exchangeAddress: string; - private readonly _chainId: number; constructor( - userAddresses: string[], - erc20EighteenDecimalTokenAddresses: string[], - erc20FiveDecimalTokenAddresses: string[], - erc20ZeroDecimalTokenAddresses: string[], - erc721TokenAddress: string, - erc1155TokenAddress: string, - erc721Balances: ERC721TokenIdsByOwner, - erc1155Holdings: ERC1155HoldingsByOwner, - exchangeAddress: string, - chainId: number, + private readonly _devUtils: DevUtilsContract, + private readonly _userAddresses: string[], + private readonly _erc20EighteenDecimalTokenAddresses: string[], + private readonly _erc20FiveDecimalTokenAddresses: string[], + private readonly _erc20ZeroDecimalTokenAddresses: string[], + private readonly _erc721TokenAddress: string, + private readonly _erc1155TokenAddress: string, + private readonly _erc721Balances: ERC721TokenIdsByOwner, + private readonly _erc1155Holdings: ERC1155HoldingsByOwner, + private readonly _exchangeAddress: string, + private readonly _chainId: number, ) { - this._userAddresses = userAddresses; - this._erc20EighteenDecimalTokenAddresses = erc20EighteenDecimalTokenAddresses; - this._erc20FiveDecimalTokenAddresses = erc20FiveDecimalTokenAddresses; - this._erc20ZeroDecimalTokenAddresses = erc20ZeroDecimalTokenAddresses; - this._erc721TokenAddress = erc721TokenAddress; - this._erc1155TokenAddress = erc1155TokenAddress; - this._erc721Balances = erc721Balances; - this._erc1155Holdings = erc1155Holdings; - this._exchangeAddress = exchangeAddress; - this._chainId = chainId; + return; } - public generateOrder(orderScenario: OrderScenario): Order { + public async generateOrderAsync(orderScenario: OrderScenario): Promise { const makerAddress = this._userAddresses[1]; let takerAddress = this._userAddresses[2]; const erc721MakerAssetIds = this._erc721Balances[makerAddress][this._erc721TokenAddress]; @@ -113,19 +96,28 @@ export class OrderFactoryFromScenario { switch (orderScenario.makerAssetDataScenario) { case AssetDataScenario.ERC20EighteenDecimals: - makerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20EighteenDecimalTokenAddresses[0]); + makerAssetData = await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20EighteenDecimalTokenAddresses[0], + ); break; case AssetDataScenario.ERC20FiveDecimals: - makerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20FiveDecimalTokenAddresses[0]); + makerAssetData = await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20FiveDecimalTokenAddresses[0], + ); break; case AssetDataScenario.ERC721: - makerAssetData = assetDataUtils.encodeERC721AssetData(this._erc721TokenAddress, erc721MakerAssetIds[0]); + makerAssetData = await this._devUtils.encodeERC721AssetData.callAsync( + this._erc721TokenAddress, + erc721MakerAssetIds[0], + ); break; case AssetDataScenario.ERC20ZeroDecimals: - makerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20ZeroDecimalTokenAddresses[0]); + makerAssetData = await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20ZeroDecimalTokenAddresses[0], + ); break; case AssetDataScenario.ERC1155Fungible: - makerAssetData = assetDataUtils.encodeERC1155AssetData( + makerAssetData = await this._devUtils.encodeERC1155AssetData.callAsync( this._erc1155TokenAddress, [erc1155FungibleMakerTokenIds[0]], [ONE_UNITS_ZERO_DECIMALS], @@ -133,7 +125,7 @@ export class OrderFactoryFromScenario { ); break; case AssetDataScenario.ERC1155NonFungible: - makerAssetData = assetDataUtils.encodeERC1155AssetData( + makerAssetData = await this._devUtils.encodeERC1155AssetData.callAsync( this._erc1155TokenAddress, [erc1155NonFungibleMakerTokenIds[0]], [ONE_UNITS_ZERO_DECIMALS], @@ -141,11 +133,13 @@ export class OrderFactoryFromScenario { ); break; case AssetDataScenario.MultiAssetERC20: - makerAssetData = assetDataUtils.encodeMultiAssetData( + makerAssetData = await this._devUtils.encodeMultiAssetData.callAsync( [ONE_UNITS_EIGHTEEN_DECIMALS, ONE_UNITS_FIVE_DECIMALS], [ - assetDataUtils.encodeERC20AssetData(this._erc20EighteenDecimalTokenAddresses[0]), - assetDataUtils.encodeERC20AssetData(this._erc20FiveDecimalTokenAddresses[0]), + await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20EighteenDecimalTokenAddresses[0], + ), + await this._devUtils.encodeERC20AssetData.callAsync(this._erc20FiveDecimalTokenAddresses[0]), ], ); break; @@ -155,19 +149,28 @@ export class OrderFactoryFromScenario { switch (orderScenario.takerAssetDataScenario) { case AssetDataScenario.ERC20EighteenDecimals: - takerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20EighteenDecimalTokenAddresses[1]); + takerAssetData = await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20EighteenDecimalTokenAddresses[1], + ); break; case AssetDataScenario.ERC20FiveDecimals: - takerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20FiveDecimalTokenAddresses[1]); + takerAssetData = await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20FiveDecimalTokenAddresses[1], + ); break; case AssetDataScenario.ERC721: - takerAssetData = assetDataUtils.encodeERC721AssetData(this._erc721TokenAddress, erc721TakerAssetIds[0]); + takerAssetData = await this._devUtils.encodeERC721AssetData.callAsync( + this._erc721TokenAddress, + erc721TakerAssetIds[0], + ); break; case AssetDataScenario.ERC20ZeroDecimals: - takerAssetData = assetDataUtils.encodeERC20AssetData(this._erc20ZeroDecimalTokenAddresses[1]); + takerAssetData = await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20ZeroDecimalTokenAddresses[1], + ); break; case AssetDataScenario.ERC1155Fungible: - takerAssetData = assetDataUtils.encodeERC1155AssetData( + takerAssetData = await this._devUtils.encodeERC1155AssetData.callAsync( this._erc1155TokenAddress, [erc1155FungibleTakerTokenIds[1]], [ONE_UNITS_ZERO_DECIMALS], @@ -175,7 +178,7 @@ export class OrderFactoryFromScenario { ); break; case AssetDataScenario.ERC1155NonFungible: - takerAssetData = assetDataUtils.encodeERC1155AssetData( + takerAssetData = await this._devUtils.encodeERC1155AssetData.callAsync( this._erc1155TokenAddress, [erc1155NonFungibleTakerTokenIds[0]], [ONE_UNITS_ZERO_DECIMALS], @@ -183,11 +186,13 @@ export class OrderFactoryFromScenario { ); break; case AssetDataScenario.MultiAssetERC20: - takerAssetData = assetDataUtils.encodeMultiAssetData( + takerAssetData = await this._devUtils.encodeMultiAssetData.callAsync( [ONE_UNITS_EIGHTEEN_DECIMALS, ONE_UNITS_FIVE_DECIMALS], [ - assetDataUtils.encodeERC20AssetData(this._erc20EighteenDecimalTokenAddresses[1]), - assetDataUtils.encodeERC20AssetData(this._erc20FiveDecimalTokenAddresses[1]), + await this._devUtils.encodeERC20AssetData.callAsync( + this._erc20EighteenDecimalTokenAddresses[1], + ), + await this._devUtils.encodeERC20AssetData.callAsync(this._erc20FiveDecimalTokenAddresses[1]), ], ); break; @@ -303,7 +308,7 @@ export class OrderFactoryFromScenario { throw errorUtils.spawnSwitchErr('OrderAssetAmountScenario', orderScenario.takerAssetAmountScenario); } - const feeFromScenario = ( + const feeFromScenario = async ( feeAmountScenario: OrderAssetAmountScenario, feeAssetDataScenario: FeeAssetDataScenario, erc20EighteenDecimalTokenAddress: string, @@ -312,7 +317,7 @@ export class OrderFactoryFromScenario { erc721AssetId: BigNumber, erc1155FungibleTokenId: BigNumber, erc1155NonFungibleAssetId: BigNumber, - ): [BigNumber, string] => { + ): Promise<[BigNumber, string]> => { const feeAmount = getFeeAmountFromScenario(orderScenario, feeAssetDataScenario, feeAmountScenario); switch (feeAssetDataScenario) { case FeeAssetDataScenario.MakerToken: @@ -320,17 +325,29 @@ export class OrderFactoryFromScenario { case FeeAssetDataScenario.TakerToken: return [feeAmount, takerAssetData]; case FeeAssetDataScenario.ERC20EighteenDecimals: - return [feeAmount, assetDataUtils.encodeERC20AssetData(erc20EighteenDecimalTokenAddress)]; + return [ + feeAmount, + await this._devUtils.encodeERC20AssetData.callAsync(erc20EighteenDecimalTokenAddress), + ]; case FeeAssetDataScenario.ERC20FiveDecimals: - return [feeAmount, assetDataUtils.encodeERC20AssetData(erc20FiveDecimalTokenAddress)]; + return [ + feeAmount, + await this._devUtils.encodeERC20AssetData.callAsync(erc20FiveDecimalTokenAddress), + ]; case FeeAssetDataScenario.ERC20ZeroDecimals: - return [feeAmount, assetDataUtils.encodeERC20AssetData(erc20ZeroDecimalTokenAddress)]; + return [ + feeAmount, + await this._devUtils.encodeERC20AssetData.callAsync(erc20ZeroDecimalTokenAddress), + ]; case FeeAssetDataScenario.ERC721: - return [feeAmount, assetDataUtils.encodeERC721AssetData(this._erc721TokenAddress, erc721AssetId)]; + return [ + feeAmount, + await this._devUtils.encodeERC721AssetData.callAsync(this._erc721TokenAddress, erc721AssetId), + ]; case FeeAssetDataScenario.ERC1155Fungible: return [ feeAmount, - assetDataUtils.encodeERC1155AssetData( + await this._devUtils.encodeERC1155AssetData.callAsync( this._erc1155TokenAddress, [erc1155FungibleTokenId], [ONE_UNITS_ZERO_DECIMALS], @@ -340,7 +357,7 @@ export class OrderFactoryFromScenario { case FeeAssetDataScenario.ERC1155NonFungible: return [ feeAmount, - assetDataUtils.encodeERC1155AssetData( + await this._devUtils.encodeERC1155AssetData.callAsync( this._erc1155TokenAddress, [erc1155NonFungibleAssetId], [ONE_UNITS_ZERO_DECIMALS], @@ -350,11 +367,11 @@ export class OrderFactoryFromScenario { case FeeAssetDataScenario.MultiAssetERC20: return [ feeAmount, - assetDataUtils.encodeMultiAssetData( + await this._devUtils.encodeMultiAssetData.callAsync( [POINT_ZERO_FIVE_UNITS_EIGHTEEN_DECIMALS, POINT_ZERO_FIVE_UNITS_FIVE_DECIMALS], [ - assetDataUtils.encodeERC20AssetData(erc20EighteenDecimalTokenAddress), - assetDataUtils.encodeERC20AssetData(erc20FiveDecimalTokenAddress), + await this._devUtils.encodeERC20AssetData.callAsync(erc20EighteenDecimalTokenAddress), + await this._devUtils.encodeERC20AssetData.callAsync(erc20FiveDecimalTokenAddress), ], ), ]; @@ -363,7 +380,7 @@ export class OrderFactoryFromScenario { } }; - [makerFee, makerFeeAssetData] = feeFromScenario( + [makerFee, makerFeeAssetData] = await feeFromScenario( orderScenario.makerFeeScenario, orderScenario.makerFeeAssetDataScenario, this._erc20EighteenDecimalTokenAddresses[2], @@ -373,7 +390,7 @@ export class OrderFactoryFromScenario { erc1155FungibleMakerTokenIds[2], erc1155NonFungibleMakerTokenIds[1], ); - [takerFee, takerFeeAssetData] = feeFromScenario( + [takerFee, takerFeeAssetData] = await feeFromScenario( orderScenario.takerFeeScenario, orderScenario.takerFeeAssetDataScenario, this._erc20EighteenDecimalTokenAddresses[3], diff --git a/contracts/extensions/package.json b/contracts/extensions/package.json index 6d7716c0a3..1ce1634f70 100644 --- a/contracts/extensions/package.json +++ b/contracts/extensions/package.json @@ -73,6 +73,7 @@ "dependencies": { "@0x/base-contract": "^5.5.0-beta.0", "@0x/contracts-asset-proxy": "^2.3.0-beta.0", + "@0x/contracts-dev-utils": "^0.1.0-beta.0", "@0x/contracts-erc20": "^2.3.0-beta.0", "@0x/contracts-erc721": "^2.2.0-beta.0", "@0x/contracts-exchange": "^2.2.0-beta.0", diff --git a/contracts/extensions/test/balance_threshold_filter.ts b/contracts/extensions/test/balance_threshold_filter.ts index 1c5872fdaa..7fe4ee5566 100644 --- a/contracts/extensions/test/balance_threshold_filter.ts +++ b/contracts/extensions/test/balance_threshold_filter.ts @@ -1,6 +1,7 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { ExchangeContract, ExchangeWrapper } from '@0x/contracts-exchange'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils, ExchangeRevertErrors } from '@0x/order-utils'; +import { ExchangeRevertErrors } from '@0x/order-utils'; import { Order, RevertReason, SignedOrder } from '@0x/types'; import { BigNumber, providerUtils } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -52,6 +53,7 @@ describe(ContractName.BalanceThresholdFilter, () => { let zrxToken: DummyERC20TokenContract; let exchangeInstance: ExchangeContract; let exchangeWrapper: ExchangeWrapper; + let devUtils: DevUtilsContract; let orderFactory: OrderFactory; let orderFactory2: OrderFactory; @@ -105,6 +107,7 @@ describe(ContractName.BalanceThresholdFilter, () => { const makerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(validMakerAddress)]; const secondMakerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(validMakerAddress2)]; const invalidAddressPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(invalidAddress)]; + devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); // Create wrappers erc20Wrapper = new ERC20Wrapper(provider, usedAddresses, owner); const validAddresses = _.cloneDeepWith(usedAddresses); @@ -123,7 +126,7 @@ describe(ContractName.BalanceThresholdFilter, () => { ); defaultMakerAssetAddress = erc20TokenA.address; defaultTakerAssetAddress = erc20TokenB.address; - zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); + zrxAssetData = await devUtils.encodeERC20AssetData.callAsync(zrxToken.address); // Create proxies const erc20Proxy = await erc20Wrapper.deployProxyAsync(); await erc20Wrapper.setBalancesAndAllowancesAsync(); @@ -170,8 +173,8 @@ describe(ContractName.BalanceThresholdFilter, () => { // Default order parameters defaultOrderParams = { feeRecipientAddress, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerAssetAddress), makerAssetAmount, takerAssetAmount, makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(100), DECIMALS_DEFAULT), @@ -1236,8 +1239,8 @@ describe(ContractName.BalanceThresholdFilter, () => { feeRecipientAddress, }); const signedOrderRight = await orderFactory2.newSignedOrderAsync({ - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(75), 0), takerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(13), 0), makerFee: Web3Wrapper.toBaseUnitAmount(new BigNumber(1), 18), diff --git a/contracts/extensions/test/dutch_auction.ts b/contracts/extensions/test/dutch_auction.ts index e395bd21e2..c7cfab18ab 100644 --- a/contracts/extensions/test/dutch_auction.ts +++ b/contracts/extensions/test/dutch_auction.ts @@ -1,4 +1,5 @@ import { ERC20Wrapper, ERC721Wrapper } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { DummyERC721TokenContract } from '@0x/contracts-erc721'; import { ExchangeContract, ExchangeWrapper } from '@0x/contracts-exchange'; @@ -59,6 +60,8 @@ describe(ContractName.DutchAuction, () => { let dutchAuctionTestWrapper: DutchAuctionTestWrapper; let defaultERC20MakerAssetData: string; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); + before(async () => { await blockchainLifecycle.startAsync(); @@ -86,7 +89,7 @@ describe(ContractName.DutchAuction, () => { wethContract = await WETH9Contract.deployFrom0xArtifactAsync(artifacts.WETH9, provider, txDefaults, artifacts); erc20Wrapper.addDummyTokenContract(wethContract as any); - const zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxToken.address); + const zrxAssetData = await devUtils.encodeERC20AssetData.callAsync(zrxToken.address); const exchangeInstance = await ExchangeContract.deployFrom0xArtifactAsync( artifacts.Exchange, provider, @@ -153,11 +156,11 @@ describe(ContractName.DutchAuction, () => { // taker address or sender address should be set to the ducth auction contract takerAddress: dutchAuctionContract.address, makerAssetData: assetDataUtils.encodeDutchAuctionAssetData( - assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), + await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), auctionBeginTimeSeconds, auctionBeginAmount, ), - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultTakerAssetAddress), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultTakerAssetAddress), makerAssetAmount: Web3Wrapper.toBaseUnitAmount(new BigNumber(200), DECIMALS_DEFAULT), takerAssetAmount: auctionEndAmount, expirationTimeSeconds: auctionEndTimeSeconds, @@ -179,7 +182,7 @@ describe(ContractName.DutchAuction, () => { const takerPrivateKey = constants.TESTRPC_PRIVATE_KEYS[accounts.indexOf(takerAddress)]; sellerOrderFactory = new OrderFactory(makerPrivateKey, sellerDefaultOrderParams); buyerOrderFactory = new OrderFactory(takerPrivateKey, buyerDefaultOrderParams); - defaultERC20MakerAssetData = assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress); + defaultERC20MakerAssetData = await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress); }); after(async () => { await blockchainLifecycle.revertAsync(); @@ -318,7 +321,7 @@ describe(ContractName.DutchAuction, () => { }); it('asset data contains auction parameters', async () => { sellOrder = await sellerOrderFactory.newSignedOrderAsync({ - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultMakerAssetAddress), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(defaultMakerAssetAddress), }); const tx = dutchAuctionTestWrapper.matchOrdersAsync(buyOrder, sellOrder, takerAddress); return expect(tx).to.revertWith(RevertReason.InvalidAssetData); @@ -327,7 +330,10 @@ describe(ContractName.DutchAuction, () => { describe('ERC721', () => { it('should match orders when ERC721', async () => { const makerAssetId = erc721MakerAssetIds[0]; - const erc721MakerAssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, makerAssetId); + const erc721MakerAssetData = await devUtils.encodeERC721AssetData.callAsync( + erc721Token.address, + makerAssetId, + ); const makerAssetData = assetDataUtils.encodeDutchAuctionAssetData( erc721MakerAssetData, auctionBeginTimeSeconds, diff --git a/contracts/extensions/test/order_matcher.ts b/contracts/extensions/test/order_matcher.ts index 4b7359fb91..bd85592601 100644 --- a/contracts/extensions/test/order_matcher.ts +++ b/contracts/extensions/test/order_matcher.ts @@ -4,6 +4,7 @@ import { ERC20Wrapper, ERC721ProxyContract, } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/contracts-erc721'; import { ExchangeContract, ExchangeWrapper } from '@0x/contracts-exchange'; @@ -20,7 +21,7 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils, ExchangeRevertErrors } from '@0x/order-utils'; +import { ExchangeRevertErrors } from '@0x/order-utils'; import { RevertReason } from '@0x/types'; import { BigNumber, providerUtils } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; @@ -62,6 +63,7 @@ describe('OrderMatcher', () => { let defaultERC20MakerAssetAddress: string; let defaultERC20TakerAssetAddress: string; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider, txDefaults); before(async () => { await blockchainLifecycle.startAsync(); }); @@ -112,7 +114,7 @@ describe('OrderMatcher', () => { provider, txDefaults, artifacts, - assetDataUtils.encodeERC20AssetData(zrxToken.address), + await devUtils.encodeERC20AssetData.callAsync(zrxToken.address), new BigNumber(chainId), ); exchangeWrapper = new ExchangeWrapper(exchange); @@ -136,8 +138,8 @@ describe('OrderMatcher', () => { // Set default addresses defaultERC20MakerAssetAddress = erc20TokenA.address; defaultERC20TakerAssetAddress = erc20TokenB.address; - leftMakerAssetData = assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress); - leftTakerAssetData = assetDataUtils.encodeERC20AssetData(defaultERC20TakerAssetAddress); + leftMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(defaultERC20MakerAssetAddress); + leftTakerAssetData = await devUtils.encodeERC20AssetData.callAsync(defaultERC20TakerAssetAddress); // Set OrderMatcher balances and allowances await web3Wrapper.awaitTransactionSuccessAsync( await erc20TokenA.setBalance.sendTransactionAsync(orderMatcher.address, constants.INITIAL_ERC20_BALANCE, { @@ -743,7 +745,7 @@ describe('OrderMatcher', () => { await erc721Token.mint.sendTransactionAsync(orderMatcher.address, tokenId, { from: owner }), constants.AWAIT_TRANSACTION_MINED_MS, ); - const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId); + const assetData = await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, tokenId); const withdrawAmount = new BigNumber(1); await web3Wrapper.awaitTransactionSuccessAsync( await orderMatcher.withdrawAsset.sendTransactionAsync(assetData, withdrawAmount, { from: owner }), @@ -782,7 +784,10 @@ describe('OrderMatcher', () => { constants.DUMMY_TOKEN_NAME, constants.DUMMY_TOKEN_SYMBOL, ); - const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, constants.ZERO_AMOUNT); + const assetData = await devUtils.encodeERC721AssetData.callAsync( + erc721Token.address, + constants.ZERO_AMOUNT, + ); const allowance = new BigNumber(1); await web3Wrapper.awaitTransactionSuccessAsync( await orderMatcher.approveAssetProxy.sendTransactionAsync(assetData, allowance, { from: owner }), @@ -800,7 +805,10 @@ describe('OrderMatcher', () => { constants.DUMMY_TOKEN_NAME, constants.DUMMY_TOKEN_SYMBOL, ); - const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, constants.ZERO_AMOUNT); + const assetData = await devUtils.encodeERC721AssetData.callAsync( + erc721Token.address, + constants.ZERO_AMOUNT, + ); const allowance = new BigNumber(2); await web3Wrapper.awaitTransactionSuccessAsync( await orderMatcher.approveAssetProxy.sendTransactionAsync(assetData, allowance, { from: owner }), diff --git a/contracts/integrations/test/coordinator/coordinator_test.ts b/contracts/integrations/test/coordinator/coordinator_test.ts index 076066c332..d953739a3f 100644 --- a/contracts/integrations/test/coordinator/coordinator_test.ts +++ b/contracts/integrations/test/coordinator/coordinator_test.ts @@ -1,4 +1,5 @@ import { CoordinatorContract, SignedCoordinatorApproval } from '@0x/contracts-coordinator'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { BlockchainBalanceStore, constants as exchangeConstants, @@ -10,8 +11,16 @@ import { ExchangeFunctionName, LocalBalanceStore, } from '@0x/contracts-exchange'; -import { blockchainTests, constants, expect, hexConcat, hexSlice, verifyEvents } from '@0x/contracts-test-utils'; -import { assetDataUtils, CoordinatorRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils'; +import { + blockchainTests, + constants, + expect, + hexConcat, + hexSlice, + provider, + verifyEvents, +} from '@0x/contracts-test-utils'; +import { CoordinatorRevertErrors, orderHashUtils, transactionHashUtils } from '@0x/order-utils'; import { SignedOrder, SignedZeroExTransaction } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; @@ -26,6 +35,7 @@ blockchainTests.resets('Coordinator integration tests', env => { let deployment: DeploymentManager; let coordinator: CoordinatorContract; let balanceStore: BlockchainBalanceStore; + let devUtils: DevUtilsContract; let maker: Maker; let taker: Actor; @@ -38,6 +48,7 @@ blockchainTests.resets('Coordinator integration tests', env => { numErc1155TokensToDeploy: 0, }); coordinator = await deployCoordinatorAsync(deployment, env); + devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); const [makerToken, takerToken, makerFeeToken, takerFeeToken] = deployment.tokens.erc20; @@ -53,10 +64,10 @@ blockchainTests.resets('Coordinator integration tests', env => { orderConfig: { senderAddress: coordinator.address, feeRecipientAddress: feeRecipient.address, - makerAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address), - takerAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(makerFeeToken.address), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(takerFeeToken.address), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(makerToken.address), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(takerToken.address), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(makerFeeToken.address), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(takerFeeToken.address), }, }); @@ -77,30 +88,40 @@ blockchainTests.resets('Coordinator integration tests', env => { ); }); - function simulateFills( + async function simulateFillsAsync( orders: SignedOrder[], txReceipt: TransactionReceiptWithDecodedLogs, msgValue?: BigNumber, - ): LocalBalanceStore { + ): Promise { let remainingValue = msgValue || constants.ZERO_AMOUNT; - const localBalanceStore = LocalBalanceStore.create(balanceStore); + const localBalanceStore = LocalBalanceStore.create(devUtils, balanceStore); // Transaction gas cost localBalanceStore.burnGas(txReceipt.from, DeploymentManager.gasPrice.times(txReceipt.gasUsed)); for (const order of orders) { // Taker -> Maker - localBalanceStore.transferAsset(taker.address, maker.address, order.takerAssetAmount, order.takerAssetData); + await localBalanceStore.transferAssetAsync( + taker.address, + maker.address, + order.takerAssetAmount, + order.takerAssetData, + ); // Maker -> Taker - localBalanceStore.transferAsset(maker.address, taker.address, order.makerAssetAmount, order.makerAssetData); + await localBalanceStore.transferAssetAsync( + maker.address, + taker.address, + order.makerAssetAmount, + order.makerAssetData, + ); // Taker -> Fee Recipient - localBalanceStore.transferAsset( + await localBalanceStore.transferAssetAsync( taker.address, feeRecipient.address, order.takerFee, order.takerFeeAssetData, ); // Maker -> Fee Recipient - localBalanceStore.transferAsset( + await localBalanceStore.transferAssetAsync( maker.address, feeRecipient.address, order.makerFee, @@ -116,11 +137,11 @@ blockchainTests.resets('Coordinator integration tests', env => { ); remainingValue = remainingValue.minus(DeploymentManager.protocolFee); } else { - localBalanceStore.transferAsset( + await localBalanceStore.transferAssetAsync( taker.address, deployment.staking.stakingProxy.address, DeploymentManager.protocolFee, - assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address), + await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address), ); } } @@ -174,7 +195,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: taker.address, value: DeploymentManager.protocolFee }, ); - const expectedBalances = simulateFills([order], txReceipt, DeploymentManager.protocolFee); + const expectedBalances = await simulateFillsAsync([order], txReceipt, DeploymentManager.protocolFee); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill); @@ -189,7 +210,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: feeRecipient.address, value: DeploymentManager.protocolFee }, ); - const expectedBalances = simulateFills([order], txReceipt, DeploymentManager.protocolFee); + const expectedBalances = await simulateFillsAsync([order], txReceipt, DeploymentManager.protocolFee); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill); @@ -204,7 +225,11 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: feeRecipient.address, value: DeploymentManager.protocolFee.plus(1) }, ); - const expectedBalances = simulateFills([order], txReceipt, DeploymentManager.protocolFee.plus(1)); + const expectedBalances = await simulateFillsAsync( + [order], + txReceipt, + DeploymentManager.protocolFee.plus(1), + ); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill); @@ -219,7 +244,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: feeRecipient.address }, ); - const expectedBalances = simulateFills([order], txReceipt); + const expectedBalances = await simulateFillsAsync([order], txReceipt); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill); @@ -234,7 +259,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: feeRecipient.address, value: new BigNumber(1) }, ); - const expectedBalances = simulateFills([order], txReceipt, new BigNumber(1)); + const expectedBalances = await simulateFillsAsync([order], txReceipt, new BigNumber(1)); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, [expectedFillEvent(order)], ExchangeEvents.Fill); @@ -318,7 +343,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: taker.address, value }, ); - const expectedBalances = simulateFills(orders, txReceipt, value); + const expectedBalances = await simulateFillsAsync(orders, txReceipt, value); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); @@ -334,7 +359,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: feeRecipient.address, value }, ); - const expectedBalances = simulateFills(orders, txReceipt, value); + const expectedBalances = await simulateFillsAsync(orders, txReceipt, value); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); @@ -350,7 +375,7 @@ blockchainTests.resets('Coordinator integration tests', env => { { from: feeRecipient.address, value }, ); - const expectedBalances = simulateFills(orders, txReceipt, value); + const expectedBalances = await simulateFillsAsync(orders, txReceipt, value); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); verifyEvents(txReceipt, orders.map(order => expectedFillEvent(order)), ExchangeEvents.Fill); diff --git a/contracts/integrations/test/forwarder/forwarder_test.ts b/contracts/integrations/test/forwarder/forwarder_test.ts index 53937393df..f521b9e44c 100644 --- a/contracts/integrations/test/forwarder/forwarder_test.ts +++ b/contracts/integrations/test/forwarder/forwarder_test.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { DummyERC20TokenContract } from '@0x/contracts-erc20'; import { DummyERC721TokenContract } from '@0x/contracts-erc721'; import { @@ -13,9 +14,10 @@ import { expect, getLatestBlockTimestampAsync, getPercentageOfValue, + provider, toBaseUnitAmount, } from '@0x/contracts-test-utils'; -import { assetDataUtils, ForwarderRevertErrors } from '@0x/order-utils'; +import { ForwarderRevertErrors } from '@0x/order-utils'; import { BigNumber } from '@0x/utils'; import { Actor, actorAddressesByName, FeeRecipient, Maker } from '../actors'; @@ -24,6 +26,8 @@ import { DeploymentManager } from '../utils/deployment_manager'; import { deployForwarderAsync } from './deploy_forwarder'; import { ForwarderTestFactory } from './forwarder_test_factory'; +const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); + blockchainTests('Forwarder integration tests', env => { let deployment: DeploymentManager; let forwarder: ForwarderContract; @@ -53,8 +57,8 @@ blockchainTests('Forwarder integration tests', env => { [makerToken, makerFeeToken, anotherErc20Token] = deployment.tokens.erc20; [erc721Token] = deployment.tokens.erc721; - wethAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address); - makerAssetData = assetDataUtils.encodeERC20AssetData(makerToken.address); + wethAssetData = await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address); + makerAssetData = await devUtils.encodeERC20AssetData.callAsync(makerToken.address); taker = new Actor({ name: 'Taker', deployment }); orderFeeRecipient = new FeeRecipient({ @@ -75,7 +79,7 @@ blockchainTests('Forwarder integration tests', env => { makerAssetData, takerAssetData: wethAssetData, takerFee: constants.ZERO_AMOUNT, - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(makerFeeToken.address), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(makerFeeToken.address), takerFeeAssetData: wethAssetData, }, }); @@ -106,6 +110,7 @@ blockchainTests('Forwarder integration tests', env => { taker, orderFeeRecipient, forwarderFeeRecipient, + devUtils, ); }); @@ -166,7 +171,7 @@ blockchainTests('Forwarder integration tests', env => { await testFactory.marketSellTestAsync(orders, 1.34); }); it('should fail to fill an order with a percentage fee if the asset proxy is not yet approved', async () => { - const unapprovedAsset = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address); + const unapprovedAsset = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address); const order = await maker.signOrderAsync({ makerAssetData: unapprovedAsset, takerFee: toBaseUnitAmount(2), @@ -186,7 +191,7 @@ blockchainTests('Forwarder integration tests', env => { }, ); - const expectedBalances = LocalBalanceStore.create(balanceStore); + const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore); expectedBalances.burnGas(tx.from, DeploymentManager.gasPrice.times(tx.gasUsed)); // Verify balances @@ -236,7 +241,7 @@ blockchainTests('Forwarder integration tests', env => { }); it('should fill orders with different makerAssetData', async () => { const firstOrder = await maker.signOrderAsync(); - const secondOrderMakerAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address); + const secondOrderMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address); const secondOrder = await maker.signOrderAsync({ makerAssetData: secondOrderMakerAssetData, }); @@ -245,7 +250,7 @@ blockchainTests('Forwarder integration tests', env => { await testFactory.marketSellTestAsync(orders, 1.5); }); it('should fail to fill an order with a fee denominated in an asset other than makerAsset or WETH', async () => { - const takerFeeAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address); + const takerFeeAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address); const order = await maker.signOrderAsync({ takerFeeAssetData, takerFee: toBaseUnitAmount(1), @@ -336,7 +341,7 @@ blockchainTests('Forwarder integration tests', env => { }); it('should buy exactly makerAssetBuyAmount in orders with different makerAssetData', async () => { const firstOrder = await maker.signOrderAsync(); - const secondOrderMakerAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address); + const secondOrderMakerAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address); const secondOrder = await maker.signOrderAsync({ makerAssetData: secondOrderMakerAssetData, }); @@ -385,7 +390,7 @@ blockchainTests('Forwarder integration tests', env => { it('should buy an ERC721 asset from a single order', async () => { const erc721Order = await maker.signOrderAsync({ makerAssetAmount: new BigNumber(1), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, nftId), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, nftId), takerFeeAssetData: wethAssetData, }); await testFactory.marketBuyTestAsync([erc721Order], 1); @@ -393,14 +398,14 @@ blockchainTests('Forwarder integration tests', env => { it('should buy an ERC721 asset and pay a WETH fee', async () => { const erc721orderWithWethFee = await maker.signOrderAsync({ makerAssetAmount: new BigNumber(1), - makerAssetData: assetDataUtils.encodeERC721AssetData(erc721Token.address, nftId), + makerAssetData: await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, nftId), takerFee: toBaseUnitAmount(1), takerFeeAssetData: wethAssetData, }); await testFactory.marketBuyTestAsync([erc721orderWithWethFee], 1); }); it('should fail to fill an order with a fee denominated in an asset other than makerAsset or WETH', async () => { - const takerFeeAssetData = assetDataUtils.encodeERC20AssetData(anotherErc20Token.address); + const takerFeeAssetData = await devUtils.encodeERC20AssetData.callAsync(anotherErc20Token.address); const order = await maker.signOrderAsync({ takerFeeAssetData, takerFee: toBaseUnitAmount(1), @@ -491,11 +496,21 @@ blockchainTests('Forwarder integration tests', env => { ); // Compute expected balances - const expectedBalances = LocalBalanceStore.create(balanceStore); - expectedBalances.transferAsset(maker.address, taker.address, makerAssetFillAmount, makerAssetData); + const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore); + await expectedBalances.transferAssetAsync( + maker.address, + taker.address, + makerAssetFillAmount, + makerAssetData, + ); expectedBalances.wrapEth(taker.address, deployment.tokens.weth.address, ethValue); - expectedBalances.transferAsset(taker.address, maker.address, primaryTakerAssetFillAmount, wethAssetData); - expectedBalances.transferAsset( + await expectedBalances.transferAssetAsync( + taker.address, + maker.address, + primaryTakerAssetFillAmount, + wethAssetData, + ); + await expectedBalances.transferAssetAsync( taker.address, deployment.staking.stakingProxy.address, DeploymentManager.protocolFee, @@ -537,15 +552,15 @@ blockchainTests('Forwarder integration tests', env => { ); // Compute expected balances - const expectedBalances = LocalBalanceStore.create(balanceStore); - expectedBalances.transferAsset(maker.address, taker.address, makerAssetFillAmount, makerAssetData); + const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore); + expectedBalances.transferAssetAsync(maker.address, taker.address, makerAssetFillAmount, makerAssetData); expectedBalances.wrapEth( taker.address, deployment.tokens.weth.address, takerAssetFillAmount.plus(DeploymentManager.protocolFee), ); - expectedBalances.transferAsset(taker.address, maker.address, takerAssetFillAmount, wethAssetData); - expectedBalances.transferAsset( + expectedBalances.transferAssetAsync(taker.address, maker.address, takerAssetFillAmount, wethAssetData); + expectedBalances.transferAssetAsync( taker.address, deployment.staking.stakingProxy.address, DeploymentManager.protocolFee, diff --git a/contracts/integrations/test/forwarder/forwarder_test_factory.ts b/contracts/integrations/test/forwarder/forwarder_test_factory.ts index 0eff83fe99..fcc0b83199 100644 --- a/contracts/integrations/test/forwarder/forwarder_test_factory.ts +++ b/contracts/integrations/test/forwarder/forwarder_test_factory.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { BlockchainBalanceStore, LocalBalanceStore } from '@0x/contracts-exchange'; import { ForwarderContract } from '@0x/contracts-exchange-forwarder'; import { constants, expect, getPercentageOfValue, OrderStatus } from '@0x/contracts-test-utils'; @@ -33,6 +34,7 @@ export class ForwarderTestFactory { private readonly _taker: Actor, private readonly _orderFeeRecipient: FeeRecipient, private readonly _forwarderFeeRecipient: FeeRecipient, + private readonly _devUtils: DevUtilsContract, ) {} public async marketBuyTestAsync( @@ -157,7 +159,7 @@ export class ForwarderTestFactory { options: Partial, ): Promise { await this._balanceStore.updateBalancesAsync(); - const balances = LocalBalanceStore.create(this._balanceStore); + const balances = LocalBalanceStore.create(this._devUtils, this._balanceStore); const currentTotal = { wethSpentAmount: constants.ZERO_AMOUNT, makerAssetAcquiredAmount: constants.ZERO_AMOUNT, @@ -173,7 +175,7 @@ export class ForwarderTestFactory { continue; } - const { wethSpentAmount, makerAssetAcquiredAmount } = this._simulateSingleFill( + const { wethSpentAmount, makerAssetAcquiredAmount } = await this._simulateSingleFillAsync( balances, order, ordersInfoBefore[i].orderTakerAssetFilledAmount, @@ -197,12 +199,12 @@ export class ForwarderTestFactory { return { ...currentTotal, balances }; } - private _simulateSingleFill( + private async _simulateSingleFillAsync( balances: LocalBalanceStore, order: SignedOrder, takerAssetFilled: BigNumber, fillFraction: number, - ): ForwarderFillState { + ): Promise { let { makerAssetAmount, takerAssetAmount, makerFee, takerFee } = order; makerAssetAmount = makerAssetAmount.times(fillFraction).integerValue(BigNumber.ROUND_CEIL); takerAssetAmount = takerAssetAmount.times(fillFraction).integerValue(BigNumber.ROUND_CEIL); @@ -236,27 +238,42 @@ export class ForwarderTestFactory { // (In reality this is done all at once, but we simulate it order by order) // Maker -> Forwarder - balances.transferAsset(this._maker.address, this._forwarder.address, makerAssetAmount, order.makerAssetData); + await balances.transferAssetAsync( + this._maker.address, + this._forwarder.address, + makerAssetAmount, + order.makerAssetData, + ); // Maker -> Order fee recipient - balances.transferAsset(this._maker.address, this._orderFeeRecipient.address, makerFee, order.makerFeeAssetData); + await balances.transferAssetAsync( + this._maker.address, + this._orderFeeRecipient.address, + makerFee, + order.makerFeeAssetData, + ); // Forwarder -> Maker - balances.transferAsset(this._forwarder.address, this._maker.address, takerAssetAmount, order.takerAssetData); + await balances.transferAssetAsync( + this._forwarder.address, + this._maker.address, + takerAssetAmount, + order.takerAssetData, + ); // Forwarder -> Order fee recipient - balances.transferAsset( + await balances.transferAssetAsync( this._forwarder.address, this._orderFeeRecipient.address, takerFee, order.takerFeeAssetData, ); // Forwarder pays the protocol fee in WETH - balances.transferAsset( + await balances.transferAssetAsync( this._forwarder.address, this._deployment.staking.stakingProxy.address, DeploymentManager.protocolFee, order.takerAssetData, ); // Forwarder gives acquired maker asset to taker - balances.transferAsset( + await balances.transferAssetAsync( this._forwarder.address, this._taker.address, makerAssetAcquiredAmount, diff --git a/contracts/integrations/test/internal-integration-tests/exchange_wrapper_test.ts b/contracts/integrations/test/internal-integration-tests/exchange_wrapper_test.ts index 160e0fc74e..2ba36dcce6 100644 --- a/contracts/integrations/test/internal-integration-tests/exchange_wrapper_test.ts +++ b/contracts/integrations/test/internal-integration-tests/exchange_wrapper_test.ts @@ -1,4 +1,5 @@ import { artifacts as assetProxyArtifacts } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { IERC20TokenEvents, IERC20TokenTransferEventArgs } from '@0x/contracts-erc20'; import { artifacts as exchangeArtifacts, @@ -16,11 +17,12 @@ import { expect, getLatestBlockTimestampAsync, Numberish, + provider, toBaseUnitAmount, TransactionHelper, verifyEvents, } from '@0x/contracts-test-utils'; -import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils'; +import { ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils'; import { FillResults, OrderStatus, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; @@ -32,6 +34,7 @@ import { DeploymentManager } from '../utils/deployment_manager'; const { addFillResults, safeGetPartialAmountFloor } = ReferenceFunctions; +const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); // tslint:disable:no-unnecessary-type-assertion blockchainTests.resets('Exchange wrappers', env => { let maker: Maker; @@ -67,10 +70,10 @@ blockchainTests.resets('Exchange wrappers', env => { name: 'market maker', deployment, orderConfig: { - makerAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[0].address), - takerAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[1].address), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[0].address), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[1].address), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[2].address), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.erc20[2].address), feeRecipientAddress: feeRecipient, }, }); @@ -106,9 +109,9 @@ blockchainTests.resets('Exchange wrappers', env => { await blockchainBalances.updateBalancesAsync(); - initialLocalBalances = LocalBalanceStore.create(blockchainBalances); + initialLocalBalances = LocalBalanceStore.create(devUtils, blockchainBalances); - wethAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address); + wethAssetData = await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address); txHelper = new TransactionHelper(env.web3Wrapper, { ...assetProxyArtifacts, @@ -118,7 +121,7 @@ blockchainTests.resets('Exchange wrappers', env => { }); beforeEach(async () => { - localBalances = LocalBalanceStore.create(initialLocalBalances); + localBalances = LocalBalanceStore.create(devUtils, initialLocalBalances); }); interface SignedOrderWithValidity { @@ -126,9 +129,13 @@ blockchainTests.resets('Exchange wrappers', env => { isValid: boolean; } - function simulateFill(signedOrder: SignedOrder, expectedFillResults: FillResults, shouldUseWeth: boolean): void { + async function simulateFillAsync( + signedOrder: SignedOrder, + expectedFillResults: FillResults, + shouldUseWeth: boolean, + ): Promise { // taker -> maker - localBalances.transferAsset( + await localBalances.transferAssetAsync( taker.address, maker.address, expectedFillResults.takerAssetFilledAmount, @@ -136,7 +143,7 @@ blockchainTests.resets('Exchange wrappers', env => { ); // maker -> taker - localBalances.transferAsset( + await localBalances.transferAssetAsync( maker.address, taker.address, expectedFillResults.makerAssetFilledAmount, @@ -144,7 +151,7 @@ blockchainTests.resets('Exchange wrappers', env => { ); // maker -> feeRecipient - localBalances.transferAsset( + await localBalances.transferAssetAsync( maker.address, feeRecipient, expectedFillResults.makerFeePaid, @@ -152,7 +159,7 @@ blockchainTests.resets('Exchange wrappers', env => { ); // taker -> feeRecipient - localBalances.transferAsset( + await localBalances.transferAssetAsync( taker.address, feeRecipient, expectedFillResults.takerFeePaid, @@ -161,7 +168,7 @@ blockchainTests.resets('Exchange wrappers', env => { // taker -> protocol fees if (shouldUseWeth) { - localBalances.transferAsset( + await localBalances.transferAssetAsync( taker.address, deployment.staking.stakingProxy.address, expectedFillResults.protocolFeePaid, @@ -332,7 +339,7 @@ blockchainTests.resets('Exchange wrappers', env => { const shouldPayWethFees = DeploymentManager.protocolFee.gt(value); // Simulate filling the order - simulateFill(signedOrder, expectedFillResults, shouldPayWethFees); + await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees); // Ensure that the correct logs were emitted and that the balances are accurate. await assertResultsAsync(receipt, [{ signedOrder, expectedFillResults, shouldPayWethFees }]); @@ -430,7 +437,7 @@ blockchainTests.resets('Exchange wrappers', env => { } fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees }); - simulateFill(signedOrder, expectedFillResults, shouldPayWethFees); + await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees); } const [fillResults, receipt] = await txHelper.getResultAndReceiptAsync( @@ -492,7 +499,7 @@ blockchainTests.resets('Exchange wrappers', env => { } fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees }); - simulateFill(signedOrder, expectedFillResults, shouldPayWethFees); + await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees); } const [fillResults, receipt] = await txHelper.getResultAndReceiptAsync( @@ -583,7 +590,7 @@ blockchainTests.resets('Exchange wrappers', env => { } fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees }); - simulateFill(signedOrder, expectedFillResults, shouldPayWethFees); + await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees); } else { totalFillResults.push(nullFillResults); } @@ -696,7 +703,7 @@ blockchainTests.resets('Exchange wrappers', env => { takerFillAmount, ); - simulateFill(signedOrder, expectedFillResults, shouldPayWethFees); + await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees); fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees }); totalFillResults = addFillResults(totalFillResults, expectedFillResults); @@ -774,7 +781,9 @@ blockchainTests.resets('Exchange wrappers', env => { }); it('should fill a signedOrder that does not use the same takerAssetAddress (eth protocol fee)', async () => { - const differentTakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address); + const differentTakerAssetData = await devUtils.encodeERC20AssetData.callAsync( + deployment.tokens.erc20[2].address, + ); signedOrders = [ await maker.signOrderAsync(), @@ -795,7 +804,9 @@ blockchainTests.resets('Exchange wrappers', env => { }); it('should fill a signedOrder that does not use the same takerAssetAddress (weth protocol fee)', async () => { - const differentTakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address); + const differentTakerAssetData = await devUtils.encodeERC20AssetData.callAsync( + deployment.tokens.erc20[2].address, + ); signedOrders = [ await maker.signOrderAsync(), @@ -890,7 +901,7 @@ blockchainTests.resets('Exchange wrappers', env => { makerAssetBought, ); - simulateFill(signedOrder, expectedFillResults, shouldPayWethFees); + await simulateFillAsync(signedOrder, expectedFillResults, shouldPayWethFees); fillTestInfo.push({ signedOrder, expectedFillResults, shouldPayWethFees }); totalFillResults = addFillResults(totalFillResults, expectedFillResults); @@ -968,7 +979,9 @@ blockchainTests.resets('Exchange wrappers', env => { }); it('should fill a signedOrder that does not use the same makerAssetAddress (eth protocol fee)', async () => { - const differentMakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address); + const differentMakerAssetData = await devUtils.encodeERC20AssetData.callAsync( + deployment.tokens.erc20[2].address, + ); signedOrders = [ await maker.signOrderAsync(), @@ -990,7 +1003,9 @@ blockchainTests.resets('Exchange wrappers', env => { }); it('should fill a signedOrder that does not use the same makerAssetAddress (weth protocol fee)', async () => { - const differentMakerAssetData = assetDataUtils.encodeERC20AssetData(deployment.tokens.erc20[2].address); + const differentMakerAssetData = await devUtils.encodeERC20AssetData.callAsync( + deployment.tokens.erc20[2].address, + ); signedOrders = [ await maker.signOrderAsync(), diff --git a/contracts/integrations/test/internal-integration-tests/fillorder_test.ts b/contracts/integrations/test/internal-integration-tests/fillorder_test.ts index ea873b35db..16f532f609 100644 --- a/contracts/integrations/test/internal-integration-tests/fillorder_test.ts +++ b/contracts/integrations/test/internal-integration-tests/fillorder_test.ts @@ -1,3 +1,4 @@ +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { IERC20TokenEvents, IERC20TokenTransferEventArgs } from '@0x/contracts-erc20'; import { BlockchainBalanceStore, @@ -13,8 +14,8 @@ import { IStakingEventsRewardsPaidEventArgs, IStakingEventsStakingPoolEarnedRewardsInEpochEventArgs, } from '@0x/contracts-staking'; -import { blockchainTests, constants, expect, toBaseUnitAmount, verifyEvents } from '@0x/contracts-test-utils'; -import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { blockchainTests, constants, expect, provider, toBaseUnitAmount, verifyEvents } from '@0x/contracts-test-utils'; +import { orderHashUtils } from '@0x/order-utils'; import { SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; @@ -22,6 +23,7 @@ import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { actorAddressesByName, FeeRecipient, Maker, OperatorStakerMaker, StakerKeeper, Taker } from '../actors'; import { DeploymentManager } from '../utils/deployment_manager'; +const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); blockchainTests.resets('fillOrder integration tests', env => { let deployment: DeploymentManager; let balanceStore: BlockchainBalanceStore; @@ -48,10 +50,10 @@ blockchainTests.resets('fillOrder integration tests', env => { }); const orderConfig = { feeRecipientAddress: feeRecipient.address, - makerAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address), - takerAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(makerToken.address), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(takerToken.address), + makerAssetData: await devUtils.encodeERC20AssetData.callAsync(makerToken.address), + takerAssetData: await devUtils.encodeERC20AssetData.callAsync(takerToken.address), + makerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(makerToken.address), + takerFeeAssetData: await devUtils.encodeERC20AssetData.callAsync(takerToken.address), makerFee: constants.ZERO_AMOUNT, takerFee: constants.ZERO_AMOUNT, }; @@ -93,20 +95,30 @@ blockchainTests.resets('fillOrder integration tests', env => { await balanceStore.updateBalancesAsync(); }); - function simulateFill( + async function simulateFillAsync( order: SignedOrder, txReceipt: TransactionReceiptWithDecodedLogs, msgValue?: BigNumber, - ): LocalBalanceStore { + ): Promise { let remainingValue = msgValue !== undefined ? msgValue : DeploymentManager.protocolFee; - const localBalanceStore = LocalBalanceStore.create(balanceStore); + const localBalanceStore = LocalBalanceStore.create(devUtils, balanceStore); // Transaction gas cost localBalanceStore.burnGas(txReceipt.from, DeploymentManager.gasPrice.times(txReceipt.gasUsed)); // Taker -> Maker - localBalanceStore.transferAsset(taker.address, maker.address, order.takerAssetAmount, order.takerAssetData); + await localBalanceStore.transferAssetAsync( + taker.address, + maker.address, + order.takerAssetAmount, + order.takerAssetData, + ); // Maker -> Taker - localBalanceStore.transferAsset(maker.address, taker.address, order.makerAssetAmount, order.makerAssetData); + await localBalanceStore.transferAssetAsync( + maker.address, + taker.address, + order.makerAssetAmount, + order.makerAssetData, + ); // Protocol fee if (remainingValue.isGreaterThanOrEqualTo(DeploymentManager.protocolFee)) { @@ -117,11 +129,11 @@ blockchainTests.resets('fillOrder integration tests', env => { ); remainingValue = remainingValue.minus(DeploymentManager.protocolFee); } else { - localBalanceStore.transferAsset( + await localBalanceStore.transferAssetAsync( taker.address, deployment.staking.stakingProxy.address, DeploymentManager.protocolFee, - assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address), + await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address), ); } @@ -178,7 +190,7 @@ blockchainTests.resets('fillOrder integration tests', env => { const receipt = await taker.fillOrderAsync(order, order.takerAssetAmount); // Check balances - const expectedBalances = simulateFill(order, receipt); + const expectedBalances = await simulateFillAsync(order, receipt); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); @@ -204,7 +216,7 @@ blockchainTests.resets('fillOrder integration tests', env => { const receipt = await taker.fillOrderAsync(order, order.takerAssetAmount); // Check balances - const expectedBalances = simulateFill(order, receipt); + const expectedBalances = await simulateFillAsync(order, receipt); await balanceStore.updateBalancesAsync(); balanceStore.assertEquals(expectedBalances); @@ -237,7 +249,7 @@ blockchainTests.resets('fillOrder integration tests', env => { // Fetch the current balances await balanceStore.updateBalancesAsync(); - const expectedBalances = LocalBalanceStore.create(balanceStore); + const expectedBalances = LocalBalanceStore.create(devUtils, balanceStore); // End the epoch. This should wrap the staking proxy's ETH balance. const endEpochReceipt = await delegator.endEpochAsync(); @@ -279,11 +291,11 @@ blockchainTests.resets('fillOrder integration tests', env => { const [finalizePoolReceipt] = await delegator.finalizePoolsAsync([poolId]); // Check balances - expectedBalances.transferAsset( + await expectedBalances.transferAssetAsync( deployment.staking.stakingProxy.address, operator.address, operatorReward, - assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address), + await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address), ); expectedBalances.burnGas(delegator.address, DeploymentManager.gasPrice.times(finalizePoolReceipt.gasUsed)); await balanceStore.updateBalancesAsync(); @@ -340,7 +352,7 @@ blockchainTests.resets('fillOrder integration tests', env => { const order = await maker.signOrderAsync(); const receipt = await taker.fillOrderAsync(order, order.takerAssetAmount, { value: constants.ZERO_AMOUNT }); const rewardsAvailable = DeploymentManager.protocolFee; - const expectedBalances = simulateFill(order, receipt, constants.ZERO_AMOUNT); + const expectedBalances = await simulateFillAsync(order, receipt, constants.ZERO_AMOUNT); // End the epoch. This should wrap the staking proxy's ETH balance. const endEpochReceipt = await delegator.endEpochAsync(); @@ -359,11 +371,11 @@ blockchainTests.resets('fillOrder integration tests', env => { const [finalizePoolReceipt] = await delegator.finalizePoolsAsync([poolId]); // Check balances - expectedBalances.transferAsset( + await expectedBalances.transferAssetAsync( deployment.staking.stakingProxy.address, operator.address, operatorReward, - assetDataUtils.encodeERC20AssetData(deployment.tokens.weth.address), + await devUtils.encodeERC20AssetData.callAsync(deployment.tokens.weth.address), ); expectedBalances.burnGas(delegator.address, DeploymentManager.gasPrice.times(finalizePoolReceipt.gasUsed)); await balanceStore.updateBalancesAsync(); diff --git a/contracts/staking/package.json b/contracts/staking/package.json index 8ca31ec93a..b2596a2a1c 100644 --- a/contracts/staking/package.json +++ b/contracts/staking/package.json @@ -50,6 +50,7 @@ "homepage": "https://github.com/0xProject/0x-monorepo/contracts/tokens/README.md", "devDependencies": { "@0x/abi-gen": "^4.3.0-beta.0", + "@0x/contracts-dev-utils": "^0.1.0-beta.0", "@0x/contracts-exchange-libs": "^3.1.0-beta.0", "@0x/contracts-gen": "^1.1.0-beta.0", "@0x/contracts-test-utils": "^3.2.0-beta.0", diff --git a/contracts/staking/test/unit_tests/zrx_vault_test.ts b/contracts/staking/test/unit_tests/zrx_vault_test.ts index c2c3a10b4e..6c2209ce44 100644 --- a/contracts/staking/test/unit_tests/zrx_vault_test.ts +++ b/contracts/staking/test/unit_tests/zrx_vault_test.ts @@ -1,12 +1,14 @@ import { ERC20Wrapper } from '@0x/contracts-asset-proxy'; +import { DevUtilsContract } from '@0x/contracts-dev-utils'; import { blockchainTests, constants, expect, expectTransactionFailedAsync, filterLogsToArguments, + provider, } from '@0x/contracts-test-utils'; -import { assetDataUtils, StakingRevertErrors } from '@0x/order-utils'; +import { StakingRevertErrors } from '@0x/order-utils'; import { RevertReason } from '@0x/types'; import { AuthorizableRevertErrors, BigNumber, SafeMathRevertErrors } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; @@ -32,6 +34,8 @@ blockchainTests.resets('ZrxVault unit tests', env => { let zrxAssetData: string; let zrxProxyAddress: string; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); + before(async () => { // create accounts accounts = await env.getAccountAddressesAsync(); @@ -44,7 +48,7 @@ blockchainTests.resets('ZrxVault unit tests', env => { zrxProxyAddress = erc20ProxyContract.address; // deploy zrx token const [zrxTokenContract] = await erc20Wrapper.deployDummyTokensAsync(1, constants.DUMMY_TOKEN_DECIMALS); - zrxAssetData = assetDataUtils.encodeERC20AssetData(zrxTokenContract.address); + zrxAssetData = await devUtils.encodeERC20AssetData.callAsync(zrxTokenContract.address); await erc20Wrapper.setBalancesAndAllowancesAsync(); diff --git a/contracts/test-utils/CHANGELOG.json b/contracts/test-utils/CHANGELOG.json index fbac14a39b..a3c37665ed 100644 --- a/contracts/test-utils/CHANGELOG.json +++ b/contracts/test-utils/CHANGELOG.json @@ -1,4 +1,13 @@ [ + { + "version": "3.2.0-beta.1", + "changes": [ + { + "note": "OrderFactory default order expiration time increased from ten minutes to fifteen minutes ", + "pr": 2304 + } + ] + }, { "version": "3.2.0-beta.0", "changes": [ diff --git a/contracts/test-utils/src/order_factory.ts b/contracts/test-utils/src/order_factory.ts index 4a20febc4b..04e3adab1c 100644 --- a/contracts/test-utils/src/order_factory.ts +++ b/contracts/test-utils/src/order_factory.ts @@ -19,12 +19,12 @@ export class OrderFactory { customOrderParams: Partial = {}, signatureType: SignatureType = SignatureType.EthSign, ): Promise { - const tenMinutesInSeconds = 10 * 60; + const fifteenMinutesInSeconds = 15 * 60; const currentBlockTimestamp = await getLatestBlockTimestampAsync(); const order = ({ takerAddress: constants.NULL_ADDRESS, senderAddress: constants.NULL_ADDRESS, - expirationTimeSeconds: new BigNumber(currentBlockTimestamp).plus(tenMinutesInSeconds), + expirationTimeSeconds: new BigNumber(currentBlockTimestamp).plus(fifteenMinutesInSeconds), salt: generatePseudoRandomSalt(), ...this._defaultOrderParams, ...customOrderParams, diff --git a/contracts/tests/test/dev-utils/lib_asset_data.ts b/contracts/tests/test/dev-utils/lib_asset_data.ts index 1b1d9b6dda..67c1277162 100644 --- a/contracts/tests/test/dev-utils/lib_asset_data.ts +++ b/contracts/tests/test/dev-utils/lib_asset_data.ts @@ -1,5 +1,6 @@ import * as chai from 'chai'; import { LogWithDecodedArgs } from 'ethereum-types'; +import * as crypto from 'crypto'; import { artifacts as proxyArtifacts, @@ -20,12 +21,12 @@ import { artifacts as erc721Artifacts, DummyERC721TokenContract } from '@0x/cont import { artifacts as exchangeArtifacts, ExchangeContract } from '@0x/contracts-exchange'; import { chaiSetup, constants, LogDecoder, provider, txDefaults, web3Wrapper } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { AssetProxyId } from '@0x/types'; -import { BigNumber, providerUtils } from '@0x/utils'; +import { BigNumber, providerUtils, StringRevertError } from '@0x/utils'; import * as ethUtil from 'ethereumjs-util'; import { artifacts, LibAssetDataContract } from '@0x/contracts-dev-utils'; +import { InvalidByteOperationError } from '@0x/utils/lib/src/lib_bytes_revert_errors'; chaiSetup.configure(); const expect = chai.expect; @@ -61,6 +62,13 @@ const KNOWN_MULTI_ASSET_ENCODING = { assetData: '0x94cfcdd7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000046000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204a7cb5fb70000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c480000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000003e90000000000000000000000000000000000000000000000000000000000002711000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c800000000000000000000000000000000000000000000000000000000000007d10000000000000000000000000000000000000000000000000000000000004e210000000000000000000000000000000000000000000000000000000000000044025717920000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c4800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', }; +const KNOWN_STATIC_CALL_ENCODING = { + staticCallTargetAddress: '0x6dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f', + staticCallData: '0xed2cfc9c0000000000000000000000000000000000000000000000000000000000000001', + expectedReturnDataHash: '0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6', + assetData: + '0xc339d10a0000000000000000000000006dfff22588be9b3ef8cf0ad6dc9b84796f9fb45f0000000000000000000000000000000000000000000000000000000000000060b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60000000000000000000000000000000000000000000000000000000000000024ed2cfc9c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000', +}; describe('LibAssetData', () => { let exchange: ExchangeContract; @@ -215,6 +223,18 @@ describe('LibAssetData', () => { }); describe('encoding and decoding', () => { + it('should decode any asset proxy ID', async () => { + const assetDataScenarios = [ + [KNOWN_ERC20_ENCODING.assetData, AssetProxyId.ERC20], + [KNOWN_ERC721_ENCODING.assetData, AssetProxyId.ERC721], + [KNOWN_ERC1155_ENCODING.assetData, AssetProxyId.ERC1155], + [KNOWN_MULTI_ASSET_ENCODING.assetData, AssetProxyId.MultiAsset], + ]; + + for (const [assetData, proxyId] of assetDataScenarios) { + expect(await libAssetData.decodeAssetProxyId.callAsync(assetData)).to.equal(proxyId); + } + }); it('should encode ERC20 asset data', async () => { expect(await libAssetData.encodeERC20AssetData.callAsync(KNOWN_ERC20_ENCODING.address)).to.equal( KNOWN_ERC20_ENCODING.assetData, @@ -286,35 +306,97 @@ describe('LibAssetData', () => { KNOWN_MULTI_ASSET_ENCODING.nestedAssetData, ]); }); + + it('should encode StaticCall data', async () => { + expect( + await libAssetData.encodeStaticCallAssetData.callAsync( + KNOWN_STATIC_CALL_ENCODING.staticCallTargetAddress, + KNOWN_STATIC_CALL_ENCODING.staticCallData, + KNOWN_STATIC_CALL_ENCODING.expectedReturnDataHash, + ), + ).to.equal(KNOWN_STATIC_CALL_ENCODING.assetData); + }); + + it('should decode StaticCall data', async () => { + expect( + await libAssetData.decodeStaticCallAssetData.callAsync(KNOWN_STATIC_CALL_ENCODING.assetData), + ).to.deep.equal([ + AssetProxyId.StaticCall, + KNOWN_STATIC_CALL_ENCODING.staticCallTargetAddress, + KNOWN_STATIC_CALL_ENCODING.staticCallData, + KNOWN_STATIC_CALL_ENCODING.expectedReturnDataHash, + ]); + }); + }); + describe('revertIfInvalidAssetData', async () => { + it('should succeed for any valid asset data', async () => { + const assetData = [ + KNOWN_ERC20_ENCODING.assetData, + KNOWN_ERC721_ENCODING.assetData, + KNOWN_ERC1155_ENCODING.assetData, + KNOWN_MULTI_ASSET_ENCODING.assetData, + KNOWN_STATIC_CALL_ENCODING.assetData, + ]; + + for (const data of assetData) { + await libAssetData.revertIfInvalidAssetData.callAsync(data); + } + return; + }); + + it('should revert for invalid assetProxyId', async () => { + const badAssetData = '0x' + crypto.randomBytes(4).toString('hex') + constants.NULL_ADDRESS; + await expect(libAssetData.revertIfInvalidAssetData.callAsync(badAssetData)).to.eventually.be.rejectedWith( + StringRevertError, + ); + }); + + it('should revert for invalid assetData with valid assetProxyId', async () => { + // the other encodings are always valid if the assetProxyId is valid + const assetData = [KNOWN_ERC20_ENCODING.assetData, KNOWN_ERC721_ENCODING.assetData]; + + for (const data of assetData) { + const badData = data.substring(0, data.length - 2); // drop one byte but retain assetProxyId + await expect(libAssetData.revertIfInvalidAssetData.callAsync(badData)).to.eventually.be.rejectedWith( + InvalidByteOperationError, + ); + } + }); }); describe('getBalance', () => { it('should query ERC20 balance by asset data', async () => { - const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); + const assetData = await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address); expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal( erc20TokenTotalSupply, ); }); it('should return 0 if ERC20 token does not exist', async () => { - const assetData = assetDataUtils.encodeERC20AssetData(constants.NULL_ADDRESS); + const assetData = await libAssetData.encodeERC20AssetData.callAsync(constants.NULL_ADDRESS); const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); }); it('should query ERC721 balance by asset data', async () => { - const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); + const assetData = await libAssetData.encodeERC721AssetData.callAsync( + erc721Token.address, + firstERC721TokenId, + ); expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal(1); }); it('should return 0 if ERC721 token does not exist', async () => { - const assetData = assetDataUtils.encodeERC721AssetData(constants.NULL_ADDRESS, firstERC721TokenId); + const assetData = await libAssetData.encodeERC721AssetData.callAsync( + constants.NULL_ADDRESS, + firstERC721TokenId, + ); const balance = await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData); expect(balance).to.bignumber.equal(constants.ZERO_AMOUNT); }); it('should query ERC1155 balances by asset data', async () => { - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await libAssetData.encodeERC1155AssetData.callAsync( erc1155Token.address, [erc1155TokenId], [new BigNumber(1)], @@ -324,7 +406,7 @@ describe('LibAssetData', () => { }); it('should return 0 if ERC1155 token does not exist', async () => { - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await libAssetData.encodeERC1155AssetData.callAsync( constants.NULL_ADDRESS, [erc1155TokenId], [new BigNumber(1)], @@ -335,11 +417,11 @@ describe('LibAssetData', () => { }); it('should query multi-asset batch balance by asset data', async () => { - const assetData = assetDataUtils.encodeMultiAssetData( + const assetData = await libAssetData.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], [ - assetDataUtils.encodeERC20AssetData(erc20Token.address), - assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId), + await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address), + await libAssetData.encodeERC721AssetData.callAsync(erc721Token.address, firstERC721TokenId), ], ); expect(await libAssetData.getBalance.callAsync(tokenOwnerAddress, assetData)).to.bignumber.equal( @@ -357,7 +439,7 @@ describe('LibAssetData', () => { const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(1)); const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await libAssetData.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -370,7 +452,7 @@ describe('LibAssetData', () => { const staticCallData = staticCallTarget.isOddNumber.getABIEncodedTransactionData(new BigNumber(0)); const trueAsBuffer = ethUtil.toBuffer('0x0000000000000000000000000000000000000000000000000000000000000001'); const expectedResultHash = ethUtil.bufferToHex(ethUtil.sha3(trueAsBuffer)); - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await libAssetData.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, expectedResultHash, @@ -386,7 +468,7 @@ describe('LibAssetData', () => { await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); + const assetData = await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address); expect( await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), ).to.bignumber.equal(allowance); @@ -396,7 +478,10 @@ describe('LibAssetData', () => { await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); + const assetData = await libAssetData.encodeERC721AssetData.callAsync( + erc721Token.address, + firstERC721TokenId, + ); expect( await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), ).to.bignumber.equal(1); @@ -406,7 +491,10 @@ describe('LibAssetData', () => { await erc721Token.setApprovalForAll.awaitTransactionSuccessAsync(erc721Proxy.address, true, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); + const assetData = await libAssetData.encodeERC721AssetData.callAsync( + erc721Token.address, + firstERC721TokenId, + ); expect( await libAssetData.getAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), ).to.bignumber.equal(constants.UNLIMITED_ALLOWANCE_IN_BASE_UNITS); @@ -416,7 +504,7 @@ describe('LibAssetData', () => { await erc1155Token.setApprovalForAll.awaitTransactionSuccessAsync(erc1155Proxy.address, true, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeERC1155AssetData( + const assetData = await libAssetData.encodeERC1155AssetData.callAsync( erc1155Token.address, [erc1155TokenId], [new BigNumber(1)], @@ -435,11 +523,11 @@ describe('LibAssetData', () => { await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeMultiAssetData( + const assetData = await libAssetData.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], [ - assetDataUtils.encodeERC20AssetData(erc20Token.address), - assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId), + await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address), + await libAssetData.encodeERC721AssetData.callAsync(erc721Token.address, firstERC721TokenId), ], ); expect( @@ -456,7 +544,7 @@ describe('LibAssetData', () => { it('should return an allowance of MAX_UINT256 for any staticCallAssetData', async () => { const staticCallData = AssetProxyId.StaticCall; - const assetData = assetDataUtils.encodeStaticCallAssetData( + const assetData = await libAssetData.encodeStaticCallAssetData.callAsync( staticCallTarget.address, staticCallData, constants.KECCAK256_NULL, @@ -468,8 +556,11 @@ describe('LibAssetData', () => { describe('getBatchBalances', () => { it('should query balances for a batch of asset data strings', async () => { - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); + const erc20AssetData = await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address); + const erc721AssetData = await libAssetData.encodeERC721AssetData.callAsync( + erc721Token.address, + firstERC721TokenId, + ); expect( await libAssetData.getBatchBalances.callAsync(tokenOwnerAddress, [erc20AssetData, erc721AssetData]), ).to.deep.equal([new BigNumber(erc20TokenTotalSupply), new BigNumber(1)]); @@ -482,7 +573,7 @@ describe('LibAssetData', () => { await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); + const assetData = await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address); expect( await libAssetData.getBalanceAndAssetProxyAllowance.callAsync(tokenOwnerAddress, assetData), ).to.deep.equal([new BigNumber(erc20TokenTotalSupply), allowance]); @@ -494,7 +585,7 @@ describe('LibAssetData', () => { await erc20Token.approve.awaitTransactionSuccessAsync(erc20Proxy.address, allowance, { from: tokenOwnerAddress, }); - const assetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); + const assetData = await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address); expect( await libAssetData.getBatchBalancesAndAssetProxyAllowances.callAsync(tokenOwnerAddress, [assetData]), ).to.deep.equal([[new BigNumber(erc20TokenTotalSupply)], [allowance]]); @@ -510,8 +601,11 @@ describe('LibAssetData', () => { await erc721Token.approve.awaitTransactionSuccessAsync(erc721Proxy.address, firstERC721TokenId, { from: tokenOwnerAddress, }); - const erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); - const erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, firstERC721TokenId); + const erc20AssetData = await libAssetData.encodeERC20AssetData.callAsync(erc20Token.address); + const erc721AssetData = await libAssetData.encodeERC721AssetData.callAsync( + erc721Token.address, + firstERC721TokenId, + ); expect( await libAssetData.getBatchAssetProxyAllowances.callAsync(tokenOwnerAddress, [ erc20AssetData, diff --git a/contracts/tests/test/dev-utils/order_validation_utils.ts b/contracts/tests/test/dev-utils/order_validation_utils.ts index e8d2c126fd..05f5ea8da5 100644 --- a/contracts/tests/test/dev-utils/order_validation_utils.ts +++ b/contracts/tests/test/dev-utils/order_validation_utils.ts @@ -19,7 +19,7 @@ import { web3Wrapper, } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { orderHashUtils } from '@0x/order-utils'; import { OrderTransferResults, SignedOrder } from '@0x/types'; import { BigNumber, providerUtils } from '@0x/utils'; import * as chai from 'chai'; @@ -79,7 +79,6 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => { [erc721Token] = await erc721Wrapper.deployDummyTokensAsync(); erc721Proxy = await erc721Wrapper.deployProxyAsync(); - feeAssetData = assetDataUtils.encodeERC20AssetData(feeErc20Token.address); exchange = await ExchangeContract.deployFrom0xArtifactAsync( exchangeArtifacts.Exchange, provider, @@ -109,9 +108,10 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => { exchange.address, ); - erc20AssetData = assetDataUtils.encodeERC20AssetData(erc20Token.address); - erc20AssetData2 = assetDataUtils.encodeERC20AssetData(erc20Token2.address); - erc721AssetData = assetDataUtils.encodeERC721AssetData(erc721Token.address, tokenId); + feeAssetData = await devUtils.encodeERC20AssetData.callAsync(feeErc20Token.address); + erc20AssetData = await devUtils.encodeERC20AssetData.callAsync(erc20Token.address); + erc20AssetData2 = await devUtils.encodeERC20AssetData.callAsync(erc20Token2.address); + erc721AssetData = await devUtils.encodeERC721AssetData.callAsync(erc721Token.address, tokenId); const defaultOrderParams = { ...constants.STATIC_ORDER_PARAMS, makerAddress, @@ -162,7 +162,7 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => { expect(transferableAmount).to.bignumber.equal(allowance); }); it('should return the correct transferable amount for multiAssetData', async () => { - const multiAssetData = assetDataUtils.encodeMultiAssetData( + const multiAssetData = await devUtils.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2], ); @@ -227,7 +227,7 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => { expect(fillableTakerAssetAmount).to.bignumber.equal(constants.ZERO_AMOUNT); }); it('should return a fillableTakerAssetAmount of 0 when balances/allowances of one asset within a multiAssetData are insufficient', async () => { - const multiAssetData = assetDataUtils.encodeMultiAssetData( + const multiAssetData = await devUtils.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2], ); @@ -285,7 +285,7 @@ describe('OrderValidationUtils/OrderTransferSimulatorUtils', () => { ); }); it('should return the correct fillableTakerAssetAmount when balances/allowances of one asset within a multiAssetData are partially sufficient', async () => { - const multiAssetData = assetDataUtils.encodeMultiAssetData( + const multiAssetData = await devUtils.encodeMultiAssetData.callAsync( [new BigNumber(1), new BigNumber(1)], [erc20AssetData, erc20AssetData2], ); diff --git a/packages/asset-buyer/src/asset_buyer.ts b/packages/asset-buyer/src/asset_buyer.ts index ff595fe567..55f972bcd4 100644 --- a/packages/asset-buyer/src/asset_buyer.ts +++ b/packages/asset-buyer/src/asset_buyer.ts @@ -137,7 +137,7 @@ export class AssetBuyer { assert.isValidPercentage('feePercentage', feePercentage); assert.isBoolean('shouldForceOrderRefresh', shouldForceOrderRefresh); assert.isNumber('slippagePercentage', slippagePercentage); - const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow(); + const zrxTokenAssetData = await this._getZrxTokenAssetDataOrThrowAsync(); const isMakerAssetZrxToken = assetData === zrxTokenAssetData; // get the relevant orders for the makerAsset and fees // if the requested assetData is ZRX, don't get the fee info @@ -177,7 +177,7 @@ export class AssetBuyer { ): Promise { assert.isETHAddressHex('tokenAddress', tokenAddress); assert.isBigNumber('assetBuyAmount', assetBuyAmount); - const assetData = assetDataUtils.encodeERC20AssetData(tokenAddress); + const assetData = await this._contractWrappers.devUtils.encodeERC20AssetData.callAsync(tokenAddress); const buyQuote = this.getBuyQuoteAsync(assetData, assetBuyAmount, options); return buyQuote; } @@ -200,7 +200,7 @@ export class AssetBuyer { assert.isBoolean('options.shouldForceOrderRefresh', shouldForceOrderRefresh); const assetPairs = await this.orderProvider.getAvailableMakerAssetDatasAsync(assetData); - const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow(); + const etherTokenAssetData = await this._getEtherTokenAssetDataOrThrowAsync(); if (!assetPairs.includes(etherTokenAssetData)) { return { tokensAvailableInBaseUnits: new BigNumber(0), @@ -298,7 +298,7 @@ export class AssetBuyer { * @return An array of asset data strings that can be purchased using wETH. */ public async getAvailableAssetDatasAsync(): Promise { - const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow(); + const etherTokenAssetData = await this._getEtherTokenAssetDataOrThrowAsync(); return this.orderProvider.getAvailableMakerAssetDatasAsync(etherTokenAssetData); } /** @@ -325,8 +325,8 @@ export class AssetBuyer { const result = ordersEntryIfExists.ordersAndFillableAmounts; return result; } - const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow(); - const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow(); + const etherTokenAssetData = await this._getEtherTokenAssetDataOrThrowAsync(); + const zrxTokenAssetData = await this._getZrxTokenAssetDataOrThrowAsync(); // construct orderProvider request const orderProviderRequest = { makerAssetData: assetData, @@ -359,14 +359,18 @@ export class AssetBuyer { * Get the assetData that represents the WETH token. * Will throw if WETH does not exist for the current chain. */ - private _getEtherTokenAssetDataOrThrow(): string { - return assetDataUtils.encodeERC20AssetData(this._contractWrappers.contractAddresses.etherToken); + private async _getEtherTokenAssetDataOrThrowAsync(): Promise { + return this._contractWrappers.devUtils.encodeERC20AssetData.callAsync( + this._contractWrappers.contractAddresses.etherToken, + ); } /** * Get the assetData that represents the ZRX token. * Will throw if ZRX does not exist for the current chain. */ - private _getZrxTokenAssetDataOrThrow(): string { - return assetDataUtils.encodeERC20AssetData(this._contractWrappers.contractAddresses.zrxToken); + private async _getZrxTokenAssetDataOrThrowAsync(): Promise { + return this._contractWrappers.devUtils.encodeERC20AssetData.callAsync( + this._contractWrappers.contractAddresses.zrxToken, + ); } } diff --git a/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts b/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts index 427484dfd5..a709fa53db 100644 --- a/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts +++ b/packages/asset-swapper/src/quote_consumers/forwarder_swap_quote_consumer.ts @@ -1,5 +1,4 @@ import { ContractError, ContractWrappers, ForwarderError } from '@0x/contract-wrappers'; -import { assetDataUtils } from '@0x/order-utils'; import { MarketOperation } from '@0x/types'; import { AbiEncoder, providerUtils } from '@0x/utils'; import { SupportedProvider, ZeroExProvider } from '@0x/web3-wrapper'; @@ -50,7 +49,7 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase, ): Promise { - assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow()); + assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync()); const { toAddress, methodAbi, ethAmount, params } = await this.getSmartContractParamsOrThrowAsync(quote, opts); @@ -82,7 +81,7 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase, ): Promise> { - assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow()); + assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync()); const { ethAmount, feeRecipient, feePercentage: unFormattedFeePercentage } = _.merge( {}, @@ -160,7 +159,7 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase, ): Promise { - assert.isValidForwarderSwapQuote('quote', quote, this._getEtherTokenAssetDataOrThrow()); + assert.isValidForwarderSwapQuote('quote', quote, await this._getEtherTokenAssetDataOrThrowAsync()); const { ethAmount, takerAddress, gasLimit, gasPrice, feeRecipient, feePercentage } = _.merge( {}, @@ -236,7 +235,9 @@ export class ForwarderSwapQuoteConsumer implements SwapQuoteConsumerBase { + return this._contractWrappers.devUtils.encodeERC20AssetData.callAsync( + this._contractWrappers.contractAddresses.etherToken, + ); } } diff --git a/packages/asset-swapper/src/swap_quoter.ts b/packages/asset-swapper/src/swap_quoter.ts index 89080c6760..a5f43d8350 100644 --- a/packages/asset-swapper/src/swap_quoter.ts +++ b/packages/asset-swapper/src/swap_quoter.ts @@ -216,8 +216,8 @@ export class SwapQuoter { assert.isETHAddressHex('makerTokenAddress', makerTokenAddress); assert.isETHAddressHex('takerTokenAddress', takerTokenAddress); assert.isBigNumber('makerAssetBuyAmount', makerAssetBuyAmount); - const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenAddress); - const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenAddress); + const makerAssetData = await this._contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress); + const takerAssetData = await this._contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress); const swapQuote = this.getMarketBuySwapQuoteForAssetDataAsync( makerAssetData, takerAssetData, @@ -246,8 +246,8 @@ export class SwapQuoter { assert.isETHAddressHex('makerTokenAddress', makerTokenAddress); assert.isETHAddressHex('takerTokenAddress', takerTokenAddress); assert.isBigNumber('takerAssetSellAmount', takerAssetSellAmount); - const makerAssetData = assetDataUtils.encodeERC20AssetData(makerTokenAddress); - const takerAssetData = assetDataUtils.encodeERC20AssetData(takerTokenAddress); + const makerAssetData = await this._contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress); + const takerAssetData = await this._contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress); const swapQuote = this.getMarketSellSwapQuoteForAssetDataAsync( makerAssetData, takerAssetData, @@ -346,7 +346,7 @@ export class SwapQuoter { assert.isString('takerAssetData', takerAssetData); assetDataUtils.decodeAssetDataOrThrow(makerAssetData); assetDataUtils.decodeAssetDataOrThrow(takerAssetData); - const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow(); + const zrxTokenAssetData = await this._getZrxTokenAssetDataOrThrowAsync(); // get orders const response = await this.orderbook.getOrdersAsync(makerAssetData, takerAssetData); const adaptedResponse = { orders: response.map(o => ({ ...o.order, ...o.metaData })) }; @@ -396,8 +396,10 @@ export class SwapQuoter { * Get the assetData that represents the ZRX token. * Will throw if ZRX does not exist for the current chain. */ - private _getZrxTokenAssetDataOrThrow(): string { - return assetDataUtils.encodeERC20AssetData(this._contractWrappers.contractAddresses.zrxToken); + private async _getZrxTokenAssetDataOrThrowAsync(): Promise { + return this._contractWrappers.devUtils.encodeERC20AssetData.callAsync( + this._contractWrappers.contractAddresses.zrxToken, + ); } /** @@ -418,7 +420,7 @@ export class SwapQuoter { assert.isString('makerAssetData', makerAssetData); assert.isString('takerAssetData', takerAssetData); assert.isNumber('slippagePercentage', slippagePercentage); - const zrxTokenAssetData = this._getZrxTokenAssetDataOrThrow(); + const zrxTokenAssetData = await this._getZrxTokenAssetDataOrThrowAsync(); const isMakerAssetZrxToken = makerAssetData === zrxTokenAssetData; // get the relevant orders for the makerAsset const ordersAndFillableAmounts = await this.getOrdersAndFillableAmountsAsync(makerAssetData, takerAssetData); diff --git a/packages/asset-swapper/src/utils/swap_quote_consumer_utils.ts b/packages/asset-swapper/src/utils/swap_quote_consumer_utils.ts index 291b7f2cbc..3a1fd1c9d8 100644 --- a/packages/asset-swapper/src/utils/swap_quote_consumer_utils.ts +++ b/packages/asset-swapper/src/utils/swap_quote_consumer_utils.ts @@ -1,5 +1,4 @@ import { ContractWrappers } from '@0x/contract-wrappers'; -import { assetDataUtils } from '@0x/order-utils'; import { MarketOperation, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { SupportedProvider, Web3Wrapper } from '@0x/web3-wrapper'; @@ -85,7 +84,9 @@ export const swapQuoteConsumerUtils = { provider: Provider, opts: Partial, ): Promise { - const wethAssetData = assetDataUtils.encodeERC20AssetData(contractWrappers.contractAddresses.etherToken); + const wethAssetData = await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + contractWrappers.contractAddresses.etherToken, + ); if (swapQuoteConsumerUtils.isValidForwarderSwapQuote(quote, wethAssetData)) { if (opts.takerAddress !== undefined) { assert.isETHAddressHex('takerAddress', opts.takerAddress); diff --git a/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts b/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts index 9bdd7b878c..f48f28c856 100644 --- a/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts +++ b/packages/asset-swapper/test/exchange_swap_quote_consumer_test.ts @@ -1,7 +1,6 @@ import { ContractAddresses, ContractWrappers, ERC20TokenContract } from '@0x/contract-wrappers'; import { constants as devConstants, OrderFactory } from '@0x/contracts-test-utils'; import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { MarketOperation, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -67,9 +66,9 @@ describe('ExchangeSwapQuoteConsumer', () => { [coinbaseAddress, takerAddress, makerAddress, feeRecipient] = userAddresses; [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); [makerAssetData, takerAssetData, wethAssetData] = [ - assetDataUtils.encodeERC20AssetData(makerTokenAddress), - assetDataUtils.encodeERC20AssetData(takerTokenAddress), - assetDataUtils.encodeERC20AssetData(contractAddresses.etherToken), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(contractAddresses.etherToken), ]; erc20TokenContract = new ERC20TokenContract(makerTokenAddress, provider); @@ -80,8 +79,12 @@ describe('ExchangeSwapQuoteConsumer', () => { takerAddress, makerAssetData, takerAssetData, - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(contractAddresses.zrxToken), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(contractAddresses.zrxToken), + makerFeeAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + contractAddresses.zrxToken, + ), + takerFeeAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + contractAddresses.zrxToken, + ), exchangeAddress: contractAddresses.exchange, chainId, }; diff --git a/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts b/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts index 4c80770ddc..4b6621487e 100644 --- a/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts +++ b/packages/asset-swapper/test/forwarder_swap_quote_consumer_test.ts @@ -1,6 +1,5 @@ import { ContractAddresses, ContractWrappers, ERC20TokenContract } from '@0x/contract-wrappers'; import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { MarketOperation, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -67,9 +66,9 @@ describe('ForwarderSwapQuoteConsumer', () => { [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); erc20Token = new ERC20TokenContract(makerTokenAddress, provider); [makerAssetData, takerAssetData, wethAssetData] = [ - assetDataUtils.encodeERC20AssetData(makerTokenAddress), - assetDataUtils.encodeERC20AssetData(takerTokenAddress), - assetDataUtils.encodeERC20AssetData(contractAddresses.etherToken), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(contractAddresses.etherToken), ]; }); after(async () => { diff --git a/packages/asset-swapper/test/swap_quote_consumer_test.ts b/packages/asset-swapper/test/swap_quote_consumer_test.ts index f1e59ad68c..11cc89af3c 100644 --- a/packages/asset-swapper/test/swap_quote_consumer_test.ts +++ b/packages/asset-swapper/test/swap_quote_consumer_test.ts @@ -1,6 +1,5 @@ import { ContractAddresses, ContractWrappers, ERC20TokenContract } from '@0x/contract-wrappers'; import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { MarketOperation, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -61,9 +60,9 @@ describe('SwapQuoteConsumer', () => { [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); erc20Token = new ERC20TokenContract(makerTokenAddress, provider); [makerAssetData, takerAssetData, wethAssetData] = [ - assetDataUtils.encodeERC20AssetData(makerTokenAddress), - assetDataUtils.encodeERC20AssetData(takerTokenAddress), - assetDataUtils.encodeERC20AssetData(contractAddresses.etherToken), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(contractAddresses.etherToken), ]; }); after(async () => { diff --git a/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts b/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts index d0cbb26956..b5e782c96a 100644 --- a/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts +++ b/packages/asset-swapper/test/swap_quote_consumer_utils_test.ts @@ -1,6 +1,5 @@ import { ContractAddresses, ContractWrappers } from '@0x/contract-wrappers'; import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { MarketOperation, SignedOrder } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -53,9 +52,9 @@ describe('swapQuoteConsumerUtils', () => { [takerAddress, makerAddress] = userAddresses; [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); [makerAssetData, takerAssetData, wethAssetData] = [ - assetDataUtils.encodeERC20AssetData(makerTokenAddress), - assetDataUtils.encodeERC20AssetData(takerTokenAddress), - assetDataUtils.encodeERC20AssetData(contractAddresses.etherToken), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(contractAddresses.etherToken), ]; swapQuoteConsumer = new SwapQuoteConsumer(provider, { diff --git a/packages/base-contract/src/index.ts b/packages/base-contract/src/index.ts index 74b9f22c52..a1c5937be2 100644 --- a/packages/base-contract/src/index.ts +++ b/packages/base-contract/src/index.ts @@ -80,9 +80,9 @@ export class BaseContract { public address: string; public contractName: string; public constructorArgs: any[] = []; + public _deployedBytecodeIfExists?: Buffer; private _evmIfExists?: VM; private _evmAccountIfExists?: Buffer; - private _deployedBytecodeIfExists?: Buffer; protected static _formatABIDataItemList( abis: DataItem[], values: any[], diff --git a/packages/contract-wrappers/src/utils/assert.ts b/packages/contract-wrappers/src/utils/assert.ts index 1f1c8201a5..85079b5f59 100644 --- a/packages/contract-wrappers/src/utils/assert.ts +++ b/packages/contract-wrappers/src/utils/assert.ts @@ -1,36 +1,13 @@ import { assert as sharedAssert } from '@0x/assert'; // HACK: We need those two unused imports because they're actually used by sharedAssert which gets injected here import { Schema } from '@0x/json-schemas'; // tslint:disable-line:no-unused-variable -import { assetDataUtils, signatureUtils } from '@0x/order-utils'; import { Order } from '@0x/types'; // tslint:disable-line:no-unused-variable import { BigNumber } from '@0x/utils'; // tslint:disable-line:no-unused-variable import { Web3Wrapper } from '@0x/web3-wrapper'; -import { SupportedProvider } from 'ethereum-types'; import * as _ from 'lodash'; -const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; - export const assert = { ...sharedAssert, - async isValidSignatureAsync( - supportedProvider: SupportedProvider, - orderHash: string, - signature: string, - signerAddress: string, - ): Promise { - const isValid = await signatureUtils.isValidSignatureAsync( - supportedProvider, - orderHash, - signature, - signerAddress, - ); - sharedAssert.assert(isValid, `Expected order with hash '${orderHash}' to have a valid signature`); - }, - isValidSubscriptionToken(variableName: string, subscriptionToken: string): void { - const uuidRegex = new RegExp('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$'); - const isValid = uuidRegex.test(subscriptionToken); - sharedAssert.assert(isValid, `Expected ${variableName} to be a valid subscription token`); - }, async isSenderAddressAsync( variableName: string, senderAddressHex: string, @@ -43,53 +20,4 @@ export const assert = { `Specified ${variableName} ${senderAddressHex} isn't available through the supplied web3 provider`, ); }, - ordersCanBeUsedForForwarderContract(orders: Order[], etherTokenAddress: string): void { - sharedAssert.assert(!_.isEmpty(orders), 'Expected at least 1 signed order. Found no orders'); - assert.ordersHaveAtMostOneUniqueValueForProperty(orders, 'makerAssetData'); - assert.allTakerAssetDatasAreErc20Token(orders, etherTokenAddress); - assert.allTakerAddressesAreNull(orders); - }, - feeOrdersCanBeUsedForForwarderContract(orders: Order[], zrxTokenAddress: string, etherTokenAddress: string): void { - if (!_.isEmpty(orders)) { - assert.allMakerAssetDatasAreErc20Token(orders, zrxTokenAddress); - assert.allTakerAssetDatasAreErc20Token(orders, etherTokenAddress); - } - }, - allTakerAddressesAreNull(orders: Order[]): void { - assert.ordersHaveAtMostOneUniqueValueForProperty(orders, 'takerAddress', NULL_ADDRESS); - }, - allMakerAssetDatasAreErc20Token(orders: Order[], tokenAddress: string): void { - assert.ordersHaveAtMostOneUniqueValueForProperty( - orders, - 'makerAssetData', - assetDataUtils.encodeERC20AssetData(tokenAddress), - ); - }, - allTakerAssetDatasAreErc20Token(orders: Order[], tokenAddress: string): void { - assert.ordersHaveAtMostOneUniqueValueForProperty( - orders, - 'takerAssetData', - assetDataUtils.encodeERC20AssetData(tokenAddress), - ); - }, - /* - * Asserts that all the orders have the same value for the provided propertyName - * If the value parameter is provided, this asserts that all orders have the prope - */ - ordersHaveAtMostOneUniqueValueForProperty(orders: Order[], propertyName: string, value?: any): void { - const allValues = _.map(orders, order => _.get(order, propertyName)); - sharedAssert.hasAtMostOneUniqueValue( - allValues, - `Expected all orders to have the same ${propertyName} field. Found the following ${propertyName} values: ${JSON.stringify( - allValues, - )}`, - ); - if (value !== undefined) { - const firstValue = _.head(allValues); - sharedAssert.assert( - firstValue === value, - `Expected all orders to have a ${propertyName} field with value: ${value}. Found: ${firstValue}`, - ); - } - }, }; diff --git a/packages/contract-wrappers/test/calldata_decoder_test.ts b/packages/contract-wrappers/test/calldata_decoder_test.ts index bdd5fc61be..e205e63725 100644 --- a/packages/contract-wrappers/test/calldata_decoder_test.ts +++ b/packages/contract-wrappers/test/calldata_decoder_test.ts @@ -1,6 +1,5 @@ import { constants, OrderFactory } from '@0x/contracts-test-utils'; import { BlockchainLifecycle } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { SignedOrder } from '@0x/types'; import { addressUtils, BigNumber } from '@0x/utils'; import * as chai from 'chai'; @@ -43,36 +42,62 @@ describe('ABI Decoding Calldata', () => { exchangeAddress, chainId, }; + + contractAddresses = await migrateOnceAsync(); + await blockchainLifecycle.startAsync(); + const config = { + chainId: constants.TESTRPC_CHAIN_ID, + contractAddresses, + blockPollingIntervalMs: 10, + }; + contractWrappers = new ContractWrappers(provider, config); + // Create orders to match. // Values are arbitrary, with the exception of maker addresses (generated above). orderLeft = { makerAddress: makerAddressLeft, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), makerAssetAmount: new BigNumber(10), takerAddress: '0x0000000000000000000000000000000000000000', - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + takerAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), takerAssetAmount: new BigNumber(1), feeRecipientAddress, makerFee: new BigNumber(0), takerFee: new BigNumber(0), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerFeeAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), + takerFeeAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), senderAddress: '0x0000000000000000000000000000000000000000', expirationTimeSeconds: new BigNumber(1549498915), salt: new BigNumber(217), }; orderRight = { makerAddress: makerAddressRight, - makerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), makerAssetAmount: new BigNumber(1), takerAddress: '0x0000000000000000000000000000000000000000', - takerAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + takerAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), takerAssetAmount: new BigNumber(8), feeRecipientAddress, makerFee: new BigNumber(0), takerFee: new BigNumber(0), - makerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), - takerFeeAssetData: assetDataUtils.encodeERC20AssetData(defaultERC20MakerAssetAddress), + makerFeeAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), + takerFeeAssetData: await contractWrappers.devUtils.encodeERC20AssetData.callAsync( + defaultERC20MakerAssetAddress, + ), senderAddress: '0x0000000000000000000000000000000000000000', expirationTimeSeconds: new BigNumber(1549498915), salt: new BigNumber(50010), @@ -82,14 +107,6 @@ describe('ABI Decoding Calldata', () => { const orderFactoryRight = new OrderFactory(privateKeyRight, orderRight); signedOrderRight = await orderFactoryRight.newSignedOrderAsync(domainInfo); // Encode match orders transaction - contractAddresses = await migrateOnceAsync(); - await blockchainLifecycle.startAsync(); - const config = { - chainId: constants.TESTRPC_CHAIN_ID, - contractAddresses, - blockPollingIntervalMs: 10, - }; - contractWrappers = new ContractWrappers(provider, config); matchOrdersTxData = getAbiEncodedTransactionData( contractWrappers.exchange, 'matchOrders', diff --git a/packages/contract-wrappers/test/coordinator_wrapper_test.ts b/packages/contract-wrappers/test/coordinator_wrapper_test.ts index 66e4ac49b3..6589f2ce3c 100644 --- a/packages/contract-wrappers/test/coordinator_wrapper_test.ts +++ b/packages/contract-wrappers/test/coordinator_wrapper_test.ts @@ -1,7 +1,6 @@ import { constants, OrderFactory } from '@0x/contracts-test-utils'; import { defaultOrmConfig, getAppAsync } from '@0x/coordinator-server'; import { BlockchainLifecycle, tokenUtils } from '@0x/dev-utils'; -import { assetDataUtils } from '@0x/order-utils'; import { SignedOrder } from '@0x/types'; import { BigNumber, fetchAsync, logUtils, providerUtils } from '@0x/utils'; import * as chai from 'chai'; @@ -86,9 +85,9 @@ describe.skip('CoordinatorWrapper', () => { [makerTokenAddress, takerTokenAddress] = tokenUtils.getDummyERC20TokenAddresses(); feeTokenAddress = contractAddresses.zrxToken; [makerAssetData, takerAssetData, feeAssetData] = [ - assetDataUtils.encodeERC20AssetData(makerTokenAddress), - assetDataUtils.encodeERC20AssetData(takerTokenAddress), - assetDataUtils.encodeERC20AssetData(feeTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(makerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(takerTokenAddress), + await contractWrappers.devUtils.encodeERC20AssetData.callAsync(feeTokenAddress), ]; // Configure order defaults diff --git a/packages/contract-wrappers/test/global_hooks.ts b/packages/contract-wrappers/test/global_hooks.ts index e23739b59a..7a71d75923 100644 --- a/packages/contract-wrappers/test/global_hooks.ts +++ b/packages/contract-wrappers/test/global_hooks.ts @@ -1,6 +1,6 @@ before('set up mocha', async function(): Promise { // HACK: Since the migrations take longer then our global mocha timeout limit // we manually increase it for this before hook. - const mochaTestTimeoutMs = 50000; + const mochaTestTimeoutMs = 500000; this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this }); diff --git a/packages/order-utils/src/asset_data_utils.ts b/packages/order-utils/src/asset_data_utils.ts index 25d8b52219..67423836c6 100644 --- a/packages/order-utils/src/asset_data_utils.ts +++ b/packages/order-utils/src/asset_data_utils.ts @@ -296,7 +296,7 @@ export const assetDataUtils = { throw new Error( `Could not decode assetData. Expected length of encoded data to be at least 10. Got ${ assetData.length - } for assetData ${assetData}`, + }`, ); } const assetProxyId = assetData.slice(0, constants.SELECTOR_CHAR_LENGTH_WITH_PREFIX); diff --git a/packages/order-utils/src/order_state_utils.ts b/packages/order-utils/src/order_state_utils.ts index 26eb6ec6a3..72d6c48410 100644 --- a/packages/order-utils/src/order_state_utils.ts +++ b/packages/order-utils/src/order_state_utils.ts @@ -1,11 +1,16 @@ import { + AssetProxyId, + ERC20AssetData, + ERC721AssetData, ExchangeContractErrs, + MultiAssetData, ObjectMap, OrderRelevantState, OrderState, OrderStateInvalid, OrderStateValid, SignedOrder, + SingleAssetData, } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; @@ -309,13 +314,14 @@ export class OrderStateUtils { ): Promise> { const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); let balances: ObjectMap = { ...initialBalances }; - if (assetDataUtils.isERC20AssetData(decodedAssetData) || assetDataUtils.isERC721AssetData(decodedAssetData)) { + if (isERC20AssetData(decodedAssetData) || isERC721AssetData(decodedAssetData)) { const balance = await this._balanceAndProxyAllowanceFetcher.getBalanceAsync(assetData, traderAddress); - const tokenAddress = decodedAssetData.tokenAddress; + // tslint:disable-next-line:no-unnecessary-type-assertion + const tokenAddress = (decodedAssetData as ERC20AssetData | ERC721AssetData).tokenAddress; balances[tokenAddress] = initialBalances[tokenAddress] === undefined ? balance : balances[tokenAddress].plus(balance); - } else if (assetDataUtils.isMultiAssetData(decodedAssetData)) { - for (const assetDataElement of decodedAssetData.nestedAssetData) { + } else if (isMultiAssetData(decodedAssetData)) { + for (const assetDataElement of (decodedAssetData as MultiAssetData).nestedAssetData) { balances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, balances); } } @@ -328,19 +334,30 @@ export class OrderStateUtils { ): Promise> { const decodedAssetData = assetDataUtils.decodeAssetDataOrThrow(assetData); let allowances: ObjectMap = { ...initialAllowances }; - if (assetDataUtils.isERC20AssetData(decodedAssetData) || assetDataUtils.isERC721AssetData(decodedAssetData)) { + if (isERC20AssetData(decodedAssetData) || isERC721AssetData(decodedAssetData)) { const allowance = await this._balanceAndProxyAllowanceFetcher.getProxyAllowanceAsync( assetData, traderAddress, ); - const tokenAddress = decodedAssetData.tokenAddress; + // tslint:disable-next-line:no-unnecessary-type-assertion + const tokenAddress = (decodedAssetData as ERC20AssetData | ERC721AssetData).tokenAddress; allowances[tokenAddress] = initialAllowances[tokenAddress] === undefined ? allowance : allowances[tokenAddress].plus(allowance); - } else if (assetDataUtils.isMultiAssetData(decodedAssetData)) { - for (const assetDataElement of decodedAssetData.nestedAssetData) { + } else if (isMultiAssetData(decodedAssetData)) { + for (const assetDataElement of (decodedAssetData as MultiAssetData).nestedAssetData) { allowances = await this._getAssetBalancesAsync(assetDataElement, traderAddress, allowances); } } return allowances; } } + +function isERC20AssetData(decodedAssetData: SingleAssetData | MultiAssetData): boolean { + return decodedAssetData.assetProxyId === AssetProxyId.ERC20; +} +function isERC721AssetData(decodedAssetData: SingleAssetData | MultiAssetData): boolean { + return decodedAssetData.assetProxyId === AssetProxyId.ERC721; +} +function isMultiAssetData(decodedAssetData: SingleAssetData | MultiAssetData): boolean { + return decodedAssetData.assetProxyId === AssetProxyId.MultiAsset; +} diff --git a/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts b/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts index 00974e28f7..9f76189dac 100644 --- a/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts +++ b/packages/order-utils/src/store/balance_and_proxy_allowance_lazy_store.ts @@ -1,10 +1,8 @@ -import { AssetProxyId } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import { AbstractBalanceAndProxyAllowanceFetcher } from '../abstract/abstract_balance_and_proxy_allowance_fetcher'; import { AbstractBalanceAndProxyAllowanceLazyStore } from '../abstract/abstract_balance_and_proxy_allowance_lazy_store'; -import { assetDataUtils } from '../asset_data_utils'; /** * Copy on read store for balances/proxyAllowances of tokens/accounts @@ -111,25 +109,6 @@ export class BalanceAndProxyAllowanceLazyStore implements AbstractBalanceAndProx } } } - /** - * Clear all ERC721 0x proxy allowances a user has on all items of a specific ERC721 contract - * @param tokenAddress ERc721 token address - * @param userAddress Owner Ethereum address - */ - public deleteAllERC721ProxyAllowance(tokenAddress: string, userAddress: string): void { - for (const assetData in this._proxyAllowance) { - if (this._proxyAllowance.hasOwnProperty(assetData)) { - const decodedAssetData = assetDataUtils.decodeERC721AssetData(assetData); - if ( - decodedAssetData.assetProxyId === AssetProxyId.ERC721 && - decodedAssetData.tokenAddress === tokenAddress && - this._proxyAllowance[assetData][userAddress] !== undefined - ) { - delete this._proxyAllowance[assetData][userAddress]; - } - } - } - } /** * Delete all balances & allowances */ diff --git a/packages/order-utils/test/exchange_transfer_simulator_test.ts b/packages/order-utils/test/exchange_transfer_simulator_test.ts index 0228eef6dd..1d64401482 100644 --- a/packages/order-utils/test/exchange_transfer_simulator_test.ts +++ b/packages/order-utils/test/exchange_transfer_simulator_test.ts @@ -1,11 +1,15 @@ -import { DummyERC20TokenContract, ERC20ProxyContract, ERC20TokenContract } from '@0x/abi-gen-wrappers'; +import { + DevUtilsContract, + DummyERC20TokenContract, + ERC20ProxyContract, + ERC20TokenContract, +} from '@0x/abi-gen-wrappers'; import * as artifacts from '@0x/contract-artifacts'; import { BlockchainLifecycle, devConstants } from '@0x/dev-utils'; import { ExchangeContractErrs } from '@0x/types'; import { BigNumber } from '@0x/utils'; import * as chai from 'chai'; -import { assetDataUtils } from '../src/asset_data_utils'; import { constants } from '../src/constants'; import { ExchangeTransferSimulator } from '../src/exchange_transfer_simulator'; import { BalanceAndProxyAllowanceLazyStore } from '../src/store/balance_and_proxy_allowance_lazy_store'; @@ -30,6 +34,7 @@ describe('ExchangeTransferSimulator', async () => { let exchangeTransferSimulator: ExchangeTransferSimulator; let txHash: string; let erc20ProxyAddress: string; + const devUtils = new DevUtilsContract(constants.NULL_ADDRESS, provider); before(async function(): Promise { const mochaTestTimeoutMs = 20000; this.timeout(mochaTestTimeoutMs); // tslint:disable-line:no-invalid-this @@ -67,7 +72,7 @@ describe('ExchangeTransferSimulator', async () => { totalSupply, ); - exampleAssetData = assetDataUtils.encodeERC20AssetData(dummyERC20Token.address); + exampleAssetData = await devUtils.encodeERC20AssetData.callAsync(dummyERC20Token.address); }); beforeEach(async () => { await blockchainLifecycle.startAsync();